Firefox onchange not calling function - javascript

I have a form that contains input:
<input onchange="checkDomain(true); return false;" type="text" id="dsearch" value="" name="domain" maxlength="30"/>
Which works just fine in Opera, Chrome and IE - but Firefox and Safari are having problems with calling the function checkDomain(). I added a line into the function for debugging:
function checkDomain(check)
{
console.log('checkDomain() called!');
// do rest of the stuff...
}
So, Chrome/Opera/IE calls the function with no problem after you enter text and click somewhere else - but Firefox/Safari doesn't. Anyone have a clue?

I cannot remember where I read it, but you should use .keydown()/.keyup()/.keypress() (whatever suits your needs) instead of onchange. At least for input[type=text].
you can use .blur() and .focus for their respective purposes too.
Seeing this in your question: "after you enter text and click somewhere else", makes me conclude you need the .blur() function.
$("input[type=text]").blur(function(){
console.log('checkDomain() called!')
});

maybe onblur is best for this:
<input onblur="checkDomain(true); return false;" type="text" id="dsearch" value="" name="domain" maxlength="30"/>

This problem happens when you change the behavior of your input keypress and key down.
You need to manually call the onchange trigger to fire it.
As an example consider you have a jQuery function for your inputs which do some stuff when user clicks on keyboard.
You need to call input.trigger("onchange"); to make sure the onchange is fired after keypress and keydown
/**
* Keyboard Manager
*/
(function($) {
$.fn.inputManager = function(options) {
};
options = $.extend(defaults, options);
// The key down event only use to manage key board language changes
var keyDown = function(e) {
//Do something
};
var keyPress = function(e) {
//Do something
};
return this.each(function() {
var input = $(this);
//The Firefox dose not trigger the input onchange when you change keypress and key down
//functions. So manually call it!
input.keypress(function(e) {
keyPress(e);
input.trigger("onchange");
});
input.keydown(function(e) {
keyDown(e);
input.trigger("onchange");
});
});
};
})(jQuery);

Related

How to call a function when default browser autocomplete list item selected [duplicate]

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.

onclick event not firing after onchange event

Does anyone know how to make a simple JavaScript onclick event fire if the process of clicking the element causes an onchange event to fire elsewhere on the page? I've created a very simple page to demonstrate this problem:
<html>
<body>
<input type="text" name="test" id="test1" onchange="return change(event);" />
Bang
Boom
<script type="text/javascript">
function change(event) {
alert("Change");
return true;
}
function bang() {
alert("Bang!");
return true;
}
function boom() {
alert("Boom!");
return true;
}
</script>
</body>
</html>
If you click the bang link you get the Bang! alert. Boom gives you the Boom alert. And if you enter text in the text field and tab out you get the Change alert. All well and good.
However, if you enter text in the text field and, without tabbing or clicking anything else first, click either Bang or Boom you get the Change alert and nothing else. I would expect to see the Change alert followed by either Bang or Boom.
What's going on here? My change event returns true. How can I ensure that my click event is fired?
Okay... So it seems like it's time for a bit of an explanation.
Explanation
You encounter this error because the onchange event is triggered as soon as focus is moved away from the element. In your example the action that takes focuse away from the input element is the mousedown event which triggers as you click down on the mouse. This means that when you mousedown on the link it fires off the onchange function and pops up the alert.
The onclick event on the other hand is triggered on the mouseup event (i.e. when you release the pressure on the mouse - prove this to yourself by click, hold/pause, release on a onlcick event). Back to your situation... Before the mouseup (i.e. onclick) happens the focus is moved to the alert triggered from your onchange function.
Fix
There are a couple of options to fix this. Most simple change from using onclick="...." to onmousedown="....".
Alternatively, you could use setTimeout like,:
function change() {
setTimeout(function (){
alert("Change event")
}, 100)
}
I suggest the onmousedown method as preferred. The setTimeout method will fail if you click and hold on the link for more than the prescribed amount on the timeout.
The problem is that the alert() function grabs the event chain somehow, test this:
<html>
<body>
<input type="text" name="test" id="test1" onchange="return change(event);" />
Bang Boom
<script type="text/javascript">
function change(event) {
console.log("change");
return true;
}
function bang() {
console.log("bang");
return true;
}
function boom() {
console.log("boom");
return true;
}
</script>
</body>
As you'll see you'll get the expected behaviour in the console.
JSBin
Rather than try and replicate your problem, I just created the solution in jsFiddle.
I seperated your HTML and your JavaScript.
HTML
<input type="text" name="test1" id="test1" />
Bang
Boom
JavaScript
var test1 = document.getElementById("test1");
var test2 = document.getElementById("test2");
var test3 = document.getElementById("test3");
test1.onchange = function (event) {
alert("Change");
};
test2.onclick = function () {
alert("Bang!");
};
test3.onclick = function () {
alert("Boom!");
};
After making a change in the text box and click out side of it will trigger the onchange event, and the onclick events will still fire. If you are expecting the change alert to fire for each key stroke change onchange to onkeyup.

