I'm really looking for something that works with all current popular browsers (IE9, Chrome, Firefox, Safari) and all the way back to IE8.
Although, I've been looking for a way to set focus on a Flash move object after it has lost focus, I've found that all historical ways of doing this fail. I assume it is yet another security issue.
So, I'm now looking for how to monitor change events of some sort for the document.activeElement (though "change" doesn't really occur).
While #James's answer above is correct. I've added more details to make it a completely working solution along with the use of focus event too.
<html>
<body>
<input type="text" id="Text1" name ="Text1" value=""/>
<input type="text" id="Text2" name ="Text2" value=""/>
<SELECT><OPTION>ASDASD</OPTION><OPTION>A232</OPTION></SELECT>
<INPUT TYPE="CHECKBOX" id="Check1"/>
<INPUT type="TEXT" id="text3"/>
<input type="radio"/>
<div id="console"> </div>
<textarea id="textarea1"> </textarea>
<script>
var lastActiveElement = document.activeElement;
function detectBlur() {
// Do logic related to blur using document.activeElement;
// You can do change detection too using lastActiveElement as a history
}
function isSameActiveElement() {
var currentActiveElement = document.activeElement;
if(lastActiveElement != currentActiveElement) {
lastActiveElement = currentActiveElement;
return false;
}
return true;
}
function detectFocus() {
// Add logic to detect focus and to see if it has changed or not from the lastActiveElement.
}
function attachEvents() {
window.addEventListener ? window.addEventListener('focus', detectFocus, true) : window.attachEvent('onfocusout', detectFocus);
window.addEventListener ? window.addEventListener('blur', detectBlur, true) : window.attachEvent('onblur', detectBlur);
}
attachEvents();
</script>
</body>
</html>
It seems that you can use a combination of capturing focus/blur and focusin/focusout (IE) events. Something like this perhaps:
window.addEventListener ?
window.addEventListener('blur', blurHappened, true)
: window.attachEvent('onfocusout', blurHappened);
function blurHappened() {
console.log('document.activeElement changed');
}
onfocusout will catch bubbled "blurs" while regular blur on addEventListener will capture "blurs".
You may need to add additional checks in blurHappened. I'm not sure as I haven't tested.
You can capture a focus change on the document using the focusin event listener.
document.addEventListener('focusin', () => {
console.log('focus changed');
});
div {
display: flex;
flex-direction: column;
}
<div>
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
</div>
In my experience, the best source of information on cross-browser issues is Quirksmode. Here's a link to the "obvious" (but not useable) option -- focus and blur events.
http://www.quirksmode.org/dom/events/blurfocus.html
Oddly (and surprisingly) it's Webkit-based browsers that are the fly in the ointment here.
Another option would be to use an interval timer to check whether the activeElement has changed either as your sole option OR as backup for focus/blur. (You could also listen for key presses, mouse clicks, and touches to check if activeElement changes.) If you cover these options, your intervalTimer will hardly ever need to clean up.
I have the following code to display a textbox in a HTML webpage.
<input type="text" id="userid" name="userid" value="Please enter the user ID" />
When the page displays, the text contains the Please enter the user ID message. However, I found that the user needs to click 3 times in order to select all the text (in this case it is Please enter the user ID).
Is it possible to select the entire text with only one click?
Edit:
Sorry, I forgot to say: I must use the input type="text"
You can use the JavaScript .select() method for HTMLElement:
<label for="userid">User ID</label>
<input onClick="this.select();" value="Please enter the user ID" id="userid" />
But apparently it doesn't work on mobile Safari. In those cases you can use:
<input onClick="this.setSelectionRange(0, this.value.length)" value="Sample Text" id="userid" />
The previously posted solutions have two quirks:
In Chrome the selection via .select() doesn't stick - adding a slight timeout resolves this issue.
It's impossible to place the cursor at a desired point after focus.
Here's a complete solution that selects all text on focus, but allows selecting a specific cursor point after focus.
$(function () {
var focusedElement;
$(document).on('focus', 'input', function () {
if (focusedElement == this) return; //already focused, return so user can now place cursor at specific point in input.
focusedElement = this;
setTimeout(function () { focusedElement.select(); }, 100); //select all text in any field on focus for easy re-entry. Delay sightly to allow focus to "stick" before selecting.
});
});
Html (you'll have to put the onclick attribute on every input you want it to work for on the page)
<input type="text" value="click the input to select" onclick="this.select();"/>
OR A BETTER OPTION
jQuery (this will work for every text input on the page, no need to change your html):
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
<script type="text/javascript">
$(function(){
$(document).on('click','input[type=text]',function(){ this.select(); });
});
</script>
You should not use this approach to provide examples for input values (any more).
The best option is to now use the placeholder HTML attribute if possible:
<label for="userid">User ID</label>
<input type="text" id="userid" name="userid" placeholder="Please enter the user ID" />
This will cause the text to show unless a value is entered, eliminating the need to select text or clear inputs.
Beware that placeholders are no replacement for labels, as they disappear once text is entered, and pose issues for accessibility.
You can always use document.execCommand (supported in all major browsers)
document.execCommand("selectall", null, false);
Selects all text in the currently focused element.
Update 2021: execCommand is now deprecated.
It's probably for the best to be honest, as it was an old IE API which had been adopted by the other browsers, and it was always a little weird to work with. Nevertheless, it was nice to have one solution which worked both with <input> fields and contenteditable elements.
.select() is probably the best way to go for <input> fields these days.
For contenteditable, the modern solution there is to use the range API.
Note: When you consider onclick="this.select()", At the first click, All characters will be selected, After that maybe you wanted to edit something in input and click among characters again but it will select all characters again. To fix this problem you should use onfocus instead of onclick.
Try:
onclick="this.select()"
It works great for me.
The answers listed are partial according to me. I have linked below two examples of how to do this in Angular and with JQuery.
This solution has the following features:
Works for all browsers that support JQuery, Safari, Chrome, IE, Firefox, etc.
Works for Phonegap/Cordova: Android and IOs.
Only selects all once after input gets focus until next blur and then focus
Multiple inputs can be used and it does not glitch out.
Angular directive has great re-usage simply add directive select-all-on-click
JQuery can be modified easily
JQuery:
http://plnkr.co/edit/VZ0o2FJQHTmOMfSPRqpH?p=preview
$("input").blur(function() {
if ($(this).attr("data-selected-all")) {
//Remove atribute to allow select all again on focus
$(this).removeAttr("data-selected-all");
}
});
$("input").click(function() {
if (!$(this).attr("data-selected-all")) {
try {
$(this).selectionStart = 0;
$(this).selectionEnd = $(this).value.length + 1;
//add atribute allowing normal selecting post focus
$(this).attr("data-selected-all", true);
} catch (err) {
$(this).select();
//add atribute allowing normal selecting post focus
$(this).attr("data-selected-all", true);
}
}
});
Angular:
http://plnkr.co/edit/llcyAf?p=preview
var app = angular.module('app', []);
//add select-all-on-click to any input to use directive
app.directive('selectAllOnClick', [function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var hasSelectedAll = false;
element.on('click', function($event) {
if (!hasSelectedAll) {
try {
//iOS, Safari, thows exception on Chrome etc
this.selectionStart = 0;
this.selectionEnd = this.value.length + 1;
hasSelectedAll = true;
} catch (err) {
//Non iOS option if not supported, e.g. Chrome
this.select();
hasSelectedAll = true;
}
}
});
//On blur reset hasSelectedAll to allow full select
element.on('blur', function($event) {
hasSelectedAll = false;
});
}
};
}]);
input autofocus, with onfocus event:
<INPUT onfocus="this.select()" TYPE="TEXT" NAME="thing" autofocus>
This lets you open a form with the desired element selected. It works by using autofocus to hit the input, which then sends itself an onfocus event, which in turn selects the text.
I was looking for a CSS-only solution and found this works for iOS browsers (tested safari and chrome).
It does not have the same behavior on desktop chrome, but the pain of selecting is not as great there because you have a lot more options as a user (double-click, ctrl-a, etc):
.select-all-on-touch {
-webkit-user-select: all;
user-select: all;
}
Indeed, use onclick="this.select();" but remember not to combine it with disabled="disabled" - it will not work then and you will need to manually select or multi-click to select, still. If you wish to lock the content value to be selected, combine with the attribute readonly.
You can replace
<input type="text" id="userid" name="userid" value="Please enter the user ID" />
With:
<input type="text" id="userid" name="userid" placeholder="Please enter the user ID" />
The placeholder is used to replace value as how you wanted people to be able to Type in the text box without having to click multiple times or using ctrl + a. Placeholder makes it so it isn't a value but as the name suggests a place holder. That is what is used in multiple online forms that says "Username here" or "Email" and when you click on it the "Email" disappears and you can start typing right away.
Here's a reusable version of Shoban's answer:
<input type="text" id="userid" name="userid"
value="Please enter the user ID" onfocus="Clear(this);"
/>
function Clear(elem)
{
elem.value='';
}
That way you can reuse the clear script for multiple elements.
Here's an example in React, but it can be translated to jQuery on vanilla JS if you prefer:
class Num extends React.Component {
click = ev => {
const el = ev.currentTarget;
if(document.activeElement !== el) {
setTimeout(() => {
el.select();
}, 0);
}
}
render() {
return <input type="number" min={0} step={15} onMouseDown={this.click} {...this.props} />
}
}
The trick here is to use onMouseDown because the element has already received focus by the time the "click" event fires (and thus the activeElement check will fail).
The activeElement check is necessary so that they user can position their cursor where they want without constantly re-selecting the entire input.
The timeout is necessary because otherwise the text will be selected and then instantly unselected, as I guess the browser does the cursor-positioning check afterwords.
And lastly, the el = ev.currentTarget is necessary in React because React re-uses event objects and you'll lose the synthetic event by the time the setTimeout fires.
I think its better to control via event. This variant looks pretty intuitively and work with ts as well:
onFocus={e => {
e.target.select();
}
If you need selectAll every click then you can use this:
onClick={e => {
e.target.focus();
e.target.select();
}
The exact solution to what you asked is :
<input type="text" id="userid" name="userid" value="Please enter the user ID" onClick="this.setSelectionRange(0, this.value.length)"/>
But I suppose,you are trying to show "Please enter the user ID" as a placeholder or hint in the input.
So,you can use the following as a more efficient solution:
<input type="text" id="userid" name="userid" placeholder="Please enter the user ID" />
The problem with catching the click event is that each subsequent click within the text will select it again, whereas the user was probably expecting to reposition the cursor.
What worked for me was declaring a variable, selectSearchTextOnClick, and setting it to true by default. The click handler checks that the variable's still true: if it is, it sets it to false and performs the select(). I then have a blur event handler which sets it back to true.
Results so far seem like the behavior I'd expect.
(Edit: I neglected to say that I'd tried catching the focus event as someone suggested,but that doesn't work: after the focus event fires, the click event can fire, immediately deselecting the text).
This question has options for when .select() is not working on mobile platforms: Programmatically selecting text in an input field on iOS devices (mobile Safari)
Html like this
<input type="text" value="click the input to select" onclick="javascript:textSelector(this)"/>
and javascript code without bind
function textSelector(ele){
$(ele).select();
}
Well this is normal activity for a TextBox.
Click 1 - Set focus
Click 2/3 (double click) - Select text
You could set focus on the TextBox when the page first loads to reduce the "select" to a single double-click event.
Use "placeholder" instead of "value" in your input field.
Use this:
var textInput = document.querySelector("input");
textInput.onclick = function() {
textInput.selectionStart = 0;
textInput.selectionEnd = textInput.value.length;
}
<input type="text">
I'm using the focus-attribute in my vue application
<input #focus="$event.target.select()" />
If you are using AngularJS, you can use a custom directive for easy access:
define(['angular'], function () {
angular.module("selectionHelper", [])
.directive('selectOnClick', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.on('click', function () {
this.select();
});
}
};
});
});
Now one can just use it like this:
<input type="text" select-on-click ... />
The sample is with requirejs - so the first and the last line can be skipped if using something else.
If anyone want to do this on page load w/ jQuery (sweet for search fields) here is my solution
jQuery.fn.focusAndSelect = function() {
return this.each(function() {
$(this).focus();
if (this.setSelectionRange) {
var len = $(this).val().length * 2;
this.setSelectionRange(0, len);
} else {
$(this).val($(this).val());
}
this.scrollTop = 999999;
});
};
(function ($) {
$('#input').focusAndSelect();
})(jQuery);
Based on this post . Thanks to CSS-Tricks.com
If you are just trying to have placeholder text that gets replaced when a user selects the element then it is obviously best practice to use placeholder attribute nowadays. However, if you want to select all of the current value when a field gains focus then a combination of #Cory House and #Toastrackenigma answers seems to be most canonical. Use focus and focusout events, with handlers that set/release the current focus element, and select all when focused. An angular2/typescript example is as follows (but would be trivial to convert to vanilla js):
Template:
<input type="text" (focus)="focus()" (focusout)="focusout()" ... >
Component:
private focused = false;
public focusout = (): void => {
this.focused = false;
};
public focus = (): void => {
if(this.focused) return;
this.focused = true;
// Timeout for cross browser compatibility (Chrome)
setTimeout(() => { document.execCommand('selectall', null, false); });
};
If you are looking for a pure vanilla javascript method, you can also use:
document.createRange().selectNodeContents( element );
This will select all the text and is supported by all major browsers.
To trigger the selection on focus, you just need to add the event listener like so:
document.querySelector( element ).addEventListener( 'focusin', function () {
document.createRange().selectNodeContents( this );
} );
If you want to place it inline in your HTML, then you can do this:
<input type="text" name="myElement" onFocus="document.createRange().selectNodeContents(this)'" value="Some text to select" />
This is just another option. There appears to be a few ways of doing this. (document.execCommand("selectall") as mentioned here as well)
document.querySelector('#myElement1').addEventListener('focusin', function() {
document.createRange().selectNodeContents(this);
});
<p>Cicking inside field will not trigger the selection, but tabbing into the fields will.</p>
<label for="">JS File Example<label><br>
<input id="myElement1" value="This is some text" /><br>
<br>
<label for="">Inline example</label><br>
<input id="myElement2" value="This also is some text" onfocus="document.createRange().selectNodeContents( this );" />
Using placeholder="Please enter the user ID" instead of value="Please enter the user ID" is the best approach for this scenario, but the function can be useful in some cases.
<input> elements can already listen to focus event. We can just add the event listener to it instead of document, and there is no further needs to listen to click.
Plain JavaScript:
document.getElementById("userid").addEventListener("focus", function() {
this.select();
});
With JQuery:
$("#userid").on("focus", function() {
this.select();
});
You may use this.setSelectionRange(0, this.value.length) instead of this.select() depends on your purpose but that will not work on some input types such as number.
Live demo
<input id="my_input" style="width: 400px; height: 30px;" value="some text to select">
<br>
<button id="select-bn" style="width: 100px; height: 30px; margin-top: 20px;cursor:pointer;">Select all</button>
<br><br>
OR
<br><br>
Click to copy
<br><br>
<input id="my_input_copy" style="width: 400px; height: 30px;" value="some text to select and copy">
<br>
<button id="select-bn-copy" style="width: 170px; height: 30px; margin-top: 20px;cursor:pointer;">Click copy text</button>
<script type="text/javascript">
$(document).on('click', '#select-bn', function() {
$("#my_input").select();
});
//click to select and copy to clipboard
var text_copy_bn = document.getElementById("select-bn-copy");
text_copy_bn.addEventListener('click', function(event) {
var copy_text = document.getElementById("my_input_copy");
copy_text.focus();
copy_text.select();
try {
var works = document.execCommand('copy');
var msg = works ? 'Text copied!' : 'Could not copy!';
alert(msg);
} catch (err) {
alert('Sorry, could not copy');
}
});
</script>
I have a link inside a label. The problem is, when user clicks 'back' after having read the terms, the checkbox is unchecked, because when they clicked on the link they also unchecked the box at the same time, since the link is inside a label.
<input type="checkbox" id="terms" name="terms" checked="checked" />
<label for="terms">I agree to be bound by the Terms</label>
How can I prevent the checkbox from being checked when link is clicked? Tried doing event.preventDefault() on label click, but that doesn't prevent checkbox from being checked/unchecked.
I could just take out the link from inside a label (which means more CSS styling). But now I'm curious whether the above is possible.
You can cancel the click event by routing it through an onclick event.
The "return false;" part will prevent the click event from moving up to the label.
<input type="checkbox" id="terms" name="terms" checked="checked" />
<label for="terms">I agree to be bound by the Terms</label>
Also good practice to allow opening links with target="_blank" in new tabs.
/*
Fix links inside of labels.
*/
$( 'label a[href]' ).click( function ( e ) {
e.preventDefault();
if ( this.getAttribute( 'target' ) === '_blank' ) {
window.open( this.href, '_blank' );
}
else {
window.location = this.href;
}
});
Why not move the link outside the label?
<label for="terms">I agree to be bound by the</label> Terms
Just add the 'for' attibute and it will prevent from unwanting bubbling
You could have the link open up in a new window so that the page doesn't change.
If you don't want to do that you could check to see if the link has been visited and then automatically check the box.
I have a similar situation, but the link actually opens a new window when clicked. This doesn't check/uncheck the box. I believe it is because the click doesn't bubble up through the link to the label.
So, to extend this, if you want the link to open in the same page, you could make it open using a click handler and preventing the click on the link from bubbling, like so:
$('label a').click(function(ev) { ev.preventDefault(); window.location.href = $(this).attr('href'); }
(It's untested and not the nicest use of JS, but it should solve your issue)
I agree the best way (for usability and ease) would be to open the terms in a new window, but if you wish to open it in the same one you can use this little function:
function stopLabel(e) {
e.preventDefault();
window.location= '/terms';
}
You could also put them straight into your onclick but this is a bit nicer imo.
You would have to pass the event to the function too:
<label for="terms">I agree to be bound by the Terms</label>
If you decide to open it in a new window you can just change the window.location to window.open
The link should be outside the label and not a part of it since clicking on it will trigger two action (opening the link and checking the checkbox).
The user is expecting to trigger only one action,
if the link looks like a link he would expect to be taken to the links target,
or if the text is related to the checkbox the user will expect it to check the checkbox.
If you are ok with opening the link in a new tab (and I think it is better, because maybe the user has already filled some data on the page) then this can be handled even without js
<input type="checkbox" id="agreed" />
<label for="agreed">
I agree with Terms of use and Privacy Policy
</label>
here is js fiddle example
http://jsfiddle.net/davo3/zkcv3L3d/