jQuery late binding of Ajax elements doesn't work - javascript

I'm really stuck with a jQuery issue and I hope someone can help me out...
So I have a list of options on the left, and when you click on one, a form is generated via Ajax on the right. There's this element in the form:
<input type="text" class="value" value="something">
And what I want to do is to call
$(".value").tagsInput();
which is a jQuery plugin that works pretty much like Stack Overflow's 'Tags' input field when you ask a question.
So I tried this:
$(document).ready(function() {
$(".value").on("load", function () {
console.log("Tags Input");
$(".value").tagsInput();
});
});
and nothing is printed out. I've also tried this:
$(document).on("change", ".value", function () {
console.log("Tags Input");
$(".value").tagsInput();
});
and it doesn't work either. I'm wondering where I did wrong. Can anyone help me out?

As pointed out by Shabnam, the "change" event is not what you want, as it is fired only once the field is blurred.
Anyways, from the plugin documentation, it looks like you don't have to call that function every time a key is pressed, but it attaches its own event handlers autonomously.
So, probably you should be fine with just:
$(document).ready(function() {
$(".value").tagsInput();
});
Your .on handler will never work, as the load event is fired only by document when the page is ready.
If you want to debug things a bit, have a look at the supported callbacks, such as onChange.
SIDE NOTE
I don't like how that plugin is written, as it clogs the "global" jQuery.fn namespace with lots of functions, while jQuery documentation recommends not doing so (see: Namespacing).
UPDATE
See here: http://jsfiddle.net/aFPHL/ an example of this working (the .load() was monkeypatched to avoid having to call an actual URL, but its behavior is pretty much the same as the real one).

"change" event gets fired when the input element loses focus. If you want ajax call at the end of each key input, try using keyboard events

Related

Strange behaviour using .on() for click event - Fired twice

