I have contenteditable span with a max-width setting that allows the user to enter text. What I'm looking to do is detect when the user reaches this width limit and a new line is displayed on the page. I am trying to create a WYSIWYG editor that creates text, (in SVG), exactly the way it looks in the contenteditable span when the user presses enter. I have successfully captured the enter event, so that is not an issue, I am looking for a way to either detect the word wrap, or calculate where it should occur. Any help is appreciated. (I can post sample code if needed)
When the height of the element changes, you know you have word-wrap occurring.
Monitor for a change event and see if the height changed. If it did, you have a word-wrap (or un-wrap). I threw together an example:
http://jsfiddle.net/eZDRD/
Related
I know there are many similar topics but none of them has the solution to my problem so please read my question carefully before sending similar topic links and marking as duplicate question.
I have a content editable DIV object, something similar to TextArea control. My goal is to cancel key press events if content starts scrolling and there must be no flickering.
When i use keyUp event, it's too late to cancel and there is also no methods available to cancel changes. What's done is done at this stage.
When i use keyDown or keyPress events, they are cancelable. But new changes are not yet applied. So, i know which character is pressed etc. but i still don't know how it's going to affect the scrolling size.
Plus, i allow style changes like making the text bold or changing the font size. Since there is;
document.execCommand("undo");
command, i'm able to test these changes and undo if scrolling starts. To test things, i use a cloned div with same content. It works fine. Changes are applied to cloned div (which is visible at the moment for debugging purposes but will be invisible if the method works) and if cloned div has an overflow, changes are canceled.
My problem is at doing the same thing for key presses. It's harder to simulate what happens to editable div content than using document.execCommand for other styling options. What i need is to get the innerHTML result at keyUp stage before keyUp occurs and event is still cancelable like keyDown or keyPress.
To simulate things, i tried getting cursor position and adding pressed characters manually using substring function but content isn't plain text and i had many problems with it. For instance when i press enter, an HTML block <div><br></div> is added for newline character which messed up cursor position. I tried many ways to handle things but it's very open to bugs. So, i decided not to follow this path.
In short my question is;
How can i possibly limit an editable div area by height, not allowing
to overflow or scroll without any flickering, just canceling key press
events? Do i have to simulate something like willKeyUp or is there any
other cross browser way?
Here is jsfiddle link for my sample which works for document.execCommand case (changing font size, weight etc.) but fails at typing letters;
http://jsfiddle.net/7zQD2/
Edit: To clarify my goal at jsfiddle example, after writing 5 lines of text, either when you press enter or type to end of the line, cursor should never reach to the sixth line. Key presses should be canceled and cursor should stay at fifth line with no content changes or flickers.
One solution is to use the cloning setup you already have, but to set the opacity of the first copy to 0 and position it on top of the clone with position: absolute in the css. The first copy won't be visible, but will catch a click directed towards the visible one underneath it. You can change your event to fire on keyup.
Since the transparent div still exists, and still has height, it can measure text height for you without being visible to the user. The visible text then updates to match what is learned with the transparent text, and never reaches the 6th line or flickers.
http://jsfiddle.net/7zQD2/2/
In my project I am using a "contenteditable" div. I am trying to create an autocomplete functionality by using this div. Whenever I type any words, some suggestions should be visible in a different div. And when I press ENTER, the selected suggestion should be replaced with the entered text in the "contenteditable" div. Then when I press SPACE, further suggestions should be visible.
For a clearer explanation, please see this fiddle.
In the fiddle, type some letters and then press ENTER then SPACE.
Whenever I press SPACE, an alert box (for testing) will be displayed. This tells the current position of the caret in the "contenteditable" div.
But when I press ENTER and then SPACE, the current position of the caret is wrong, i.e. 0.
As far as I understood, if I don't use the placeCaretAtEnd() function then I am getting the caret position correctly. But in my case I want to use both (getCaretPosition() and placeCaretAtEnd()).
I am checking this in Firefox. (In Chrome, it seems to be working properly)
I need a solution that works in IE8+, Chrome and Firefox. Please help.
You need a more sophisticated means of getting the caret position that works with all the text in the editable div. You could use code from this question, although I'm not quite sure what you're trying to achieve. You may have problems stemming from the fact that the code does not take into account lin breaks implied by <br> and block elements.
Demo: http://jsfiddle.net/BN5N6/12/
Sorry I can't give you a complete answer. I'd post this as a comment only I don't have comment rights. Having played with your fiddle, I noticed that in Firefox (only browser I tested in) after I pressed Enter the "result" div would have an additional child text node. This wasn't a result of your placeCaretAtEnd function. It appears to be something that Firefox does for you when you hit enter.
It looks like the 0 that you're getting in the console is the position of the caret in the new text node that the browser created for you. If, after pressing enter, you click in the original text node and press space, the console will give you the correct caret position (once again, relative to the text node the cursor is in).
I was wondering if there is a way for me to open up a textbox for users to type in on an onclick event? How would i go about making this? I'm thinking now that there may be a way for me to grab what the user types on a canvas and use the methods i've read about to output the text. Is this a possibility? But how would i allow the user to type on the canvas in the first place?
I've done a lot of reading and all the examples i could find were about simply outputting text onto the canvas rather than creating a textbox.
Any ideas?
You have to literally make one, as in the onclick event fires and you do: var myInput = document.createElement("textarea");
You need to set the myInput.style.width, height, top, left, and of course the myInput.style.position to "absolute", then position it where the user would expect.
Then you need to assign events to it. Maybe on keydown it will look for the Enter key, and if the enter key is pressed it will disappear and commit the text however you want it committed.
Then add it to the page.
Maybe it will do the same thing on a blur event (if the user clicks away).
canvas is a bitmap image. You can't put an element "in it". You could put one hovering over it, though. What I think your looking for is the html5 contenteditable attribute.
A simple solution - use Javascript's alert box. This will enable us to grab the text which the user wants to place on the screen. Then write the text where ever you want on the canvas (lots of tutorials on how to write text on a canvas).
So I've got a web applcation in the midst of wireframing, but I've run into an issue that requires a technical solution before I can solidify this model; that being:
Fig. #1 User creates new 'text-field'
element (a div with a max-width.)
User then begins typing into said
element until...
Fig. #2 The element reaches it's
max-width, the text drops to a new line and a 'new' background image (in
the form of another div) is created (with it's opacity and position animated for effect) to accommodate the larger element sze.
This is a rough outline of the intended functionality (given at this moment, I'm not sure how to have a text-field that behaves like a div with max-width yet) but I'm curious about how to create the event handler for the 2nd step; I thought about checking on every 'keydown' event, but that seems inefficient...
Does anyone have any advice or ideas for tackling something like this? Thanks!
The 'keydown' or 'keyup' event is the first thing that comes to mind. If you decide to do it this way you will have to
check for the html elements size each time and compare it to the old (save in a variable) one.
Easiest way seems to be to bind a handler to the html element and let it fire when the size changes.
I do not know if such an event exists, but if then thats the way to go.
(+1 for your very descriptive Question)
You could try using the CSS3 transition functionality:
http://slides.html5rocks.com/#slide42
That way the elements you want can be animated by the browser itself.
Disclaimer: Obviously, this doesn't work with more complicated effects.
In MSIE an onresize should fire.
Not sure how to attack the width issue where an input field auto sizes untill max width then wraps. You could use a monospace font inside the text field so that you could use javascript to monitor and control the growth of the box horizontally uptill the max width.
To approach the height auto grow you would be better using a textarea with it set to one row to begin with so it looks like an input box and then when the text auto wraps to the next row, which it will do, you can check the scollHeight of the textarea and check the actual height of the textarea, subtract them and you get the height you need to grow the textarea to stop the vertical scroll bars appearing.
The above will make the scroll bars flick on and off briefly while your javascript does it magic. You can use overflow:auto; to hide the scroll bars but then I don't know if scrollHeight will still read correctly. You will need to experiment.
Also take note on my comment above about setting an interval on keydown and checking the input length to stop the repeating key down text issue.
Had a idea and now trying to make it happen.
Idea: Have a HTML page with several inputs with CSS to make it look liked lined paper. Than at the end of each line move the focus from one input to the next so the user can continue input on a page mimicking lined paper.
Problem: Have no way of detecting or capturing an event when the input reaches the end of the line, thus no way to move the focus from one field to the next.
I tried using the maxlength attribute on the inputs but this didn't work because of course some letters are wider than others so the lines never truly 'filled up'
Possible solution: change inputs to divs with a inner span wrapping the text, compute width of span on keyup event and match it to the overall width of the div, if greater than do work to trim text and move text & focus to the next div.
Problem with that is its messy, and could cause bad performance on the page depending on the amount of lines i decide to use.
Question: Is there any event I can grab from the input when the end of the viewable area has been reached to be able to fire my function?? OR maybe someone could have a better idea of how to implement this?? OR am i trying to recreate the wheel and something for this has already been written (i couldn't find anything on Google)??
On each keyup trigger a function to count the number of characters in the input field. If you reach your limit move focus to next line :)
Here is an example with using styling on text area. Could load up a nice handwriting font too.
http://stuff.alphaready.com/notepad/index.html