I'm using the contentEditable attribute on a DIV element in Firefox 3.03. Setting it to true allows me to edit the text content of the DIV, as expected.
Then, when I set contentEditable to "false", the div is no longer editable, also as expected.
However the flashing caret (text input cursor) remains visible even though the text is no longer editable. The caret is now also visible when I click on most other text in the same page, even in normal text paragraphs.
Has anyone seen this before? Is there any way to force the caret hidden?
(When I either resize the browser or click within another application, and come back, the caret magically disappears.)
I've dealt with this and my workaround is clearing the selection when I disable contentEditable:
if ($.browser.mozilla) { // replace with browser detection of your choice
window.getSelection().removeAllRanges();
}
I am actually removing the "contenteditable" attribute for browsers other than IE, rather than setting it to false:
if ($.browser.msie) {
element.contentEditable = false;
}
else {
$(element).removeAttr( 'contenteditable' );
}
The browsers manage the contentEditable attribute inconsistently and my testing revealed that this worked better overall. I don't remember if this contributed to fixing the caret problem, but I'm throwing it in here just in case.
The style attribute -moz-user-input can be used in Firefox to get the functionality contenteditable=false working.
The value assigned defines if user input is accepted. The possible values are
none : The element does not respond to user input.
enabled : The element can accepts user input. This is default.
disabled : The element does not accept user input.
E.g.:
// to disallow users to enter input
<asp:TextBox ID="uxFromDate" runat="server" style="-moz-user-input: disabled;"></asp:TextBox>
// to allow users to enter input
<asp:TextBox ID="uxFromDate" runat="server" style="-moz-user-input: enabled ;"></asp:TextBox>
Refer to https://developer.mozilla.org/en/CSS/-moz-user-input for further reference.
This solve the ploblem, looks like firefox is just checking is own way to make things :P
getDoc().designMode = "off";
Related
Is there a way to detect where in an input element's content a user has clicked? Specifically in Firefox?
I need to know not where the caret is but where the caret would be when the user clicks into an input element.
I am trying to fix a bug in firefox where the user cannot click to place the caret into an input element which has had '.select()' called on it -- the caret fails to appear in firefox, so I want to place it manually if possible.
Thanks!
You can get the pixel position of the user's click (relative to the input field) by reading the click event's offsetX and offsetY:
// get the click position:
document.getElementById('test').onclick = function(e) {
console.log(e.offsetX, e.offsetY)
};
// for testing the 'select' issue:
document.getElementById('btn').onclick = function() {
document.getElementById('test').select();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="test">xxxxxx</textarea>
<button id="btn">Select</button>
Converting that to the desired caret location is not easy, though, because it will depend on font sizes and the text content of the input field. The best I can think of would be to do something like the technique used in textarea-caret-position, except iterating through every possible caret position in the textarea to find the one closest to where the user clicked. Which is almost certainly overkill for the task you have in mind.
(For what it's worth, the current version of firefox (v57) does not seem to have any trouble placing the caret correctly whether the input field is selected or not. I'm not certain whether this was the case in previous versions.)
Found the root of the problem, some bad css had set text-select to auto on input elements. Changing it to text-select:text allowed the fix I used for Safari to work in Firefox as well.
Chrome's native spell check won't work on a contenteditable <div> unless the user clicks into the <div>, which makes sense. But if I'm adding a contenteditable <div> dynamically, is there a way to replicate a user clicking into the <div>> so that the spell check will work? I tried using jQuery:
$('#div-id').click();
and
$('#div-id').trigger('click');
but these didn't work. Any help? jQuery or JavaScript works for me.
As a comment mentioned, bringing focus to the element programmatically will work to enable spellcheck. But this might be undesirable due to the focus now being changed to another element. So here is a complete solution (not using jQuery but will still work with it):
var oldFocus = document.activeElement;
div.focus();
if (oldFocus) {
oldFocus.focus();
} else {
div.blur();
}
This saves the previously focused element before focusing the div in order to enable spellcheck. Then, the focus is returned to the old element (if there was one that already had focus), otherwise it makes nothing focused.
I've been struggling with getting a field working properly. This field displays a lot of data, and the user wants to select and copy a large portion of it. The data is basically a big list and the user wants to select all entries below a certain point. The way that they achieve the selection is by highlighting a word or two in the first entry they want then pressing ctrl+shft+end to select everything to the bottom. This was working until a new feature on the page was added below the contents of the list. Now the hot key select also selects the contents of the rest of the page.
The current implementation is simply :
<div id='diff-contents'>[content here]</div>
<div id='trailing-content'>blah blah blah...</div>
I have tried a read-only input field:
<input id='diff-contents' value='[content here]' readonly/>
This works in Firefox to some extent however the contents contains HTML, and the input field show html literally, not rendered. In addition to that Chrome doesn't show a blinking caret and the hot keys do nothing, so the input field is sadly not viable for me in this situation.
How can I make a selectable field that maintains focus for the cursor and shows a blinking caret but is not editable using javascript, CSS, HTML, or JQuery?
Edit: jsfiddle example that should clarify a bit.
Look at these questions how to determine the current selection: Getting selected text in a browser, cross-platform
The next step is to create a new range which starts at the end tag of #diff-contents. With this information, you should be able to extend/modify the existing selection.
I suggest to either add a button to the UI or use JavaScript with a key-press handler to trigger this code.
With that, the correct amount of HTML should be selected. Users can then copy that into the clipboard with Ctrl+C.
#Aaron Digulla mentioned key listeners, and that got me thinking about simply stopping the events.
The diff-content element is still a div but it is set to editable. This gives both HTML rendering and a blinking caret.
$(this).keydown(function (event) {
if (document.activeElement.id == 'diff-content') {
if (!allowedKeys(event.keyCode)) {
//The only other key presses that should be processed are ctrl+c (keycode 67) and ctrl+a (65)
if (!event.ctrlKey || !(event.keyCode == 67 || event.keyCode == 65)) {
event.preventDefault();
}
}
}
});
The javascript adds a keydown event listener to the entire page. This is necessary since if you just add it to the element, the event has already propagated through the rest of the page and will still be processed, and this was causing funny issues for me. Next we check if it's the diff-content that is active since we want other input elements to still operate normally. Then we check if the key event is an allowed key (tab, home, end, arrows). And finally, check for ctrl+c and ctrl+a and allow those too. I tried event.stopPropogation() and event.stopImmediatePropogation(), and neither of those worked, but preventDefault did.
Lastly, I added style="outline-style:none" to the element so that the blue border would not appear when the element has focus.
The only issue that I have yet to resolve is that since it is editable, the browser still allows you to select and then right click to either cut or paste, which will allow you to alter the text.
Here is the final jsfiddle for what I am using: http://jsfiddle.net/wh3nzmj8/12/
I'm very new to Javascript (and jQuery). My JSFiddle really shows the issue in the best way possible. http://jsfiddle.net/mkLsr/3/
I'm trying to make it so a search box text input that is focused upon page load, so a user can type into it without clicking into it. However, I also want default text in it that will disappear when the user clicks into the text input and re-appears if they click out of the text field without writing anything.
The problem is that I have other text inputs on the page, and as it is running now, if a user clicks onto one and begins typing, the focus jumps to the originally focused text input. How can I stop this from happening?
I tried using if ($('input:focus').size() == 0) to make it so it would only set the focus if no other focus has been set. Does it not work because it doesn't re-check after the page loads? How can I get it to re-check, or is there some other problem?
I think that a search box that you can automatically type into, that has a default text that is erased upon typing, is about as user friendly as you can get - but I'm really hoping to do it without expense to other input's user-friendliness.
Any help would be appreciated!
* EDIT *
Kai really helped me out with his Javascript solution and use of the "placeholder" HTML attribute. (http://jsfiddle.net/wgwTC/4/).
I'm just curious if someone knows how to apply it cross-browser so that the first text input is in focus still, but the placeholder text is there upon loading the page. Currently it works in Chrome, but not IE (I'm using 9) or Firefox (5.0). If there's a cross-browser solution, it may help others who want the same or similar functionality on future projects.
Here's a solution that uses the placeholder attribute but will fallback to JS for IE <= 9: (See http://jsfiddle.net/wgwTC/2/ for working example):
// Focus on this box by default
$('#header-search-box').focus();
// Support placeholder text for IE <= 9 (which doesn't support placeholder attribute)
if ( $.browser.msie && (parseInt($.browser.version, 10) <= 9) ) {
$('input[name=search]').attr('value', 'Search New Equipment...');
// Set placeholder text on blur
$('input[name=search]').on('blur', function (e) {
if (!e.currentTarget.value.length) {
e.currentTarget.value = 'Search New Equipment...';
}
});
// Clear placeholder text on focus
$('input[name=search]').on('focus', function (e) {
if (e.currentTarget.value === 'Search New Equipment...') {
e.currentTarget.value = '';
}
});
}
I think this does what you're asking (assuming I understand you correctly).
Here's the fiddle: http://jsfiddle.net/jVvX3/2/
I am developing an HTML code editor using simple DIV's and capturing events. When I use this on the iPad the keyboard never pops up since i'm not technically in an editable field.
Is there a way to programatically tell the iPad that I need a keybaord?
If your code is executed via something that was initiated via a user action then it will work.
E.g;
this works (pops keyboard):
<input type='text' id='foo'><div onclick='$("#foo").focus();'>click</div>
this doesn't work (input gets a border but no keyboard pop):
<input type='text' id='foo'>
<script>
window.onload = function() {
$("#foo").focus();
}
</script>
To make the keyboard show on iOS devices you need to focus on an editable element such as an input or a textarea. Furthermore, the element must be visible and the .focus() function must to be executed in response to a user interaction such as a mouse click.
The thing is - we DON'T want the input element to be visible..
I have fiddled with this for quiet some time and eventually got the result I was looking for.
First, create an element you want to use to show the keyboard - in this case a button, and a hidden input element: (Working jsFiddle or Test on a mobile device)
<button id="openKeyboard">Open Keyboard</button>
<input id="hiddenInput" style="visibility: hidden;">
Then use the following javascript:
document.getElementById('openKeyboard').addEventListener('click', function(){
var inputElement = document.getElementById('hiddenInput');
inputElement.style.visibility = 'visible'; // unhide the input
inputElement.focus(); // focus on it so keyboard pops
inputElement.style.visibility = 'hidden'; // hide it again
});
Notes:
I have noticed that iOS safari will automatically scroll and zoom to the area of the input so make sure you use proper viewport and position your input element in a relevant location.
You can use some CSS on your input like setting the opacity, height and width to 0. However, if your input is completely hidden this won't work again, so make sure you leave the padding or border just so there's something to be rendered (even though it won't show up due to the opacity). This also means you shouldn't use display:none to hide it, hidden elements are just not allowed to be focused.
Use the regular keyboard events (keydown, keypress, keyup) on your hidden input to access the user's interaction as you would normally do. Nothing special here.
Place a transparent textarea over the contentEditable div. The keyboard will open, as soon as the user focus the textarea.
Register an event listener on the textarea for the focus event and set the visibilityof the textarea to hidden. This prevents the blinking cursor.
Set the visibility of the textarea back to visible after the blur event occurred.
Register additional event listeners for keydown, keyup, keypressevents and process theses events the same way, as you process them in the contentEditable div.
I have found that calling prompt("Enter some value") does trigger the keyboard on my iPad 2. Not sure if this is helpful in your situation or not.
The answers to this questions suggest that it's not possible: Why doesn't #contenteditable work on the iPhone?
A colleague of mine who was working on a similar project ended up using a textarea for the iPad version of his editor, and contenteditable divs/spans for browsers that support contenteditable. Perhaps something similar would work for you.
Proxy input trick
I figured out another dirty workaround, but works well.
The trick is based on the fact, that if the keyboard is already open, changing the focus will not close the keyboard.
Add a small "proxy invisible input" in top left of the page with position fixed (the fixed position prevents the flicker, also make sure that the field has font-size bigger than 16px to prevent iOS page zoom on focus)
On clicking the button, just .focus() on this invisible field. The keyboard will open...
Show or render your other input fields
Now with the keyboard open just .focus() on the desired input. You can use small setTimeout delay, for example 500ms if needed
Here's a solution for you:
<input id="my-input" type="text" />
<script type="text/javascript">
var textbox = document.getElementById('my-input');
textbox.select();
</script>