I'm working on a little project in which users can upload their .docx files and then read those files (and files from other users) right in the app. For this purpose I have extracted text from docx and displayed it in a div in separate view and html page. Now, I would like to give my users an option to select some text from this div (and only this div) and when they have selected it, I would like to display a button that hovers over that text on which they can click. This button would be for adding selected text to their notes, similar to what MS Edge does automatically when we select some text (it adds those three dots which then open a menu for copying and the rest). Or even more precisely, if you're familiar with Coursera website - when some text from lessons is selected, a 'Save Note' button appears and clicking it adds the selected text right in your notes without the need for users to do anything else, and they can find the saved note whenever they go to their notes (photo bellow shows this button in action).
Coursera 'Save Note' button example
However, I'm not sure how to implement this. I think I would use window.getSelection, and then store the selection in some const that I would then send via fetch to my server to add it to the Notes Model (I'm using Django). But I don't know how to implement this, nor where to even start. How to even make a button hover over other text like this, only when a selection is selected? Any kind of help is much appreciated!! Note: I would like to this in Vanilla JS if possible, since I'm not yet familiar with React or other libraries/frameworks.
CodePudding user response:
Breaking the problem into tasks :
- Detect selection start and end - Can be done using onmouseup and onmousedown respectively.
Use the event object available to the
EventHandler
to find the coordinates of the selected regiononmousedown
store the coordinates where selection startedonmouseup
get the coordinates where selection endedUse the starting and ending coordinates to position the copy button (using
CSS
)
- Get selected text - window.getSelection can be used to get the selected text on pressing the button.
Once the selection is detected and the selected text is available, it can be pushed to the server.
Something like this :
const copyBtn = document.createElement("button");
copyBtn.innerHTML = "Press this button to log selected text";
copyBtn.style.position = "absolute";
copyBtn.style.display = "none";
copyBtn.onclick = function(evt) {
console.log(window.getSelection().toString())
}
document.body.appendChild(copyBtn);
const paragraph = document.querySelector('p');
let startX = 0;
let startY = 0;
function mouseDown(evt) {
console.log(`Selection started at : ${evt.clientX}, ${evt.clientY}`);
startX = evt.clientX;
startY = evt.clientY;
copyBtn.style.display = "none";
}
function mouseUp(evt) {
console.log(`Selection ended at : ${evt.clientX}, ${evt.clientY}`);
copyBtn.style.display = "block";
copyBtn.style.top = `${Math.min(startY, evt.clientY)}px`;
copyBtn.style.left = `${(startX evt.clientX) / 2}px`;
}
paragraph.onmouseup = mouseUp;
paragraph.onmousedown = mouseDown
<!DOCTYPE html>
<html>
<body>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
</body>
</html>
CodePudding user response:
There is a function in JavaScript which retrieves the current selected text:
function getSelectionText() {
if (document.getSelection().toString().length === 0) {
//do nothing
} else if (document.getSelection().toString().length > 0) {
//fire button function
}
return text;
}
I believe there isn't a function that fires only when text is selected, so the function should be ran constantly, or when there is a dom "mouseup" event.