I'm simply trying to bind the blur event to a set of inputs found on my page.
var $urlTextBoxes = $(`input[type='url'][data-url-prefixer]`);
$urlTextBoxes.on("blur", onUrlTextBoxBlur);
whereas onUrlTextBoxBlur is a simple function checking the current value,
If the <input type="url" data-url-prefixer /> is already visible when prefixing with 'http://' if not already set.$(function () { // ... } is called, the onUrlTextBoxBlur is called on blur.
On the other hand, if the input is hidden on load (inside a div) and shown later, the onUrlTextBoxBlur is never hit and I don't get the point why?
I've tried
$(document).on("blur", $urlTextBoxes, onUrlTextBoxBlur);
which is not working at all.
Putting
if (jQuery._data($("#ExternalRegistrationUrl")[0] !== undefined)) {
console.log($("#ExternalRegistrationUrl")[0]);
console.log(jQuery._data($("#ExternalRegistrationUrl")[0], "events"));
}
shows
input#ExternalRegistrationUrl.form-control
Object {blur: Array[1]}
in master, and
input#ExternalRegistrationUrl.form-control
undefined
in my sub-view. Somehow, the event gots lost. But, how can this be? The Masters onReady is called before the SubViews onReady, or not?
Seems like another plugin is removing the content and re-adding it afterwards. Therefore, all bindings are lost. Now I need a way to re-bind by events after the plugin has done it's magic!
HIDDEN FIELD ALSO WORKING WITH BLUR
FIDDLE
SCRIPT
$(document).ready(function(){
$(":text").hide();
$(":text").blur(function(){
alert("Blurred");
});;
$(":text").show();
});
HTML
<input type="text" />
CSS
input
{
display:none
}
Related
I've been working on trying to trigger an onchange listener with java script in Mozilla Firefox. I've found a lot on Stack Overflow posted about this, but nothing seems to be working for my unique case.
I've created this HTML with a onchange listener from an onchange event using this helpful post (JavaScript OnChange Listener position in HTML markup). Here's my code:
<HTML>
<head>
<script type="text/javascript">
window.onload= function () {
if(window.addEventListener) {
document.getElementsByClassName('search-box')[0].addEventListener('change', loadXMLDoc, false);
} else if (window.attachEvent){
document.getElementsByClassName('search-box')[0].attachEvent("onchange", loadXMLDoc);
}
function loadXMLDoc(){
alert('It worked');
}
}
function addTextCallListener() {
var searchBox = document.getElementsByClassName("search-box")[0];
searchBox.value = "Hello";
}
</script>
</head>
<BODY>
<input type="text" class="search-box" placeholder="Player Search">
<br \>
<button type="button" onclick="addTextCallListener()">Click Me!</button>
</BODY>
</HTML>
I also saved it as this jsfiddle (for some reason I had to keep it all together for it to work, I couldn't break it up into js and html).
https://jsfiddle.net/josephfedor42/crogL0zd/1/
If you play with this jsfiddle you can see that entering text and pressing enter will trigger the listener and the pop up with the message “It worked” will appear.
But if the button “Click Me!” is pressed it only changes the value of the text box, and the onchange listener is not called.
I realize I could easily add an onchange event to this button. But I want to to trigger the listener by programatically/ superficially using javascript in my addTextCallListener() function.
I've tried the simple stuff, like calling
searchBox.onchange();
searchBox.focus();
searchBox.click();
And a combination of these to add and remove the focus. But it doesn't seem to work. I've found quite a few posts on triggering an onchange event, but nothing that works in Firefox.
Any help would be appreciated.
Thanks for that link of a possible duplicated question. I had checked out that link before.
But I gave it a try again. I saved the jsfiddle from them both and neither one work.
My implementation of Dorian's answer
https://jsfiddle.net/josephfedor42/zaakd3dj/
My implementation of Alsciende's answer
https://jsfiddle.net/josephfedor42/xhs6L6u2/
emphasize mine
According to the mdn page about the change event,
The change event is fired for <input>, <select>, and <textarea>
elements when a change to the element's value is committed by the
user.
and to whatwg specs :
When the input and change events apply (which is the case for all
input controls other than buttons and those with the type attribute in
the Hidden state), the events are fired to indicate that the user has
interacted with the control.
Therefore, setting the value of an input is not an action "committed by the user" nor a sign that "the user has interacted with the control", since it was made by the code.
So, even if the specifications for this event are kind of unclear, the event should not fire when you change its value by code.
Something like this should work:
function addTextCallListener() {
var searchBox = document.getElementsByClassName("search-box")[0];
searchBox.value = "Hello";
//fire the event
if (document.createEvent) {
searchBox.dispatchEvent('change');
} else {
searchBox.fireEvent("onchange");
}
}
Here is the code I needed to add to my function addTextCallListener:
var evObj = document.createEvent('HTMLEvents');
evObj.initEvent( 'change', true, true );
searchBox.dispatchEvent(evObj);
I updated the jsfiddle. The working code is here https://jsfiddle.net/josephfedor42/crogL0zd/7/
Replace onchange with change in this part:
document.getElementsByClassName('search-box')[0].attachEvent("onchange", loadXMLDoc);
Right now I have this:
Event.observe(
'hidden',
'keydown',
itemOptions["_something"].showButtonsForThat
);
whereas showButtonsForThat is showButtonsForThat : function(){....function body....}.
But I needed to add other event handlers:
Event.observe(
'inputF',
'keydown',
function() { document.getElementById('hidden').value = document.getElementById('inputF').value; }
);
Event.observe(
'inputF',
'blur',
function() { document.getElementById('hidden').value = document.getElementById('inputF').value; }
);
which will change the value of the hidden field every time I change something in the input field. And now I want the first event handler (about the hidden element) to trigger whenever its value is changed (which changes according to whatever is in the input field..
I tried with eventName 'change' but unsuccessful. Somehow using onchange="myFoo();" in the html element + jQuery, etc., didn't work. Maybe my syntax misplacement mistake, but I tried many things and following different examples.
Clarification: I want to observe the change of hidden, because it will change automatically when I type something different in inputF. So I basically will NOT interact with hidden at all.
If none of the traditional ways worked for you, you could simply use a work-around, as bellow:
Event.observe(
'inputF',
'keyup',
itemOptions["_something"].showButtonsForThat
);
This means that you will still observe the inputF field, but will call your needed function on that. Anyway, you will call the handler on change of hidden, which on the other hand changes along with inputF, meaning that changing either of the fields happens at the same time and for the same purpose.
P.S. Better use keyup event name (as in my example), because keydown requires one more click, for the last symbol to be updated. I.e., if you type asde in inputF, then you will have asd in hidden, unless you click once more with the keyboard. And with keyup you won't have this problem.
var h = document.getElementById('hidden'),
f = function() { h.value = this.value; };
Event.observe('inputF','keydown', f);
Event.observe('inputF','blur', f);
...
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/
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.
There is only one text field on a HTML form. Users input some text, press Enter, submit the form, and the form is reloaded. The main use is barcode reading. I use the following code to set the focus to the text field:
<script language="javascript">
<!--
document.getElementById("#{id}").focus()
//-->
</script>
It works most of the time (if nobody touches the screen/mouse/keyboard).
However, when the user click somewhere outside the field within the browser window (the white empty space), the cursor is gone. One a single field HTML form, how can I prevent the cursor from getting lost? Or, how to re-focus the cursor inside the field after the cursor is lost? thx!
Darin's answer is right, but doesn't work in Firefox. If you want to steal focus back in Firefox too, you have to delay it until after the event:
<input onblur="var that= this; setTimeout(function() { that.focus(); }, 0);">
Or, better, assigned from JavaScript:
<script type="text/javascript">
var element= document.getElementById('foo');
element.focus();
element.onblur= function() {
setTimeout(function() {
element.focus();
}, 0);
};
</script>
But, I would strongly advise you not to do this. Clicking outside a text box to remove focus from that text box is perfectly normal browser behaviour, which can be of legitimate use (eg. to set search point for ctrl-F, or start a drag-selection, etc). There's very unlikely to be a good reason to mess with this expected behaviour.
<input type="text" name="barcode" onblur="this.focus();" />
You can hook the blur event and refocus the field again. There are very few use cases for doing this, but it sounds like yours may be one of them. Note that you'll probably have to schedule the re-focus via setTimeout or similar, you won't be able to do it within the blur handler itself.
When doing this without affecting the markup, this is easiest if you use a library like Prototype, jQuery, Closure, etc., but you can do it without them (of course), you just have to handle browser differences yourself. For instance, using Prototype:
document.observe("dom:loaded", function() {
var elm = $('thingy');
elm.focus();
elm.observe('blur', function() {
refocus.defer(elm);
});
function refocus(elm) {
elm.focus();
}
});
If you don't mind affecting the markup, you can use the onblur attribute. For instance, this works on IE, Firefox, and Chrome at least (probably others):
HTML:
<input type='text' id='thingy' onblur="refocus(this);">
Script:
function refocus(elm) {
setTimeout(go, 0);
function go() {
elm.focus();
}
}