Javascript change event on input element fires on only losing focus

I have an input element and I want to keep checking the length of the contents and whenever the length becomes equal to a particular size, I want to enable the submit button, but I am facing a problem with the onchange event of Javascript as the event fires only when the input element goes out of scope and not when the contents change.
<input type="text" id="name" onchange="checkLength(this.value)" />
----onchange does not fire on changing contents of name, but only fires when name goes out of focus.
Is there something I can do to make this event work on content change? or some other event I can use for this?
I found a workaround by using the onkeyup function, but that does not fire when we select some content from the auto completer of the browser.
I want something which can work when the content of the field change whether by keyboard or by mouse... any ideas?
(function () {
var oldVal;
$('#name').on('change textInput input', function () {
var val = this.value;
if (val !== oldVal) {
oldVal = val;
checkLength(val);
}
});
}());
This will catch change, keystrokes, paste, textInput, input (when available). And not fire more than necessary.
http://jsfiddle.net/katspaugh/xqeDj/
References:
textInput — a W3C DOM Level 3 event type. http://www.w3.org/TR/DOM-Level-3-Events/#events-textevents
A user agent must dispatch this event when one or more characters have
been entered. These characters may originate from a variety of
sources, e.g., characters resulting from a key being pressed or
released on a keyboard device, from the processing of an input method
editor, or resulting from a voice command. Where a “paste” operation
generates a simple sequence of characters, i.e., a text passage
without any structure or style information, this event type should be
generated as well.
input — an HTML5 event type.
Fired at controls when the user changes the value
Firefox, Chrome, IE9 and other modern browsers support it.
This event occurs immediately after modification, unlike the onchange event, which occurs when the element loses focus.
It took me 30 minutes to find it, but this is working in June 2019.
<input type="text" id="myInput" oninput="myFunction()">
and if you want to add an event listener programmatically in js
inputElement.addEventListener("input", event => {})
As an extention to katspaugh's answer, here's a way to do it for multiple elements using a css class.
$('.myclass').each(function(){
$(this).attr('oldval',$(this).val());
});
$('.myclass').on('change keypress paste focus textInput input',function(){
var val = $(this).val();
if(val != $(this).attr('oldval') ){
$(this).attr('oldval',val);
checkLength($(this).val());
}
});
Do it the jQuery way:
<input type="text" id="name" name="name"/>
$('#name').keyup(function() {
alert('Content length has changed to: '+$(this).val().length);
});
You can use onkeyup
<input id="name" onkeyup="checkLength(this.value)" />
You would have to use a combination of onkeyup and onclick (or onmouseup) if you want to catch every possibility.
<input id="name" onkeyup="checkLength(this.value)" onmouseup="checkLength(this.value)" />
Here is another solution I develop for the same problem. However I use many input boxes so I keep old value as an user-defined attribute of the elements itself: "data-value". Using jQuery it is so easy to manage.
$(document).delegate('.filterBox', 'keyup', { self: this }, function (e) {
var self = e.data.self;
if (e.keyCode == 13) {
e.preventDefault();
$(this).attr('data-value', $(this).val());
self.filterBy(this, true)
}
else if (e.keyCode == 27) {
$(this).val('');
$(this).attr('data-value', '');
self.filterBy(this, true)
}
else {
if ($(this).attr('data-value') != $(this).val()) {
$(this).attr('data-value', $(this).val());
self.filterBy(this);
}
}
});
here is, I used 5-6 input boxes have class 'filterBox',
I make filterBy method run only if data-value is different than its own value.

Javascript Events: How to trigger event when ALT+NUM character is entered

