Let us assume that I have many textarea elements on my page, and my goal is to log the value of current textarea element that I am typing on.
I have managed to write the code that does just that, but the problem is that when type text in one textarea, and then switch to another and type in that for a while, when I come back to the first one, I get two .keyup() methods attached to that element. So I get two logs of that textarea value.
$( "body" ).click( function( event ) {
let element = event.target
if( element.nodeName === "TEXTAREA" ){
if($(element).focus()){
$(element).keyup(function(){
console.log(element.value)
})
}else {
$(element).unbind( 'keyup' )
}
}
});
What do I need to do to remove that method stacking?
You should never attach event inside another event because when the first fired the one inside will be attached another time and so on.
I suggest attaching the input event directly to the textarea's instead of keyup and nested events, so with the helps of this keyword you will get the current changed textarea element, like :
$("textarea").on('input', function(event) {
console.log($(this).val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea></textarea>
<br>
<textarea></textarea>
<br>
<textarea></textarea>
Related
I have an input tag
<input type="text" name="cOperator" class="form-control scale-input operator" placeholder="Enter your ID" autocomplete="off" onkeyup="ajax_showOptions(this,'getEmp',event)" required>
So when I start typing in, it shows employee list. And I have a jQuery function that handles click event.
$( document ).on( "click",".optionDivSelected, .optionDiv", function() {
if($('.operator').val().length > 0){
$('.operator-li').next().addClass('active');
$( '.operator-li' ).find('span').addClass('hidden');
$('.operator-value').show();
$('.operator-value h1 span').html($('.operator').val());
$('.operator').parents('label').hide().parents('.fieldset').next().fadeIn();
}
});
function checks the value of input, hides an input, shows selected value in a div and brings to next step automatically(I don't have a next button).
This part works perfect.
Problem is: User can just navigate with tab, choose with down or up arrows and select with Enter keypress. I have a selected value in input but it doesn't bring me to next step because Click event wasn't fired. I tried to do something like below:
$( document ).on( "click, keypress",".optionDivSelected, .optionDiv", function() {console.log('someone used keyboard')});
but no luck. (I don't know if it's even possible to have multiple event handler)
How do I detect if user inserted value using Enter keypress and do my staff after.
it also creates me a problem when I validate input onchange. input wants to be typed not just inserted via click or enter keypress.
Please help me with this.
I can't show whole code. because it has a lot of backend staff mixed.
I'll include steps I am trying to achieve.
I start typing and I see a list:
I click one of option and I move to next step:
But when I select by hitting ENTER(or return) I just see input tag with selected option, no div with selected operator no next step. Just like below:
Update:
Below is my workaround and is not a question:
in combination of Aswin Ramesh's comment, alpeshandya and Vikash Mishra's answer I came up with this code and it does what I was expecting. and Most alpeshandya's answer helped me. Thank you guys.
And BTW If you see that I am somehow spagettiing the code, PLS let me know.:-)
var ajaxHandler = function(){
// $( document ).on( "click",".optionDivSelected, .optionDiv", function() {
if($('.operator').val().length > 0){
$('.operator-li').next().addClass('active');
$( '.operator-li' ).find('span').addClass('hidden');
$('.operator-value').show();
$('.operator-value h1 span').html($('.operator').val());
$('.operator').parents('label').hide().parents('.fieldset').next().fadeIn();
}
// });
console.log('ajaxhandler')
};
$( document ).on( "click",".optionDivSelected, .optionDiv", ajaxHandler)
$('.operator').on('keyup', function(event) {
if(event.which == 13) {
console.log("enter");
event.preventDefault();
ajaxHandler();
}
});
You will need to create a generic event handler function which can be used as handler for click as well as for key press. This should work for your usecase:
var eventHandler=function(){
if($('.operator').val().length > 0){
$('.operator-li').next().addClass('active');
$( '.operator-li' ).find('span').addClass('hidden');
$('.operator-value').show();
$('.operator-value h1 span').html($('.operator').val());
$('.operator').parents('label').hide().parents('.fieldset').next().fadeIn();
}
}
$( document ).on( "click",".optionDivSelected, .optionDiv", eventHandler)
$( document ).on( "keypress",".optionDivSelected, .optionDiv", function(event){
if(event.which == 13) {
eventHandler();
}
})
Here is plunker for demo:
demo
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/
I have the following html code:
<input type="text" id="theInput" value=""/>
Click me
I want to detect when the input changes and perform an operation in this case, but ONLY when the user has not clicked in the link. I have tried this:
$('#theLink').live('click', function(){
alert('click');
});
$('#theInput').live('change', function(){
alert('change');
});
However change is always executed before click when the value in the input changed, due to Javascript event precedence rules, and therefore only "change" message is displayed.
I would like it to display change only if the input value changed and the user exited the input clicking in any other place instead of the link. In that last case I would like to display click.
The example is here.
I use jQuery 1.6.4.
As far as I know, the click event fires after the blur and change events in every browser (have a look at this JSFiddle). The order of blur and change is different across browsers (source: Nicholas Zakas).
To solve your problem, you could listen to click events on the document and compare the event's target with #theLink. Any click event will bubble up to the document (unless it is prevented).
Try this:
var lastValue = '';
$(document).click(function(event) {
var newValue = $('#theInput').val();
if ($(event.target).is('#theLink')) {
// The link was clicked
} else if (newValue !== lastValue) {
// Something else was clicked & input has changed
} else {
// Something else was clicked but input didn't change
}
lastValue = newValue;
});
JSFiddle: http://jsfiddle.net/PPvG/TTwEG/
Both events will fire but in your example the alert in the onchange event handler fired when the onmousedown event occurs will stop the onmouseup event required for the onclick event to fire. Using console.log will show both events firing.
http://jsfiddle.net/hTqNr/4/
Ok, now i got it, you could do
$('#theLink').live('click', function(e){
alert('click');
});
$('#theInput').live('change', function(e){
//Check if the change events is triggerede by the link
if(e.originalEvent.explicitOriginalTarget.data === "Click me"){
//if this is the case trigger the click event of the link
$('#theLink').trigger("click");
}else{
//otherwise do what you would do in the change handler
alert('change');
}
});
Fiddle here http://jsfiddle.net/hTqNr/19/
why you dont pick the value of input box. you have to store initial value of input box on ready function
initialvalue= $('#theInput').val();
then compare the value
$('#theLink').live('click', function(){
var newvalue =$('#theInput').val();
if(newvalue!=initialvalue) {
//do something
}
});
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.