There is an input with some text. All text in this input has to be selected when input is focusing (first click on input) and specific word has to be selected when second click on input occurs.
I try to implement the same functionality that URL-bar in Chrome(Version 74.0.3729.131 (Official Build) (64-bit)) has.
Current behavior of input you can see here: https://jsfiddle.net/deaamod1s/rh5mw0e4/23/
The only solution I see it's to check was the input double-clicked or not and after that if input wasn't double-clicked - to do input.select()
input.onfocus = function(e) {
let hasValueWhenGotFocused = false;
if (input.value) {
hasValueWhenGotFocused = true;
}
setTimeout(() => {
if (hasValueWhenGotFocused && this.className.indexOf("doubleclicked") == -1) {
this.select();
} else {
this.classList.remove("doubleclicked");
}
},400);
}
input.ondblclick = function(e){
this.classList.add('doubleclicked');
}
The onfocus event handler is always executed before the ondblclick.
I suggest to delay the focus handler so that it can be executed after a possible double click (updated fiddle here):
input.ondblclick = function (e) {
// set....
this.dataset.dblclick = true;
}
input.onfocus = function (e) {
this.dataset.dblclick = false;
setTimeout(function (_this) {
// if not set...
if (_this.dataset.dblclick == "false") {
_this.select();
} else {
// remove ...
delete _this.dataset.dblclick;
}
}, 200, this);
}
Try to select second word using only two click<br>
<input type="text" id="input" value="sdsas select_me">
Related
I have an input field with the name box. I can move forward after input by
box.addEventListener('input', function () {
if(!isNaN(parseInt(box.value))){
box.value = "";
}else if(box != null){
box.nextSibling.focus();
}
});
And it's working alright. I wish to move to the previous sibling of the input by backspace, and I am doing it by the previous sibling and kind of the same logic
box.addEventListener('keyup', function (e) {
if(e.key == 'Backspace' && box != null){
box.previousSibling.focus();
}
})
But doing this only works for the first backspace properly, for the rest of the inputs I need to backspace twice. I tried with the keydown event too and even that wasn't perfect.
The problem is that (in the browsers you and I are using) input events are processed before keyup events, so you press backspace on a non-empty box and a character is deleted, so input is processed then the next sibling is selected, then the keyup is processed and you move to the previous sibling, which looks like going nowhere.
You can fix this by storing the box where the value changed, then if that reference is not null on backspace keyup you can move to the previous sibling of the box where the keyup event fired, otherwise move to the previous sibling of the box where the input event fired.
const boxes = document.getElementById('boxes');
let inputInput = null;
for(let i = 0; i < 12; i++)
{
const box = document.createElement('input');
box.type="text"
box.addEventListener('input', function (e)
{
if(!isNaN(parseInt(box.value)))
{
box.value = "";
}
else if(box != null)
{
inputInput = box;
box.nextSibling.focus();
}
});
box.addEventListener('keyup', function (e)
{
if(e.key == 'Backspace' && box != null)
{
if(inputInput == null)
{
box.previousSibling.focus();
}
else
{
inputInput.previousSibling.focus();
inputInput = null;
}
}
});
boxes.appendChild(box);
}
<div id="boxes">
</div>
The problem with this solution is that event precedence is not part of the specification, so this is not necessarily cross browser compatible, i.e. in some browsers keyup might happen before input.
can we stop prevent blur or tabbing for 5 second in input field.then after 5 second user can tab from one field to another.I use off and on function but it is not working .here is my code
http://jsfiddle.net/GV3YY/99/
$("input").off("blur");
setTimeout(function(){
$("input").on("blur");
},5000)
You need to "lock" the inputs when they is focused and use setTimeout to "unlock" it after 5 seconds. A naive implementation could look something like this: https://jsfiddle.net/my7wk6gj/2/
Update: Now pseudo prevents bluring by click. The blur still happens, but focus is returned to the original input until the 5 seconds have passed. I couldn't get event.stopImmediatePropagation to work for blur, so this is the next best thing...
var lockInput = false;
var focusTarget = null;
var lockTimeout = null;
$('input').on('focus', function (e) {
if (lockTimeout) {
return;
}
lockInput = true;
lockTimeout = setTimeout(function () { lockInput = false; lockTimeout = null }, 5000)
}).on('keydown', function (e) {
if (e.keyCode === 9 && lockInput) {
e.preventDefault();
return false;
}
}).on('blur', function (e) {
console.log('blur')
if (lockInput && focusTarget === null) {
focusTarget = e.target;
setTimeout(function () {
focusTarget.focus();
focusTarget = null;
});
}
});
The global variables are used only for the example, i'd advice against that.
Also, if you have a large number of inputs, i'd suggest using event delegation, instead of adding a listener to every one of them.
I'm using the following code to detect multiple keys on a keypress event:
var down = [];
$(document).keydown(function (e) {
down[e.keyCode] = true;
}).keyup(function (e) {
if (down[17] && down[32]) {
// Do something
}
down[e.keyCode] = false;
});
However, this hotkey (CTRL + SPACE) is meant to be used while an input field has focus. So whenever I press the key combination, it also adds a space to the input field.
How can I prevent this from happening? I've looked at ways to disable spaces in input (like this), but I can't figure out how to make it work inside my keypress event only.
You may try this. I hope it helps.
var down = [];
$(document).keydown(function (e) {
down[e.keyCode] = true;
}).keypress(function (e) {
if (down[17] && down[32]) {
var $sampleTextBox = $("input#sampleTextBox");
$sampleTextBox.val($sampleTextBox.val().replace(/\s/g, ''));
alert($sampleTextBox.val().length)
alert("Ctrl + Space Pressed!");
}
down[e.keyCode] = false;
}).keyup(function (e) {
if (down[17] && down[32]) {
var $sampleTextBox = $("input#sampleTextBox");
$sampleTextBox.val($sampleTextBox.val().replace(/\s/g, ''));
alert($sampleTextBox.val().length)
alert("Ctrl + Space Pressed!");
}
down[e.keyCode] = false;
});
--
Thanks,
SuperCoder
I ended up using a different approach, as MelanciaUK suggested.
On the keyup event, it removes the last character in the input field.
var down = [];
$(document).keydown(function (e) {
down[e.keyCode] = true;
}).keyup(function (e) {
if (down[17] && down[32]) {
// Do something
input = $(':focus');
input.val(function (index, value) {
return value.substr(0, value.length - 1);
});
}
down[e.keyCode] = false;
});
While it doesn't prevent the space from being added, it removes it immediately.
i'm using jquery.maskedinput-1.2.2.js and there is a bug when i tab the textbox with a masked input
heres my code:
$(document).ready(function(){
$default = $('input[type="text"].required');
$default.live('focus.checkDefault', function() {
var el = $(this);
if (el.hasClass('default')) {
el.removeClass('default').val('');
}
if (el.attr('name') === 'landline_number') {
$(this).mask('(99)(99)999-9999', {placeholder:'_'});
}
if (el.attr('name') === 'mobile_number') {
$(this).mask('(99)999-999-9999', {placeholder:'_'});
}
if (el.attr('name') === 'secondary_number') {
$(this).mask('(99)999-999-9999', {placeholder:'_'});
}
});
});
when i tab at the textbox landline_number to mobile_number, the landline_number masked input will be bug.
Seem like you want to use focus event on .checkDefault element, if so you can do:
$default.on('focus', '.checkDefault', function() {
I have created a form with malsup's Form Plugin wherein it submits on change of the inputs. I have set up my jQuery script to index drop down menus and visible inputs, and uses that index to determine whether keydown of tab should move focus to the next element or the first element, and likewise with shift+tab keydown. However, instead of moving focus to the first element from the last element on tab keydown like I would like it to, it moves focus to the second element. How can I change it to cycle focus to the actual first and last elements? Here is a live link to my form: http://www.presspound.org/calculator/ajax/sample.php. Thanks to anyone that tries to help. Here is my script:
$(document).ready(function() {
var options = {
target: '#c_main',
success: setFocus
};
$('#calculator').live('submit', function() {
$(this).ajaxSubmit(options);
return false;
});
$(this).focusin(function(event) {
var shiftDown = false;
$('input, select').each(function (i) {
$(this).data('initial', $(this).val());
});
$('input, select').keyup(function(event) {
if (event.keyCode==16) {
shiftDown = false;
$('#shiftCatch').val(shiftDown);
}
});
$('input, select').keydown(function(event) {
if (event.keyCode==16) {
shiftDown = true;
$('#shiftCatch').val(shiftDown);
}
if (event.keyCode==13) {
$('#captured').val(event.target.id);
} else if (event.keyCode==9 && shiftDown==false) {
return $(event.target).each(function() {
var fields = $(this).parents('form:eq(0),calculator').find('select, input:visible');
var index = fields.index(this);
var nextEl = fields.eq(index+1).attr('id');
var firstEl = fields.eq(0).attr('id');
var focusEl = '#'+firstEl;
if (index>-1 && (index+1)<fields.length) {
$('#captured').val(nextEl);
} else if(index+1>=fields.length) {
if ($(this).val() != $(this).data('initial')) {
$('#captured').val(firstEl);
} else {
event.preventDefault();
$(focusEl).focus();
}
}
return false;
});
} else if (event.keyCode==9 && shiftDown==true) {
return $(event.target).each(function() {
var fields = $(this).parents('form:eq(0),calculator').find('select, input:visible');
var index = fields.index(this);
var prevEl = fields.eq(index-1).attr('id');
var lastEl = fields.eq(fields.length-1).attr('id');
var focusEl = '#'+lastEl;
if (index<fields.length && (index-1)>-1) {
$('#captured').val(prevEl);
} else if (index==0) {
if ($(this).val() != $(this).data('initial')) {
$('#captured').val(lastEl);
} else {
event.preventDefault();
$(focusEl).select();
}
}
return false;
});
}
});
});
});
function setFocus() {
with (document.calculator)
var recap = document.getElementById(recaptured.value);
if (recap!=null) {
setTimeout(function() {
if (recap.getAttribute('type')=='text') {
recap.select();
} else {
recap.focus();
}
}, 100 );
}
}
Edit #1: I made a few minor changes to the code, which has brought me a little closer to my intended functionality of the script. However, I only made one change to the code pertaining to the focus: I tried to to disable the tab keydown when pressed on the last element (and also the shift+tab keydown on the first element) in an attempt to force the focus on the element I want without skipping over it like it has been doing. This is the code I added:
$(this).one('keydown', function (event) {
return !(event.keyCode==9 && shiftDown==true);
});
This kind of works. After the page loads, If the user presses tab on the last element without making a change to its value, the focus will be set to the second element. However, the second time the user presses tab on the last element without making a change to its value, and every subsequent time thereafter, the focus will be set to the first element, just as I would like it to.
Edit #2: I replaced the code in Edit #1, with code utilizing event.preventDefault(), which works better. While if a user does a shift+tab keydown when in the first element, the focus moves to the last element as it should. However, if the user continues to hold down the shift key and presses tab again, focus will be set back to the first element. And if the user continues to hold the shift key down still yet and hits tab, the focus will move back to the last element. The focus will shift back and forth between the first and last element until the user lifts the shift key. This problem does not occur when only pressing tab. Here is the new code snippet:
event.preventDefault();
$(focusEl).focus();
You have a lot of code I didn't get full overview over, so I don't know if I missed some functionality you wanted integrated, but for the tabbing/shift-tabbing through form elements, this should do the work:
var elements = $("#container :input:visible");
var n = elements.length;
elements
.keydown(function(event){
if (event.keyCode == 9) { //if tab
var currentIndex = elements.index(this);
var newIndex = event.shiftKey ? (currentIndex - 1) % n : (currentIndex + 1) % n;
var el = elements.eq(newIndex);
if (el.attr("type") == "text")
elements.eq(newIndex).select();
else
elements.eq(newIndex).focus();
event.preventDefault();
}
});
elements will be the jQuery object containing all the input fields, in my example it's all the input fields inside the div #container
Here's a demo: http://jsfiddle.net/rA3L9/
Here is the solution, which I couldn't have reached it without Simen's help. Thanks again, Simen.
$(document).ready(function() {
var options = {
target: '#c_main',
success: setFocus
};
$('#calculator').live('submit', function() {
$(this).ajaxSubmit(options);
return false;
});
$(this).focusin(function(event) {
$('#calculator :input:visible').each(function (i) {
$(this).data('initial', $(this).val());
});
return $(event.target).each(function() {
$('#c_main :input:visible').live(($.browser.opera ? 'keypress' : 'keydown'), function(event){
var elements = $("#calculator :input:visible");
var n = elements.length;
var currentIndex = elements.index(this);
if (event.keyCode == 13) { //if enter
var focusElement = elements.eq(currentIndex).attr('id');
$('#captured').val(focusElement);
} else if (event.keyCode == 9) { //if tab
var newIndex = event.shiftKey ? (currentIndex - 1) % n : (currentIndex + 1) % n;
var el = elements.eq(newIndex);
var focusElement = el.attr('id');
if ($(this).val() != $(this).data('initial')) {
$('#captured').val(focusElement);
} else if ((currentIndex==0 && event.shiftKey) || (currentIndex==n-1 && !event.shiftKey)) {
event.preventDefault();
if (el.attr('type')=='text') {
$.browser.msie ? "" : $(window).scrollTop(5000);
el.select().delay(800);
} else {
$.browser.msie ? "" : $(window).scrollTop(-5000);
el.focus().delay(800);
}
} else if (el.is('select')) {
event.preventDefault();
if (el.attr('type')=='text') {
el.select();
} else {
el.focus();
}
}
}
});
});
});
});
function setFocus() {
with (document.calculator)
var recap = document.getElementById(recaptured.value);
if (recap!=null) {
setTimeout(function() {
if (recap.getAttribute('type')=='text') {
recap.select();
} else {
recap.focus();
}
}, 1 );
}
}
I put my files available to download in my live link: http://www.presspound.org/calculator/ajax/sample.php