I first used the onKeyUp event to detect input changes in a textbox. However, when the user enters in a French character using ALT+Num, the event doesn't detect the change until i enter the next character...
Which event should I be using to detect the special character changes. I've tried onChange but does not seem to be working.
I've tried using onkeypress event because I notice that it triggers it after i release the ALT key, however even though once the ALT is release, the onkeypress is triggered and you see the accented character, but when I use this.value for the inputbox, it only registers up to and before the new ALT+Num character is input.
for example: i entered vidé, but the search would not dynamically find vidé, but only vid because the é has not been saved in the - this.value yet, until another key event is triggered.
Hence I was wondering if there's way to simulate/send a key press to trigger it.
FINALLY FIGURED IT OUT!! :D
here's the code, however the String converting event.which code does not work on the jsFiddle though, nonetheless the code works :)
$('#i').keydown(function() {
document.getElementById('j').value = "down";
$('#k').val($('#i').val())
});
$('#i').keyup(function() {
document.getElementById('j').value = "up";
$('#k').val($('#i').val())
});
$('#i').keypress(function(event) {
$('#k').val(String.fromCharCode(event.keycode));
});
$('#i').change(function() {
document.getElementById('j').value = "change";
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="i" type="text" /><br />
<input id="j" type="text" />
<input id="k" type="text" />
View on JSFiddle
use keyup. The new character will not be added until the user releases the ALT key and at that point the keyup event will fire.
There's a reference at http://unixpapa.com/js/key.html which might be a good idea to have a look at, and according to section 2.1, ALT should generate a keydown and keyup in modern browsers..
I would suggest you use jQuery or a similar library to ease the issues you're facing cross-browser. Have a look at http://jsfiddle.net/qvDbu/1/ for a proof of concept which works fine.
Keypress is not triggered by only modifier-presses, so that's probably the way to go, it allows you to pick up the character entered as well, rather then which key is pressed. Edit: Seems to not be the case in Fx that keypress is triggered by modifiers, but I'm not able to reproduce actually loosing any characters.
The character entered with the ALT+NUM combination will only be added to the input element's value after the keyup event triggers, so you won't be able to read it in that event handler.
In order to solve this problem you could set a timeout on the ALT keyup event before reading the input element's value:
$('input').on('keyup', function (e) {
var _this = this;
var ALT_KEY_CODE = 18;
if (e.which == ALT_KEY_CODE) {
setTimeout(function () {
handleKeyup.call(_this , e);
}, 1);
} else {
handleKeyup.call(_this , e);
}
});
function handleKeyup (e) {
// $(this).val() now holds the ALT+NUM char
}
You need to bind onkeypress, which won't fire until you finish entering the alt code.
document.getElementById('input').onkeypress = function() {
alert('fired');
}
<input id='input' type='text' />
View on JSFiddle

How do I grab the value from an html form input box as its being entered?

How do I grab the value from an input box as its being entered?
onkeyup will be triggered every time a key is released. While it looks to be the solution it has some problems.
If the user move the cursor with the arrows, it is triggered and you have to check yourself if the field value didn't change.
If the user copy/paste a value in the input field with the mouse, or click undo/redo in the browser, onkeyup is not triggered.
Like in a mac or in google docs, I didn't want a save button to submit forms in our app, here is how I do it.
Any comment, or shortcut is welcome as it is a bit heavy.
onfocus, store the current value of the field, and start an interval to check for changes
when the user moves something in the input, there is a comparison with the old value, if different a save is triggered
onblur, when the user moves away from the field, clear the interval and event handlers
Here is the function I use, elm is the input field reference and after is a callback function called when the value is changed:
<html>
<head>
<title>so</title>
</head>
<body>
<input type="text" onfocus="changeField(this, fldChanged);">
<script>
function changeField(elm, after){
var old, to, val,
chk = function(){
val = elm.value;
if(!old && val === elm.defaultValue){
old = val;
}else if(old !== val){
old = val;
after(elm);
}
};
chk();
to = setInterval(chk, 400);
elm.onblur = function(){
to && clearInterval(to);
elm.onblur = null;
};
};
function fldChanged(elm){
console.log('changed to:' + elm.value);
}
</script>
</body>
</html>
use an onchange event handler for the input box.
http://www.htmlcodetutorial.com/forms/_INPUT_onChange.html
I noticed you used the "jquery" tag. For jQuery, you can use the .keypress() method.
From the API documentation:
Description: Bind an event handler to the "keypress" JavaScript
event, or trigger that event on an
element.
The event will fire every time keyboard input is registered by the browser.
.keydown() and .keyup() are also available. Their behavior is slightly different from .keypress() and is outlined by the API documentation as well.
The nice thing about jQuery is that you can use the same code across Firefox, IE, Safari, Opera and Chrome.

Categories

Resources