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
Related
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>
is it possible to find out from (jquery) change event handler what triggered the change event - keypress of which key or mouse click?
My use case: I have dynamic list of input[type=text] items, if user fills last empty item I add new input[type=text] for another item. I want to auto-focus it if user pressed tab (which triggered the change event), but not for example when user clicked somewhere (so the change is aslo triggered, but user may want to focus something else).
Simplified example:
https://jsfiddle.net/yxu82p1o/1/
<input type=text>
<script>
function addMore() {
$('input').off('change.addMore');
$('<input type=text>').insertAfter($('input').last()).on('change.addMore', addMore);
}
$('input').on('change.addMore', addMore);
</script>
PS. I can figure out workarounds like attaching another keyup event and figuring out pressed key from it, but it would be much simpler and cleaner to find out from change event what caused it.
This might be an option. Listen for the keydown event on the input elements and if the TAB key triggered the event and the element is an input element trigger the change event on the input element. Then focus the dynamically added input element.
function addMore() {
$('input').off('change.addMore');
$('<input type=text>').insertAfter($('input').last()).on('change.addMore', addMore);
}
$('input').on('change.addMore', addMore);
$('body').on('keydown', 'input', function(e){
var keyCode = e.keyCode || e.which;
if (keyCode == 9 && this.tagName === "INPUT") {
e.preventDefault();
$(this).change();
$(':text').last().focus();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<input type=text>
I want to replace a button with an input field, where the user enters something and presses the enter button. After that, the button from the beginning should appear again. My script works so far but I can't repeat this once it finished.
Update: The button should also appear again, if the input field is shown but the user don't want to enter anything and clicks somewhere else.
The code:
<button id="createButton">Create item</button>
/*
jquery stuff
*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('#createButton').click(function( event ) {
$(this).replaceWith('<input type="text" id="buttonInput" placeholder="e.g. books, movies" autofocus>');
});
$(this).on('keypress', function (event) {
if(event.which == '13'){ // If enter button is pressed
alert('You entered something');
$('#buttonInput').replaceWith('<button id="createButton">Create item</button>');
}
});
});
</script>
Update 2: I updated the code with hide() and show() to get the same result. But how can I let the input disappear, if the user clicks somewhere inside the body, without redundancy?
The new code:
<button id="createButton">Create item</button>
<input type="text" id="input" placeholder="e.g. books, movies" autofocus>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
$('#input').hide();
$(document).on('click', '#createButton', function (event) {
$(this).hide();
$('#input').show().focus();
});
$('#input').on('keypress', function (event) {
if (event.which == '13') { // if enter button is pressed
$(this).hide().val('');
$('#createButton').show();
}
});
});
</script>
As the other answers say, you're replacing the element (createButton), which means the click handler is no longer bound.
You can either re-bind, or bind to the parent element, with the #createButton selector using on.
$(document).on('click','#createButton', function( event ) {
...
});
Don't actually use document - use whatever the parent element is, which doesn't get replace (a div, perhaps?)
Replacing DOM elements is a bad approach though -- you'd be better off leaving the elements on the page, and using show and hide.
http://jsfiddle.net/v03j8bns/
Updated Answer
Here's a fiddle showing the show/hide/ approach. To handle:
The button should also appear again, if the input field is shown but the user don't want to enter anything and clicks somewhere else.
When the button is clicked, I call focus() on the textbox. I've also hooked up a blur() event handler, so if the user clicks/tabs out, then it'll hide the textbox and show the button.
You have to bind the click event to newly created button again:
$(document).ready(function () {
$('#createButton').click(function (event) {
$(this).replaceWith('<input type="text" id="buttonInput" placeholder="e.g. books, movies" autofocus>');
});
$(this).on('keypress', function (event) {
if (event.which == '13') { // If enter button pressed
//Disable textbox to prevent multiple submit
alert('You entered something');
$('#buttonInput').replaceWith('<button id="createButton">Create item</button>');
}
$('#createButton').bind('click', function (event) {
$(this).replaceWith('<input type="text" id="buttonInput" placeholder="e.g. books, movies" autofocus>');
});
});
});
You have this issue because you replace DOM elements. It means that your new element button no longer has click handler.
I would recommend you to use something like show/hide or use jQuery delegate on/bind for handling click.
When you're changing DOM on the fly and want to automatically assign listeners to elements that may or may not exist at certain points of time, you need to use delegated event listeners.
$(document).on('click', '#createButton', function () { ... });
$(document).on('click', '#buttonInput', function () { ... });
These handlers will work however you scramble the DOM.
I am having a file upload form where I am checking the file size through javascript before finally submitting the form. The form is working fine and when I try to upload a file more than the mentioned size then it shows the correct alert at the first time. But if I again click on upload without selecting another file I get the same alert twice. If I again repeat the process I get the alert 3 times. Below is the code
<script>
var flag=0;
$('#filename').bind('change', function() {
var filesiz = this.files[0].size;
if (filesiz >10485760)
{flag=1;}
else
{flag=0;}
});
function upfunc(){
$('#smalldata').hide();
$('#invalidfile').hide();
$('#invalidfile9').hide();
if($( "#UserComments" ).hasClass( "textAreaField valid" ) && $( "#filename" ).hasClass( "valid" )){
$('#loading_image').show(); // show animation
$( "#uploadsfrm" ).submit(function() {
if(flag==1)
{alert ('File size cannot exceed 10 MB.');
$('#loading_image').hide();
return false;
//event.preventDefault();
}
else
return true;
});
}
}
</script>
I think the error may be because I am using bind. Any help would be really appreciated.Thank you
You have a multi event calling in here.
Every time you call upfunc() you attach a Submit event.
you might consider either declaring Submit event once or use $( "#uploadsfrm" ).unbind('submit') before the
$( "#uploadsfrm" ).submit(function()....
so in fact, first call you will have 1 event listener, 2nd call you will attach another event, which now sums up to 2..there until infinite.
e.preventProgration or StopDefault wont help because its the same object and therefor it wont stop the calling of the events.
Even if it will help, it is just a piece of bad code :(
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
}
});