How to undetect/ignore javascript events in a certain html element? - javascript

I have this line of code $('#tbl-purchase-list').on( 'keyup change', 'input[type="text"]' that detects the input of all input[type="text"] field. However, I have an input field that I dont want to be detected when inputting a text on the keyboard or make any changes on it.<input type="text" class="form-control purchase-freight-charge" id="purchase-freight-charge" value="" />. Is there a way in javascript that ignores certain events for a certain element? Something like this $("#purchase-freight-charge").ignoreEvents();? Please help. Thanks a lot.

Ofcourse there is a :not() Pseudo selector:
$('#tbl-purchase-list').on('keyup change',
'input[type="text"]:not(#purchase-freight-charge)',
...);
It will not add the target element in the matched set of selectors. So, there won't be any event for that element which is inside :not().
Event this can also be done:
$('#tbl-purchase-list').on('keyup change', 'input[type="text"]',function(ev){
if(this.id === "purchase-freight-charge"){
this.value = "";
}
});

You can use jQuery's event.stopImmediatePropagation():
$("#purchase-freight-charge").on('keyup change', function( event ) {
event.stopImmediatePropagation();
});
// Future event bindings won't be executed for #purchase-freight-charge
// ...

Related

Why is jQuery select event listener triggering multiple times?

Please run this sample in Google Chrome browser.
Stack Snippet
$(function() {
$(":input").select(function() {
$("div").text("Something was selected").show().fadeOut(1000);
alert("Selected");
});
$("button").click(function() {
$(":input").select();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<button>Click To Select</button>
<input type="text" value="Some text">
<div></div>
Here why jQuery select event listener is triggering multiple times? Does anyone know the reason behind this? And is there any workaround solution for this without using timeout?
The $(":input") selector is selecting the button too, so it causes recursion. Either use just $("input"), or $(":input:not(button)").
I noticed when the three events are fired, the first doesn't have originalEvent property, so we definitely can dismiss it, and the second two has very similar (however not identical) timestamp. You can store the last timestamp in some variable and in event listener compare it with the event's timestamp. If the rounded values of these two are the same, you can dismiss this event.
$(function() {
var lastTimeStamp;
$("input").select(function(event) {
if (!event.originalEvent ||
lastTimeStamp === Math.round(event.timeStamp)) return;
lastTimeStamp = Math.round(event.timeStamp);
$("div").text("Something was selected").show().fadeOut(1000);
alert("Selected");
});
$("button").click(function() {
$("input").select();
});
});
See updated JS Fiddle.
It appears the issue is a combination of:
the :input selector gets the input and the button, hence multiple events triggered.
even when using just input as the selector there is some odd event propagation being triggered on related elements which is raising the select event handler multiple times.
To avoid both of the above, use input as the selector and also use preventDefault() in the event handler. stopPropagation() may also be required, depending on your HTML stucture.
$(function() {
$('input').select(function(e) {
// e.stopPropagation(); // optional
e.preventDefault();
$('#message').text("Something was selected").show().fadeOut(1000);
console.log('Selected');
});
$('button').click(function() {
$('input').select();
});
});
Working example
UPDATE: We were all fooled. The select() function needs a prevent default.
Rory McCrossan figured it out. Well done mate.
Incidentally, I'm not sure what the benefit of select() actually is! Something like focus() or on('focus',) might make more sense. Not Sure what the context is however. The below still follows:
Why waste time using generalised tag/type selectors which may change? Use an ID, and pick out only the one you want.
If you want to detect multiple, use a class. If you want to use multiple, but figure out which one you clicked, use a class and an ID. Bind with the class, and identify using $this.attr('id').
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<button>Click To Select</button>
<input type="text" value="Some text" id="pick-me">
<div></div>
$(function() {
$("#pick-me").select(function(event) {
event.preventDefault();
$("div").text("Something was selected").show().fadeOut(1000);
alert("Selected");
});
$("button").click(function() {
$("#pick-me").select();
});
});

jQuery click event on disabled input field

I want to trigger an event on a disabled input. I have tried the following code, nothing happened - there was no error, the even just didn't fire.
$(document).on('click', '.select-row', function(e){
...
});
How do I fix this?
You can't fire any mouse event like click on a disabled HTML element. Alternative of this, is to wrap up the element in a span or div and perform the click event on those.
$("div").click(function (evt) {
// do something
});​
One more alternate is to make the element readonly instead of disabled, but bear in mind that jQuery does not have a default :readonly selector.
If it works for you, you may use readonly instead of disabled. Then you can use the click event with ease.
Demo
We had today a problem like this, but we didn't wanted to change the HTML. So we used mouseenter event to achieve that
var doThingsOnClick = function() {
// your click function here
};
$(document).on({
'mouseenter': function () {
$(this).removeAttr('disabled').bind('click', doThingsOnClick);
},
'mouseleave': function () {
$(this).unbind('click', doThingsOnClick).attr('disabled', 'disabled');
},
}, '.select-row');
This my solution
<div class="myInput"><input type="text" value="" class="class_input" disabled=""></div>
Jquery:
$("body").on("click", ".myInput", function(e) {
if($(e.target).closest('.class_input').length > 0){
console.log('Input clicked!')
}
});
If you need to trigger, use trigger() function.
$('.select-row').trigger('click');

how to fire event on label text change

I'm trying to fire a function when the label text changes. This is my code
$("#frameItemCode").change(function (e) {
alert("Changed");
});
#frameItemCode is my label id, but the event isn't firing. I have tried examples given before but they hasn't helped me.This is my html
<div class="input-group">
<span class="input-group-addon" #*style="width: 120px;"*#>Item Group</span>
<label class="input-group-addon" #*style="width: 120px;"*# id="frameGroupCode"></label>
<input class="form-control" type="text" id="frameGroupName" style="">
</div>
Take a look at the documentation for the change event. It only fires for specific types of elements:
The change event is fired for <input>, <select>, and <textarea> elements when a change to the element's value is committed by the user...
You won't be able to use the change event for an element that is not one of the previously mentioned types.
If you have some other way of knowing that editing has finished of a specific element, you'll have to fire your own event - possibly using the blur event on the element that was used to change the value. The blur event is triggered when the selected element looses focus such as when a user clicks (or tabs) out of an input element.
For label .change() will not work, So you can try something like this by using trigger() which call our custom event, here fnLabelChanged is my custom event
.change() event worked for <input> , <textarea> ,<select> .i.e
$("button").on('click',function(){
$("#frameGroupCode").text("Hello").trigger("fnLabelChanged");
});
$("#frameGroupCode").on('fnLabelChanged', function(){
console.log('changed');
})
Working Demo
You can get the current text of the label and check if the value is different on keyup or when pressing a button. The change event doesn't work for non form elements.
If you use, $("#frameItemCode").text('abc') to change the lable (as you commented), just call the alert("changed") after that. No need to define an event listener..
$("#frameItemCode").text('abc');
alert("changed");
If the label changes in several ways, define a timeInterval to check if the label has changed,
function inspectLabel(callback){
var label = $("#frameItemCode").text();
setInterval(function(){
var newlabel = $("#frameItemCode").text();
if (newlabel != label){
callback();
label = newlabel;
}
}, 100);
}
inspectLabel(function(){
alert('changed');
});
Depending on which browsers you need to support, you can use MutationObserver:
var observer = new MutationObserver(
function (mutations) {
alert('Label was changed!');
}
);
observer.observe(document.querySelector('#frameGroupCode'), { childList: true });
Example jsFiddle
I don't think label has change() event associated with it, if you want to achive it, then it can be done through JQuery or JS. Because changing label text dynamically is done through Jquery or JS.
Instead, you can create a function and call it when the label is being changed from your function where the lable text change takes place.

.on jquery only working on first element [duplicate]

This question already has answers here:
Events triggered by dynamically generated element are not captured by event handler
(5 answers)
Closed 8 years ago.
I am currently using the following code to tie in an event that limits input into a dynamicly created set of text boxes.
function createSomeTextBoxes() {
//code here to add text boxes
$('.PointerSPSLText').on('keyup', function() { charaterCount( $(this).attr('id'), 30 ) });
$('.SPSLText').on('keyup', function() { charaterCount( $(this).attr('id'), 30 ) });
}
The problem I am having is that these events only get tied to the first element of the class it finds, since there can be more than one of each, that is a problem. I used to use the .live event for this and I could declare it once when the DOM was loaded and jquery took care of the rest. Is there a way to mimic the .live event or what is the best way to achieve the results I need?
For dynamical created element, I think you must use event delegation like:
$("body").on("keyup", ".PointerSPSLText", function() {
charaterCount( $(this).attr('id'), 30 )
});
$("body").on("keyup", ".SPSLText", function() {
charaterCount( $(this).attr('id'), 30 )
});
More info at about on(): http://api.jquery.com/on/
Yeah right live is deprecated now,
You can use dynamic on version like this,
$('#some_static_parent_that_holds_PointerSPSLText').on('keyup','.PointerSPSLText', function(){});
New versions of jQuery use the on event instead of live to bind event handlers to dynamic elements.
function createSomeTextBoxes() {
//code here to add text boxes
$(document).on('keyup', '.PointerSPSLText', function() {
charaterCount( $(this).attr('id'), 30 )
});
$(document).on('keyup','.SPSLText', function() {
charaterCount( $(this).attr('id'), 30 )
});
}
Notice that the event handler is bound to the document instead of a selector for the elements. The selector is specified as the second argument to the on function. When an event is triggered it propagates to the document which then inspects if the target matches the selector supplied as the second argument. You can bind to a static parent instead of the document for better performance.
If you only want to limit the character length, why not use the "maxlength" attribute of the input/textarea element, provided you have access to the function that generates the dynamic elements?
<input type="text" name="usrname" maxlength="30">
<textarea maxlength="30">Enter text here...</textarea>

jQuery: When entering text in input field, doesn't enable the button

I have a jsfiddle here.
jQuery
$(function() {
//var input = $('form :input[type="text"]')
$('form :input[type="text"]').live('keyup', function() {
$('form .create-playlist-button')
.attr('disabled', $('form :input[type="text"]').val().length == 0);
});
});
Needed
When I start entering the data in the textbox, create should be enabled.
When I remove all text from the textbox, create should be disabled.
I am very new to jQuery and this thing is not working for me.
$('form :input[type="text"]').live('keyup', function() {
var val = $.trim(this.value); // this.value is faster than $(this).val()
$('form .create-playlist-button').prop('disabled', val.length == 0);
});
DEMO
Here, I used .prop() instead of .attr(), according to jQuery doc .prop() should be use. I also used .trim() for removing the whitespace from the beginning and end of value.
About your code
In your code you used $('form :input[type="text"]') two times, one for bind event and one to getting the value of text field. But that is not necessary, because within keyup event handler function this will refers to that input element on which keyup event binded.
If you sometime need to use any selector multiple times for any purpose it will be better to cache that in a variable and reuse that variable. Just for example:
var input = $('form :input[type="text"]');
input.on('click', function() {
alert( this.value );
input.addClass('something');
});
If would be better if you use .on() instead of .live() for delegate event handler, because .live() has been deprecated.
You can use .on() like following:
$('form').on('keyup', ':input[type="text"]', function() {
var val = $.trim(this.value);
$('form .create-playlist-button').prop('disabled', val.length == 0);
});
Note
Syntax of .on() for delegate event handling is like:
$(staticContainer).on( eventName, target, handlerFunction )
Here, staticContainer point to an element which belong to DOM at page load, i.e which is not dynamic and also container of target on which you want to bind your event.
Just for some more go here
.prop() vs .attr()
http://forum.jquery.com/topic/whats-the-difference-between-jquery-attr-and-jquery-prop
Updated:
$(function(){
//var input = $('form :input[type="text"]')
$('form :input[type="text"]').live('keyup',function(){
$(this).closest('form').find('.create-playlist-button').prop('disabled',$(this).val().length==0);
});
});
In the "keyup" handler, you use this (or $(this) to use it via jQuery) to get at the text field that's actually involved. I also changed the code to ensure you'll find the correct "companion" button. It looks up the chain of parent elements to find the enclosing <form>, then finds the button inside that form.
The way you're assigning the event handlers is deprecated. It should be:
$('form').on('keyup', ':input[type="text"]', function(){ ...
Also if you checked for "keypress" instead of "keyup" you'd fix the bug wherein the button doesn't work until the second character.
edit — oh and one more thing: you should usually use .prop() to update attributes, not .attr(). It's a confusing thing about the newer jQuery API, but the times you need to use .attr are kind-of rare. Unfortunately, there's a ton of old instructional material out there that was written back before jQuery 1.6 was released.
You should use the .change() method !
And inside it juste do a test:
if ($(this).val().length > 0)
...
else
...
here ya go... using your original fiddle:
http://jsfiddle.net/9kKXX/4/
Only a small change is necessary.
$(function(){
//var input = $('form :input[type="text"]')
$('form :input[type="text"]').live('keyup',function(){
$('form .create-playlist-button').attr('disabled',$(this).val().length==0);
});
});
Fiddle: http://jsfiddle.net/9kKXX/36/

Categories

Resources