Keeping a text field in focus - javascript

I thought this would be easy enough to do without seeking help, but I guess not. Adding the autofocus="true" tag works when the page initially loads but the text field loses focus if anyone clicks anywhere or opens a link. How do I force the field to keep focus?

Someone ask why you want to do that .
the answer of-course is as a developers we need to deal we crazy demands by our clients :)
To the answer:
$(document).ready(function(){
$(document).click(function() { $("<THE-ELEMENT>").focus() });
});
In this case we add listener to all elements in the document :)

Attach a click event listener on the document that focus's on the input box on click.
$(document).on("click", function()
{
$("yourInputIdHERE").focus();
}

$("#textbox").focus().on('blur', function() {
$(this).focus();
});

Handling all cases incase where some of the events are prevented from propagating till the document. Also handle the case where user switches tab and comes back.
$("#element").blur(function ()
{
$("#element").focus();
});
$(document).bind('keydown mousedown mouseup click',function ()
{
$("#element").focus();
});

What you might want to try do, is attach an event handler to the blur event. Once you capture it, you can simply trigger a focus event on the same element that lost focus in the first place.
$("input").on('blur',function(){
$(this).focus();
});
You might want to incorporate this with some form of validation so that once the user has entered the desired value, they will be able to leave the text field.
$("input").on('blur',function(){
var $this = $(this);
if ($this.val() == ''){
$this.focus();
showErrorMessage("Please enter a value");
}
});
If you don't implement some form of flag to enable/disable this behavior, you'll be locking the user into one field forever. There will be no (easy) way for them to move to a different area of the page.
Here is a small demo,
you'll notice that once the text field has focus, it will keep it until a value has been entered.

Related

How do I detect when the user changes between inputs pressing 'tab' using jQuery?

I have a view with a form. The form has many inputs, and I would need detect when the user moves between them (clicking or pressing 'tab').
For now I have this:
$('input').on('click',function(){
// Do something
});
But I would need detect if the user focus on these input even if he doesn't use the mouse.
Thank you
How about focus?
$('input').on('focus',function(){
// Do something
});
The focus event is sent to an element when it gains focus. This event is implicitly applicable to a limited set of elements, such as form elements (<input>, <select>, etc.) and links (<a href>).
https://api.jquery.com/focus/
For all text inputs inside the form
$(document).ready(function () {
$('form').on('focus blur', 'input', function () {
// Handle event
});
});
You need to use focus event instead of click:
$('input').on('focus',function(){
// Do something
});

Blur event is fired on focused parent element if focused element's child is clicked

I need to create a part of a form where if you click on a select, a checkbox field should popup and if you click anywhere else again, this field should disappear. I would like to do this with focusing the field after clicking on the select, but for some reason, my checkbox field loses its focus not only when you click anywhere else out of it, but even when you click on a label of a checkbox INSIDE of it. So the problem is that I am focusing an element in which I click on a label and the focused parent element loses its focus for some reason I can not figure out.
The code: http://jsfiddle.net/RELuL/2/
Any helps appreciated!
P.S.:
Just some bonus question :) As you can see, if you click on the select input, my hidden checkbox section is displayed a little late, it is not shown instantly which looks a little bad. Any tips how to optimize this?
EDIT: I use Firefox 13.0.1
When you click on a <label>, the browser focuses the associated input field. So focus leaves the parent and goes to the checkbox (and your blur event handler is called).
Instead of focusing the parent div and relying on it being blurred, attached a click handler to the document:
$(document).click(function() {
multiSelectUpdate();
});
$('.multiselect.container').click(function(event) {
event.stopPropagation(); // prevent click event from reaching document
});
Also, in Webkit clicking on <select> doesn't fire a click event. A workaround is to use the focus event instead.
Demo
Ok two simple changes got this working first change the click listen on the select box to a mousedown listener like so.
$('.multiselector').mousedown(function(event) {
event.preventDefault();
currentMulti = $(this).attr('id');
thisOffset = $(this).offset();
$(this).hide();
$('#' + currentMulti + '-container')
.css('top', thisOffset.top + 'px').show().attr("tabindex", -1).focus();
$(this).addClass('active');
});
this triggers before the box is able to comes up so it never shows.
Secondly the blur listener was believing it lost focus when a child got focus to fix this change to focusout.
$('.multiselect.container').focusout(function() {
multiSelectUpdate();
});
This only fires when the selector loses focus even focus currently on child of selector.
Fixed fiddle
enjoy :)
EDIT
For some reason blur fires multiple times on FF so to work round this use instead of blur mouseleave.
$('.multiselect.container').mouseleave(function() {
multiSelectUpdate();
});

Run javascript/jquery after text change but before submit

I have an input element on a form along with a submit button.
I want to run the change event on the input element all whenever a change occurs. The problem is if end user changes text and clicks submit button the code in the change event doesn't run.
Immediately after user clicks the submit button, the form submits (like the change is not getting time to run, the same occurs with blur or focus out).
My controls can be placed on any form, and I do not control the click event of the button.
Help please
If you're wanting to catch whenever input in a textbox is changed try this in the document.ready
$("input[type='text']").change( function() {
$("#SubmitButton").attr('disabled', 'disabled');
// check input ($(this).val()) for validity here
// after text is updated..etc, enable the button
$("#SubmitButton").removeAttr('disabled');
});
may be you want use event.preventDefault
Expanding on #Aleks G's comment, the best thing for you to do is trigger your change handling on more than just the change event. Beyond keyup, I've found you also need to be careful to handle pasting with the mouse (doesn't trigger the keyup or change event):
yourInput.bind('change keyup paste', function() {
// Your code
});

