change cursor focus after filling input field to next input - javascript

I'm working on a project where I use javascript to create a random number of input fields with maxlength = "1" and when the user fills all of them with one letter each a submit button appears .
The problem is that when a field is filled I want the cursor to move to the next input field . I am trying to add this functionality to my input elements using an eventlistener with the onkeyup event . However when I implement this in code the cursor movement functionality is not working and when I inspect my page I see no errors .
My code :
https://jsfiddle.net/bill_sk/2t7vLc5y/2/
I would appreciate your help with this . Thank you in advance .

inputLists.forEach(input => {
input.addEventListener("keyup", ()=>{
if(input.value.length === input.maxLength && parseInt(input.id) < inputLists.length) {
document.getElementById(parseInt(input.id)+1).focus();
}
})
input.id will give you a string, so you have to parse it to int.
event should be "keyup", and not "onkeyup"
always look out for the last element in an array when you want add something to the next element in a for cycle
use the inputList variable that you initialize at the top of the function, the code will be more readable
Happy coding!

First you need to listen to the keyup event not the onkeyup event
elem.addEventListener("keyup" , evt => {
and then get the next input element like this
let el = document.getElementById(parseInt(elem.id) +1).focus();

Try "keyup" instead of "onkeyup".
If you are working on something like this, always try to find out, which part of the code is not working with console.log()
There were some other mistakes, but this works
elem.addEventListener("keyup" , evt => {
elem = evt.target
if(elem.value.length >= elem.maxLength){
let el = document.getElementById(parseInt(elem.id) +1)
el.focus();
}
});

Related

Upon attaching EasyAutocomplete to input box, it loses focus

I am using EasyAutocomplete, it works well, only problem I am facing - Input box loses control when EasyAutocomplete is attached to it.
I want EasyAutocomplete to get activated after the user has typed 2 characters.
When I type 1 character nothing happens as needed, but after 2nd character has been typed EasyAutocomplete must get attached and should start working. However, what happens is I have to click outside of the input box to make things happen.
It is just this 'outside click', that I have to do to make this plugin work, is problematic for me.
I have tried input event as well but i did not work as required.
The change event seems quite suited for my requirement.
How do I solve this issue?
var ib = $("#inputbox");
$(document).on("keyup", ib,function(e) {
leng = ib.val();
});
$(document).on("change", ib,function(e) {
if(leng.length < 2){
#do something
}else{
ib.easyAutocomplete(options);
}
});
First you should change "change" by "keyup"
Second leng doesn't update as you put it outside of the event
Lastly an event on document may not be the best if you want this event to trigger only on this element, change document by your element
$("#inputbox").on("keyup", ib,function(e) {
if($("#inputbox").val().length < 2){
#do something
}else{
ib.easyAutocomplete(options);
}
});

Run a javascript function as user is inputting

I don't usually like to bother you all but I'm stuck on something and I can't find an answer anywhere, hope you guys can help me out!
I'm building a web app and designing it so the interface matches iOS7.
http://danj.eu/webdesign/new
I've got an input form, and I need the button to submit the form to only turn blue and become selectable once the validation has completed. I've wrote some JS to validate the input but this only runs once! I need to run the function every time the user modifies the value of the input.
This is what I've got so far for the JS:
function validateInput(){
if (document.getElementById('projectname').value.length < 2)
document.getElementById('forwardbutton').style.color = "#c4c4c5";
else
document.getElementById('forwardbutton').style.color = "#0e81ff";
}
Thanks guys!
add to your input onchange listener:
var input = document.getElementById("myInput");
input.addEventListener('change', validateInput, false);
this will fire validateInput function every time the value changes.
PS. you should cache your DOM elements that you get in your validation function, because it's searching through the DOM to find them always when function is fired- this can be heavy in a big DOM tree
jsFiddle Demo
You can bind to the input event using jquery which handles virtually all input events simultaneously
<input id="myInput" type="text" />
<div id="output"></div>
js
$('#myInput').bind('input',function(){
if( this.value.length < 2 ){
document.getElementById('output').style.color = "#c4c4c5";
}else{
document.getElementById('output').style.color = "#0e81ff";
}
$('#output').html(this.value);
});
I do not know if you are opposed to jQuery, but I'll provide the jQuery way of doing this. It's very simple with jQuery. You'd use a keyboard event handler, specifically the Key Up event handler.
In your event handler, you'd then check the length of the field and based on the length you would set the enabled or disabled state of the button.
$('#input-element').keyup(function () {
if (document.getElementById('projectname').value.length < 2)
document.getElementById('forwardbutton').style.color = "#c4c4c5";
else
document.getElementById('forwardbutton').style.color = "#0e81ff";
}
});
You can also use jQuery to set the color or enabled state as well, instead of your previous code. Up to you.
Do you mean
function validateInput(){
if (document.getElementById('projectname').value.length < 2)
document.getElementById('forwardbutton').style.color = "#c4c4c5";
else
document.getElementById('forwardbutton').style.color = "#0e81ff";
}
and then perhaps this?
document.getElementById('projectname').onchange=validateInput;
More information would be helpful.

How do I properly capture an onchange or onkeyup event for a dynamically inserted 'input' text element?

I have a bit of JavaScript that builds some HTML for me and inserts it into a div. I am using jQuery 1.7.2 for this test.
I'm interested in attaching a custom change or keyup event handler on an input text field called gene_autocomplete_field.
Here's what I have tried so far.
The following function builds the HTML, which is inserted into a div called gene_container:
function buildGeneContainerHTML(count, arr) {
var html = "";
// ...
html += "<input type='text' size='20' value='' id='gene_autocomplete_field' name='gene_autocomplete_field' placeholder='Enter gene name...' /><br/>";
// ...
return html;
}
// ...
$('#gene_container').html( buildGeneContainerHTML(count, geneNameArr) );
In my calling HTML, I grab the gene_autocomplete_field from the gene_container element, and then I override the keyup event handler for gene_autocomplete_field:
<script>
$(document).ready(function() {
$("#gene_container input:[name=gene_autocomplete_field]").live('keyup', function(event) {
refreshGenePicker($("#gene_container input:[name=gene_autocomplete_field]").val());
});
});
</script>
When I change the text in gene_autocomplete_field, the refreshGenePicker() function just sends an alert:
function refreshGenePicker(val) {
alert(val);
}
Result
If I type any letter into the gene_autocomplete_field element, the event handler seems to call alert(val) an infinite number of times. I get one alert after another and the browser gets taken over by the dialog boxes. The value returned is correct, but I worry that refreshGenePicker() gets called over and over again. This is not correct behavior, I don't think.
Questions
How do I properly capture the keyup event once, so that I only handle a content change to the autocomplete field the one time?
Is there a different event I should use for this purpose?
UPDATE
It turns out that more than just a keyCode of 13 (Return/Enter) can be an issue — pressing Control, Alt, Esc or other special characters will trigger an event (but will be asymptomatic, as far as the infinite loop issue goes). The gene names I am filtering on do not have metacharacters in them. So I made use of an alphanumeric detection test to filter out non-alphanumeric characters from further event handling, which includes the Return key:
if (!alphaNumericCheck(event.keyCode)) return;
alert is called infinite times because you use the 'Enter' key to confirm/dismiss the alert. Use .on('change') instead. This will prevent refreshGenePicker from being called when you use enter in an alert.
JSFiddle demonstration using keyup (Click on OK to prevent infinite alerts).
JSFiddle demonstration using change
However, the 'change' event will only trigger if the input element looses focus. If you want to use refreshGenePicker on every key, use the following approach instead:
$("#gene_container input:[name=gene_autocomplete_field]").live('keyup', function(event) {
if(event.keyCode === 13) // filter ENTER
return;
refreshGenePicker($("#gene_container input:[name=gene_autocomplete_field]").val());
});
This will filter any incoming enter keyup events (jsFiddle demo). Also switch to .on and drop .live.
EDIT: Note that there are more possibilities to dismiss an alert modal, such as the escape or space key. You should add a check inside your refreshGenePicker whether the value has actually changed.
You should really use .on() if you are using jQuery > 1.7.
Check out the perftest.
And also check out my some what related question.
Also when testing equal you should really add quotes around it:
input:[name='gene_autocomplete_field']
To answer you real question :). It shouldn;t behave like that with the code you have presented. Maybe something else is wrong. Can you setup a jsfiddle with the issue?
Check out my demo and perhaps you see what's wrong with your code:
function refreshGenePicker(value) {
console.log('keyup! Value is now: ' + value);
}
(function($) {
var someHtml = '<input type="text" name="gene_autocomplete_field">';
$('body').append(someHtml);
$('body').on('keyup', 'input[name="gene_autocomplete_field"]', function(e) {
refreshGenePicker($(this).val());
});
})(jQuery);​
$(document).ready(function() {
$('#test').html('<input id="text" />');
$('#text').keyup(function() {
console.log($(this).val());
});
});​
This works just fine. Since you've got our second code block in <script> tags, you might be running it more than once - which would cause it to bind more than once and produce more than one alert each time it is bound. You could of course use .unbind() on that input before adding the keyup, but I think a much better solution would be to group all the code in a single $(document).ready(); to ensure you're only binding the object once.
http://jsfiddle.net/Ka7Ty/2/

Any event triggered on autocomplete?

I have a pretty simple form. When the user types in an input field, I want to update what they've typed somewhere else on the page. This all works fine. I've bound the update to the keyup, change and click events.
The only problem is if you select an input from the browser's autocomplete box, it does not update. Is there any event that triggers when you select from autocomplete (it's apparently neither change nor click). Note that if you select from the autocomplete box and the blur the input field, the update will be triggered. I would like for it to be triggered as soon as the autocomplete .
See: http://jsfiddle.net/pYKKp/ (hopefully you have filled out a lot of forms in the past with an input named "email").
HTML:
<input name="email" />
<div id="whatever"><whatever></div>
CSS:
div {
float: right;
}
Script:
$("input").on('keyup change click', function () {
var v = $(this).val();
if (v) {
$("#whatever").text(v);
}
else {
$("#whatever").text('<whatever>');
}
});
I recommending using monitorEvents. It's a function provide by the javascript console in both web inspector and firebug that prints out all events that are generated by an element. Here's an example of how you'd use it:
monitorEvents($("input")[0]);
In your case, both Firefox and Opera generate an input event when the user selects an item from the autocomplete drop down. In IE7-8 a change event is produced after the user changes focus. The latest Chrome does generate a similar event.
A detailed browser compatibility chart can be found here:
https://developer.mozilla.org/en-US/docs/Web/Events/input
Here is an awesome solution.
$('html').bind('input', function() {
alert('test');
});
I tested with Chrome and Firefox and it will also work for other browsers.
I have tried a lot of events with many elements but only this is triggered when you select from autocomplete.
Hope it will save some one's time.
Add "blur". works in all browsers!
$("input").on('blur keyup change click', function () {
As Xavi explained, there's no a solution 100% cross-browser for that, so I created a trick on my own for that (5 steps to go on):
1. I need a couple of new arrays:
window.timeouts = new Array();
window.memo_values = new Array();
2. on focus on the input text I want to trigger (in your case "email", in my example "name") I set an Interval, for example using jQuery (not needed thought):
jQuery('#name').focus(function ()
{
var id = jQuery(this).attr('id');
window.timeouts[id] = setInterval('onChangeValue.call(document.getElementById("'+ id +'"), doSomething)', 500);
});
3. on blur I remove the interval: (always using jQuery not needed thought), and I verify if the value changed
jQuery('#name').blur(function ()
{
var id = jQuery(this).attr('id');
onChangeValue.call(document.getElementById(id), doSomething);
clearInterval(window.timeouts[id]);
delete window.timeouts[id];
});
4. Now, the main function which check changes is the following
function onChangeValue(callback)
{
if (window.memo_values[this.id] != this.value)
{
window.memo_values[this.id] = this.value;
if (callback instanceof Function)
{
callback.call(this);
}
else
{
eval( callback );
}
}
}
Important note: you can use "this" inside the above function, referring to your triggered input HTML element. An id must be specified in order to that function to work, and you can pass a function, or a function name or a string of command as a callback.
5. Finally you can do something when the input value is changed, even when a value is selected from a autocomplete dropdown list
function doSomething()
{
alert('got you! '+this.value);
}
Important note: again you use "this" inside the above function referring to the your triggered input HTML element.
WORKING FIDDLE!!!
I know it sounds complicated, but it isn't.
I prepared a working fiddle for you, the input to change is named "name" so if you ever entered your name in an online form you might have an autocomplete dropdown list of your browser to test.
Detecting autocomplete on form input with jQuery OR JAVASCRIPT
Using: Event input. To select (input or textarea) value suggestions
FOR EXAMPLE FOR JQUERY:
$(input).on('input', function() {
alert("Number selected ");
});
FOR EXAMPLE FOR JAVASCRIPT:
<input type="text" onInput="affiche(document.getElementById('something').text)" name="Somthing" />
This start ajax query ...
The only sure way is to use an interval.
Luca's answer is too complicated for me, so I created my own short version which hopefully will help someone (maybe even me from the future):
$input.on( 'focus', function(){
var intervalDuration = 1000, // ms
interval = setInterval( function(){
// do your tests here
// ..................
// when element loses focus, we stop checking:
if( ! $input.is( ':focus' ) ) clearInterval( interval );
}, intervalDuration );
} );
Tested on Chrome, Mozilla and even IE.
I've realised via monitorEvents that at least in Chrome the keyup event is fired before the autocomplete input event. On a normal keyboard input the sequence is keydown input keyup, so after the input.
What i did is then:
let myFun = ()=>{ ..do Something };
input.addEventListener('change', myFun );
//fallback in case change is not fired on autocomplete
let _k = null;
input.addEventListener( 'keydown', (e)=>_k=e.type );
input.addEventListener( 'keyup', (e)=>_k=e.type );
input.addEventListener( 'input', (e)=>{ if(_k === 'keyup') myFun();})
Needs to be checked with other browser, but that might be a way without intervals.
I don't think you need an event for this: this happens only once, and there is no good browser-wide support for this, as shown by #xavi 's answer.
Just add a function after loading the body that checks the fields once for any changes in the default value, or if it's just a matter of copying a certain value to another place, just copy it to make sure it is initialized properly.

Why is my onchange function called twice when using .focus()?

TLDR
Check this example in chrome.
Type someting and press tab. see one new box appear
type something and press enter. see two new boxes appear, where one is expected.
Intro
I noticed that when using enter rather then tab to change fields, my onchange function on an input field was firing twice. This page was rather large, and still in development (read: numerous other bugs), so I've made a minimal example that shows this behaviour, and in this case it even does it on 'tab'. This is only a problem in Chrome as far as I can tell.
What it should do
I want to make a new input after something is entered into the input-field. This field should get focus.
Example:
javascript - needing jquery
function myOnChange(context,curNum){
alert('onchange start');
nextNum = curNum+1;
$(context.parentNode).append('<input type="text" onchange="return myOnChange(this,'+nextNum+')" id="prefix_'+nextNum+'" >');
$('#prefix_'+nextNum).focus();
return false;
}
HTML-part
<div>
<input type="text" onchange="return myOnChange(this,1);" id="prefix_1">
</div>
the complete code is on pastebin. you need to add your path to jquery in the script
A working example is here on jFiddle
The onchange gets called twice: The myOnChange function is called, makes the new input, calls the focus(), the myOnChange gets called again, makes a new input, the 'inner' myOnChange exits and then the 'outer' myOnchange exits.
I'm assuming this is because the focus change fires the onchange()?. I know there is some difference in behaviour between browsers in this.
I would like to stop the .focus() (which seems to be the problem) to NOT call the onchange(), so myOnChange() doesn't get called twice. Anybody know how?
There's a way easier and more reasonable solution. As you expect onchange fire when the input value changes, you can simply explicitly check, if it was actually changed.
function onChangeHandler(e){
if(this.value==this.oldvalue)return; //not changed really
this.oldvalue=this.value;
// .... your stuff
}
A quick fix (untested) should be to defer the call to focus() via
setTimeout(function() { ... }, 0);
until after the event handler has terminated.
However, it is possible to make it work without such a hack; jQuery-free example code:
<head>
<style>
input { display: block; }
</style>
<body>
<div></div>
<script>
var div = document.getElementsByTagName('div')[0];
var field = document.createElement('input');
field.type = 'text';
field.onchange = function() {
// only add a new field on change of last field
if(this.num === div.getElementsByTagName('input').length)
div.appendChild(createField(this.num + 1));
this.nextSibling.focus();
};
function createField(num) {
var clone = field.cloneNode(false);
clone.num = num;
clone.onchange = field.onchange;
return clone;
}
div.appendChild(createField(1));
</script>
I can confirm myOnChange gets called twice on Chrome. But the context argument is the initial input field on both calls.
If you remove the alert call it only fires once. If you are using the alert for testing only then try using console instead (although you need to remove it for testing in IE).
EDIT: It seems that the change event fires twice on the enter key. The following adds a condition to check for the existence of the new field.
function myOnChange(context, curNum) {
nextNum = curNum+1;
if ($('#prefix_'+nextNum).length) return false;// added to avoid duplication
$(context.parentNode).append('<input type="text" onchange="return myOnChange(this,'+nextNum+')" id="prefix_'+nextNum+'" >');
$('#prefix_'+nextNum)[0].focus();
return false;
}
Update:
The $('#prefix_'+nextNum).focus(); does not get called because focus is a method of the dom object, not jQuery. Fixed it with $('#prefix_'+nextNum)[0].focus();.
The problem is indeed that because of the focus(), the onchange is called again. I don't know if this is a good sollution, but this adding this to the function is a quick sollution:
context.onchange = "";
(The onchange is called again, but is now empty. This is also good because this function should never be called twice. There will be some interface changes in the final product that help with problems that would arise from this (mistakes and all), but in the end this is something I probably would have done anyway).
sollution here: http://jsfiddle.net/k4WKH/2/
As #johnhunter says, the focus does not work in the example, but it does in my complete code. I haven't looked into what's going on there, but that seems to be a separate problem.
maybe this some help to anybody, for any reason, in chrome when you attach an event onchage to a input text, when you press the enterkey, the function in the event, do it twice, i solve this problem chaged the event for onkeypress and evaluate the codes, if i have an enter then do the function, cause i only wait for an enterkey user's, that not works for tab key.
input_txt.onkeypress=function(evt){
evt = evt || window.event;
var charCode = evt.which || evt.keyCode;
if(charCode === 13) evaluate( n_rows );
};
Try this example:
var curNum = 1;
function myOnChange( context )
{
curNum++;
$('<input type="text" onchange="return myOnChange( this )" id="prefix_'+ curNum +'" >').insertAfter( context );
$('#prefix_'+ curNum ).focus();
return false;
}
jsFiddle.

Categories