I already checked answers about click events fired twice. But I have a question about using .on().
Usually, I use it like this on dynamically added elements, and it always worked fine:
$(document).on("click", "dynElement", function(){})
In the current website I'm working on, I use it several times. But in the function that I'm trying to achieve, let's say, a dynamic "jump to page", click on page number is triggered twice:
$(document).on("click", ".jumpTo .number", function(){
console.log("Jump");
});
Trying to find the origin of this behaviour, I tried this syntax that works fine:
$(".jumpTo").on("click", ".number", function(){
console.log("Jump");
});
Can anyone explain what is the difference between these two different syntaxes (which look quite similar to me)?
And optionally, why is $(document).on("click", ".jumpTo .number", function(){}) triggered twice? (Optionally because I am not able to reproduce this behaviour in a Fiddle, everything works as it is supposed to).
$(document).on("click", ".jumpTo .number", function(){
console.log("Jump");
});
In this case the click handler is set on the document object. So whenever you click somewhere on the page, it will fire and look for a ".jumpTo .number" element inside it. If it finds it, it will check if the click was on it and your function will execute.
$(".jumpTo").on("click", ".number", function(){
console.log("Jump");
});
Here the click handler will be on .jumpTo
As Al.G said probably this code gets executed multiple times, so you actually add that handler multiple times, hence the double firing.
One way to solve it is to do something like this:
$(".jumpTo").unbind("click").on("click"...
Another is to change your code to make sure the .on() call doesn't get executed twice.

Using jQuery .on() for all events

Is it considered bad practice to use jQuery's .on() event handler for every event?
Previously, my code contained script like this:
$('#cartButton').click(function(){
openCart();
});
However I've recently started using InstantClick (a pjax jQuery plugin).
Now none of my scripts work. I understand why this is happening, but I cannot wrap my code with the InstantClick.on('change', function(){ tag as this means my code starts to repeat itself. For example, clicking on the cart button will run the openCart() function many times. So to get around this, I'm changing all my functions to something like this:
$(document).on('click', '#cartButton', function(){
openCart();
});
I'm curious as to whether this will increase loading times and cause excess strain. Is it bad practice to use the on() event handler for every event in my code?
It's not bad practice at all..
.on is the preferred method for handling all events, and using .click is just a shortcut that gets passed to the .on method anyway..
If you check out here (unminified source for jquery 2.1.0): https://code.jquery.com/jquery-2.1.0.js
Here are a couple notes:
search for this line: on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
This is the function definition for the on method and just shows you what the code is doing..
also search for this line: jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick "
Th code below this line is mapping all the directly callable shortcuts (like click) and shows you that they are just mapping to the 'on' method.
Hope this helps!!!
No it is not a bad practice to use .on(), actually if you check the source of the .click() function, you'll see that it actually calls .on().
But... Instead of creating an anonymous function, you should simply do this, which would be cleaner, and slightly faster:
$(document).on('click', '#cartButton', openCart);
and
$('#cartButton').click(openCart);

Catch changes in dynamicly updated tables

I have a page that loads tables dynamically. I want to check if any of the tds contain a keyword, and depending on that change some CSS styling.
On first load everything works well, but when something changes in the table, my function doesn't get triggered.
Here is my code. The 1st block works well, but the 2nd doesn't?
$( document ).ready(function() {
$("tr td:contains('*')").each(function(){
$(this).parent("tr").css({ "background-color": "red" });
$(this).parent().children().css({ "background": "inherit" });
});
});
jQuery('body').on('change', '.content', function () {
$("tr td:contains('*')").each(function(){
$(this).parent("tr").css({ "background-color": "red" });
$(this).parent().children().css({ "background": "inherit" });
});
});
If I understand correctly, you're attempting to listen for changes in the table itself, meaning inner html changes, added rows, etc.
Unfortunately, the reason you're not seeing the change event firing is because that event only fires when the value of the element is changed; there is no such property for tables, rows and cells.
From jQuery's documentation on the change event, found here:
This event is limited to elements, boxes and
elements. For select boxes, checkboxes, and radio buttons,
the event is fired immediately when the user makes a selection with
the mouse, but for the other element types the event is deferred until
the element loses focus.
The reason why it works the first time is because, of course, you're not wrapping it in the change event; it is firing immediately when your on-ready function fires. Your selector works fine, of course, the table is simply never firing the event you're looking for.
I've not personally done this myself, but one solution found on SO can be seen here, which involves setting up a type of poller which constantly checks whether anything has changed. It also explains how you can then set up a custom event, which you can fire, thus further separating your code into manageable pieces.
Apparently they also discuss using jqGrid, which has a refresh event you may want to consider as well.
Hope that helps.
Edit
You might also be able to make use of the MutationObserver, whose documentation can be found here, and what looks like a pretty good example of its use on SO here. In the SO example, the poster indicates they tested it on browsers as far back as IE 7, however according to this, MutationObserver is not 100% compatible by itself (maybe he uses a polyfill), so make sure you test it properly.
Wrap the on change function with document.ready
$(function(){
/*code*/
});
Thanks everybody for your help, i found solution using custom build plugin that i found here:
jQuery watch div
It works like a charm for me!

Event handlers not working correctly in jsfiddle

Trying to make a jsfiddle so I can post it on here and get some help with a problem; however, I'm having a problem getting jsfiddle to act as expected, so I'm having a problem trying to document my problem!
http://jsfiddle.net/eidsonator/he4Vc/#base
I'm trying to add a blur event handler to a input with id of "part". My alert fires as soon as the page loads (which it shouldn't) and doesn't fire when focus is lost. This behavior persists in chrome and in firefox (I'm coding for an internal web app, so I can ignore ie!)
$("#part").on('blur', alert('lost focus'));
I've changed the load method, and tried wrapping it in my own $(document).ready(function() {}); as well as using .blur() and different versions of javacript... any clues?
Thanks!
You are calling alert straight away, and passing the return value of it to the .on() method. Instead, you need to pass a reference to a function that can be invoked when the event is received:
$("#part").on('blur', function () {
alert('lost focus')
});
Here's an updated fiddle.
you have written a wrong syntax .see the docs for more info,and change your code to
$("#part").on('blur', function(){
//do something
});

onChange event not firing on a textbox in Chrome

I have the following code to bind some validation logic to be fired when a user updates the value of a textbox. I expect that the //Do some stuff here code will execute when any of the textboxes it is bound to lose focus.
function RegisterHoursValidationHandlers() {
$('.topic-frame-body input[type=text]').live('change', function () {
//Do some stuff here
});
}
This works exactly as I expect in IE, Firefox and Safari. However, the event never fires in Chrome and I have no idea why.
UPDATE: I was able to get the desired effect by changing 'change' to 'blur'. Though this still doesn't explain why it doesn't worh with 'change'.
There's no known quirk about chrome. (the change event is supported across all browsers)
Example with live showing it working against dynamic content.
Test it here:
There is a piece of information or an assumption being made here that makes this unsolvable.
UPDATE: If it works when you change it to blur, it is possible that you are overwriting the previous event or function. By changing it to blur, whatever is overwriting it no longer will because it is a a different event.
This would also explain why you are not seeing any errors. (keep in mind, I believe that jQuery will chain events bound to the same elements, but live() is a bit of a special case - but that fact might point to it being the function, not the event binding)
Try using .delegate() instead http://api.jquery.com/delegate/
I've tried you code in both FF and Chrome - http://jsfiddle.net/B3aRy/ - It worked in both. So maybe its an issue elsewhere in your code?
What version of Jquery are you using?
I can't see the issue myself, but .live does not support the "change" event until jquery 1.4+
Try:
function RegisterHoursValidationHandlers() {
$(".topic-frame-body input[type='text']").live('change', function () {
//Do some stuff here
});
}
With the quotes around 'text' as I have it. Worth a shot.
Or try:
$(".topic-frame-body input:text").live();
The point being, I think the problem is in the details of how you're targeting the input field, rather than in the method.

Categories