How do you avoid losing focus on a contenteditable element when a user clicks outside that element?

I want to prevent a contentEditable area from losing focus if a click is made outside that area. Some sample HTML looks like this:
<div id="content">
<p>Hello</p>
</div>
<div id="clickThis">
<p>If you click on this or anywhere for that matter after focusing on Hello, you lose your focus on Hello</p>
</div>
Sample Javascript looks as follows:
$(document).ready(function()
{
$('#content')[0].contentEditable=true;
$('#clickThis').bind('click',function(e)
{
console.log(window.getSelection().getRangeAt(0).startContainer);
e.preventDefault();
});
});
When you click on the #clickThis div or anywhere outside the #content div, you lose focus on the #content div even if you call the click event's preventDefault function.
In addition, the range changes the moment the click event is fired, so I can't just return to the previous range after the click has occurred. Is there a way to maintain the cursor position and focus after a click occurs?
jsFiddle: http://jsfiddle.net/VivekVish/FKDhe/4/
Putting Juan's question into an answer, instead of using the click event, you have to use the mousedown event as follows:
$(document).ready(function()
{
$('#content')[0].contentEditable=true;
$('#clickThis').bind('mousedown',function(e)
{
console.log(window.getSelection().getRangeAt(0).startContainer);
e.preventDefault();
});
});
You can see it working here:
http://jsfiddle.net/FKDhe/7/
The answer is to add event.preventDefault() to the mouseDown event.
const button = document.getElementById('boldFormat')
button.addEventListener('mousedown', (event) => {
event.preventDefault() // prevent loss of focus
document.execCommand('bold', false)
})
The problem occurred because the you are listening to the click event which causes the contentEditable element to lose focus; regardless of whether you run preventDefault or not.
try adding $('#content').focus(); after e.preventDefault();
it's not a perfect solution, since it jumps to the beginning, but give it a try.
anyway, are you sure it's a good idea to force the user back to this area? :)

DOM problem with click initiating a focusout event on a different input

I have an <input type=text> with focusout event handler
I have a <button> with click event handler
Focusout checks whether format in input box is correct. It does so by testing input value against a regular expression. If it fails it displays a message (a div fades-in and -out after some time) and refocuses my input by calling
window.setTimout(function() { $(this).focus(); }, 10);
since I can't refocus in focusout event handler. focusout event can't be cancelled either. Just FYI.
Click collects data from input elements and sends it using Ajax.
The problem
When user TABs their way through the form everything is fine. When a certain input box failes formatting check it gets refocused immediately after user presses TAB.
But when user doesn't use TAB but instead clicks on each individual input field everything works fine until they click the button. focusout fires and sets time-out for refocusing. Since time-out is so short focusing happens afterwards and then click event fires and issues an Ajax request.
Question
I have implemented my formatting check as an independent jQuery plugin that I want to keep that way. It uses .live() to attach focusout on all input fields with a particular attribute where format regular expression is defined.
Data submission is also generic and I don't want to make it dependant on formatting plugin. They should both stay independent.
How can I prevent click event from executing without making these two plugins dependant?
Example code I'm fiddling with
After some searching I've seen that all major browser support document.activeElement but I can't make it work in Chrome. FF and IE both report this being the active element, but Chrome always says it's BODY that is active even though click fired on the button element.
Check this code http://jsfiddle.net/Anp4b/1/ and click on the button. Test with Chrome and some other browser and see the difference.
You could use a flag...
Live demo: http://jsfiddle.net/Anp4b/4/
So your question is:
How can I prevent click event from executing without making these two plugins dependent?
Well, you obviously cannot prevent the click event. If the user wants to click the button, he will, and the click event will trigger. There's nothing you can do about that.
So the answer to the above question is: You cannot.
Based on the current conditions, you have to - inside the click handler - retrieve the validation result, and based on that result, decide if form submission should or should not occur.
JS Code:
$("#Name").focusout(function(){
var that = this;
valid = this.value.length ? true : false;
!valid && window.setTimeout(function() {
$(that).focus();
}, 0);
});
$("#Confirm").click(function(e) {
if ( !valid ) { return false; }
e.preventDefault();
alert('AJAX-TIME :)');
});
HTML Code:
<input type="text" id="Name">
<button id="Confirm">OK</button>
Is there are reason you use .focusout instead of .blur?
Using a flag is a good idea, but I would rather use a class on the element. By using classes to determine the state you can also style it accordingly. Here's my example based on your fiddle.
Another solution that hopefully gives the result you are looking for.
1) Create a named click handler:
var clickHandler = function(e){ /** submit form or whatever you want to do**/ };
$("button").click(clickHandler);
2) Add the following to the focusout event when it's failing validation:
$("button").unbind("click", clickHandler).one("click", function(){ button.click(clickHandler); return false;});
You can find an example of this here.

Categories