Saving user selection when contentEditable=false - javascript

I have included a simple homemade WYSIWYG editor into my HTML Javascript App by using a contentEditable DIV (let's call this EDITDIV) and a series of edit buttons in another DIV. Although far from brilliant it works for me and my users.
My problem is whenever I need to fix the text in EDITDIV which I do by simply setting contentEditable=false, I still want to allow the app users to be able select some of their previously editable text in EDITDIV and perform not edit operations on it, e.g. to use it as a search string.
To do this the users need to be able to select some of the text in EDITDIV and then click outside of EDITDIV. At this point the selection is no more. My question is how do I save the selection to use later on. I could do this every time the selection changes, or at the point when the focus on EDITDIV is lost. I tried both techniques. I cannot find an event (e.g. onselect, onselectionchange) that worked reliably for the first method and for the second method, setting contentEditable to false stops the focus, so the onblur event never happens.
Help much appreciated.

Related

Building WYSIWYG in React, difficulty restoring selection range and creating link

I'm building a simple WYSIWYG editor in React and I've implemented all of the different button functionalities except this last one: selecting text and turning it into a hyperlink.
I need to preface this with: I'm not interested in answers like "just use React-Quill" or "just use react-draft-wysiwyg".
So the type of feature I'm trying to implement can be seen on https://quilljs.com/ - scroll down until you see the demo editor, then select some text, click the "link" button, and a secondary window will pop up containing a text input that allows you to enter a URL. Click SAVE, and the originally selected text will turn into a hyperlink.
I'm approaching this like so:
Using document.execCommand('createLink', false, myURL) to handle the actual hyperlink creation
When my url entry window pops up, I save the currently selected range by saving off the result of document.getSelection().getRangeAt(0)
When the SAVE button is clicked, I restore the range by grabbing the document selection again, clearing all ranges with sel.removeAllRanges() and then calling sel.addRange(mySavedRange)
Note: all of this range saving and restoring is necessary, because when the user clicks on the text input on the pop-up window to enter a url, the document selection clears.
So here's what I'm seeing happen:
Instead of the selected text turning into a hyperlink (in this case I was selecting the word 'this',) the url is just thrown at the end of the line of text.
For reference, after trying my own code, I decided to try the functions implemented here: https://gist.github.com/dantaex/543e721be845c18d2f92652c0ebe06aa
I still see the same issue.
Any thoughts?
An extra note: I'm building an electron app, so I'm not as concerned with "cross-browser" compatibility. If it works in Chrome, then great!
My solution: the issue was that the contenteditable div needed to be focused.
So I changed my approach:
Upon clicking "Save", instead of using the document.execCommand right away, I would update a global state field, like enteredHyperlinkText (I'm using Reactn)
I added a ref to my editor with useRef and an effect to my editor with useEffect (I'm using React Hooks) the effect would only re-run when enteredHyperlinkText updates, and it will handle focusing on the editor, restoring the selection, and calling document.execCommand.
Note: focus the contenteditable div before restoring the selection.

JavaScript dummy/proxy input for another DOM element

I'm using an iframe to get the content of a registration form on a web page, and, as I have to show this registration form inside an HTML app for Android, I'd like to analyse the html inside the iframe to search for input textfields and to use my custom text field as "dummy" or "proxy" for the considered element:
Let me explain better:
As the web page wouldn't give the user the same easy approach as an app, instead of clicking on a textfield and having the problem that the virtual keyboard overlaps the other fields making it difficult to go further.
I want to create a div that covers the iframe and has a text field inside with the same functionality as the one clicked: by this way after entering the text into the dummy field and clicking an ok button aside, the clicked field would be updated and all the other things hidden (virtual keyboard, etc.).
It would be simple if the goal was just to copy a text from a field to another, but the real problem is that the clicked field could have some events like onkeypress or onchange (e.g. to autocomplete) and so on, and I should get the same behaviour on the dummy field.
In an imaginary world I'd do:
document.getElementById("dummy") = document.getElementById("original")
And then destroying and recreating the dummy whenever required.
Do you know if is there something possible to do?
You can't read a div from inside of an iframe after the iframe has loaded. The reason for this is to prevent hackers from making programs that can grab your credit card numbers from web-based forms through iframes and then use the apps to record them.
UPDATE
You would have to retrieve the entire form in the background, then render it again using webkit, then when the person clicks submit, you would have to submit the exact same form data to the host from your device.
Its possible, but I don't see a good reason why you would ever need to use that.

How to enable a backspace work inside a form textbox?

I'm using a form where in a text box is bound to a variable object by its path. I also have a button to fetch few records based on the input given in this text box. When I enter something for the first time and hit the button, it fetches the records. But again if I try to hit backspace or delete buttons inside the text box, it takes me to the previous page instead of simply deleting the text inside. Is there a way out? I tried with events like preventDefault() using keyCode restrictions, but in vain. Please help.
PS: This text box has regex validations and also has logic to pre-populate.
when records are fetched, you lose the focus on your text box. When you press the Backspace key once more, the browser takes you to the previous page (as most browers do). Set the focus back on your element after you fetch the records or change you code so the records fetching will not change the focused element.
See : https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.focus

Toggle/Formatting with Javascript

I posted awhile ago and got great insight on hide/show text with javascript... Now I need to take this one step further. Can't find the right combination to make it work.
Here's what I NEED:
When a viewer comes to this page, the first hide/show element is displayed in the text box AND
That element is also highlighted a certain color to display that it is active.
Lastly, as every hide/show element is clicked, that stays highlighted until the next is selected.
Here's a link to my dev site. I think it's easier this way.
http://verus.exigodigital.com/services/
Here was my previous post on the hide/show text:
Showing & Hiding Text with Javascript
REALLY appreciate the help, guys! :)
You could make 2 CSS definitions, one for the currently selected textbox, and one for textboxes that aren't selected
When someone clicks on one of the textboxes to edit its contents (the onfocus event), you just call a function that runs through all of your textboxes, and for each one checks if it's the one with focus - if it is, set the className variable of the element to "selected" or something, and it it's not the one with focus then set it's className variable to "normal" or something
If I didn't understand the question or you need more info, just let me know :)

jQuery / Javascript > onClick place text at last known cursor position

I have a form I'm working with that allows the user to continually add new rows as needed (used for making an article with multiple "howto" steps, they can click over and over again to add a new step). What I would like to be able to do is have the user be able to click in any of those rows at any time and then click on a word or button that is off to the side that will then insert the value of that button into the last known cursor position.
So for example I may have one form that currently has 3 rows. If the user goes back and wants to insert some data they could click back in the box and hit the button corresponding to the data they want to insert.
Example input 1: "Remove the customers current IP address and replace with their static IP, [USER COULD CLICK HERE AND THEN CLICK THE STATIC IP BUTTON AND %STATIC_IP% WOULD BE INSERTED AT THE LAST KNOWN CURSOR POSITION (AKA HERE)]
Example input 2: "Enter in the customers [Click to insert %WIFI_SSID%] into the router settings"
I have found several other stackoverflow articles that are able to all insert text but they all expect it to be into a defined textarea or input. In this case I'm needing it to insert into the last known cursor position. I hope this is all clear. I look forward to any assistance or questions.
Starter code: http://jsfiddle.net/4mJwU/
If you already know how to insert some arbitrary content at the last known caret position, your only problem is to know which field was focues last time before button was clicked.
That can be done in numerous number of ways, one of those would be utilize focus and blur events (attached to fields - rows in your case) to track (in some variable for example) reference to the field last focused. It should be a piece of cake from there.
Quick and simple script that can get you started http://jsfiddle.net/sjqWu/1/
Combine what you've learned from other stackoverflow anwsers with example above and you should be ok. Happy learning!
I'd question your design. To make the user have to click a field then click some text to insert into that field seems like too many steps. You could possibly utilize some sort of drag and drop routine. Or instead of the first click being a text box, maybe make it a drop down list?
I agree with WTK. You can store the record id or text box id using some sort of event, then proceed from there.

Categories

Resources