jQuery live help - ajax

I have the following script which works perfectly until I regenerate the links ".resultLink" via jquery ajax:
$("a.resultLink").live('click', function()
{
var that = this;
$.ajax({
url: 'most_used.aspx',
type: 'POST',
data: { strMostUsedID:$(that).attr("href") },
error: function() { },
success: function() { }
});
});
"live" normally fixes this for me but this time it did not. Not sure what I am doing wrong.

The most likely cause I can think of is the selector not matching, double check that the .resultLink class is being applied to the new links...if it's not the .live() handler won't match the selector.

Related

Kendo Datasource Transport custom function not getting called

Im experiencing a rather annoying bug (?) in Kendo UI Datasource.
My Update method on my transport is not getting called when I pass a custom function, but it does work if I just give it the URL.
This works:
...
transport: {
update: { url: "/My/Action" }
}
...
This does not
...
transport: {
update: function(options) {
var params = JSON.stringify({
pageId: pageId,
pageItem: options.data
});
alert("Update");
$.ajax({
url: "/My/Action",
data:params,
success:function(result) {
options.success($.isArray(result) ? result : [result]);
}
});
}
}
...
The function is not getting invoked, but an ajax request is made to the current page URL, and the model data is being posted, which is rather odd. Sounds like a bug to me.
The only reason I have a need for this, is because Kendo can't figure out that my update action returns only a single element, and not an array - so, since I dont want to bend my API just to satisfy Kendo, I though I'd do it the other way around.
Have anyone experienced this, and can point me in the right direction?
I also tried using the schema.parse, but that didn't get invoked when the Update method was being called.
I use myDs.sync() to sync my datasource.
Works as expected with the demo from the documentation:
var dataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
$.ajax( {
url: "http://demos.kendoui.com/service/products",
dataType: "jsonp",
success: function(result) {
options.success(result);
}
});
},
update: function(options) {
alert(1);
// make JSONP request to http://demos.kendoui.com/service/products/update
$.ajax( {
url: "http://demos.kendoui.com/service/products/update",
dataType: "jsonp", // "jsonp" is required for cross-domain requests; use "json" for same-domain requests
// send the updated data items as the "models" service parameter encoded in JSON
data: {
models: kendo.stringify(options.data.models)
},
success: function(result) {
// notify the data source that the request succeeded
options.success(result);
},
error: function(result) {
// notify the data source that the request failed
options.error(result);
}
});
}
},
batch: true,
schema: {
model: { id: "ProductID" }
}
});
dataSource.fetch(function() {
var product = dataSource.at(0);
product.set("UnitPrice", product.UnitPrice + 1);
dataSource.sync();
});
Here is a live demo: http://jsbin.com/omomes/1/edit

Disable ajaxStart() and ajaxStop() for a specific request

I am using .ajaxStart() and .ajaxStop() to show a modal while an ajax request is being made. (between start and stop)
Now I'd like to add a longpoll function that keeps waiting for notifications, similar to the one on the left upper corner of this site.
My problem now lies in disabling this modal only for the longpolling request..
Registering "loading screen" on and off handlers:
$(document).ajaxStart(handleAjaxStart);
$(document).ajaxStop(handleAjaxStop);
My longpoll function:
$.ajax({
timeout: 35000,
url: longPollUrl,
success: function(data){
if(data.queCount) $('#numQueCount').html(data.queCount);
if(data.queAccept) $('#numQueAccept').html(data.queAccept);
},
dataType: 'json',
complete: longpoll
});
I tried:
$().off('ajaxStart');
$().off('ajaxStop');
..and reattaching the handlers after starting the polling, but no joy.
I also tried introducing a global variable into handleAjaxStart() that would return at the first line of the function, but that seems to completely kill the loading screen.
Any ideas how this can be achieved?
I figured it out..
There is an attribute in the options object .ajax() takes called global.
If set to false, it will not trigger the ajaxStart event for the call.
$.ajax({
timeout: 35000,
url: longPollUrl,
success: function(data){
if(data.queCount) $('#numQueCount').html(data.queCount);
if(data.queAccept) $('#numQueAccept').html(data.queAccept);
},
global: false, // this makes sure ajaxStart is not triggered
dataType: 'json',
complete: longpoll
});
After reading all possible solutions, I want to combine answers.
Solution 1: Bind/Unbind
//binding
$(document).bind("ajaxStart.mine", function() {
$('#ajaxProgress').show();
});
$(document).bind("ajaxStop.mine", function() {
$('#ajaxProgress').hide();
});
//Unbinding
$(document).unbind(".mine");
It is a depreciated solution. Before jQuery 1.9, global events of ajax like ajaxStart, ajaxStop, ajaxError etc. can be binded to any element. After jQuery 1.9:
As of jQuery 1.9, all the handlers for the jQuery global Ajax events,
including those added with the .ajaxStart() method, must be attached
to document.
Therefore we cannot bind/unbind these events to custom namespaces.
Solution 2: Set the property global to false
$.ajax({
url: "google.com",
type: "GET",
dataType: "json",
global: false, //This is the key property.
success: function (data) {
console.log(data);
},
error: function (data) {
console.log(data);
}
});
This solution works to disable ajaxStart()/ajaxStop() event(s). However, it also makes disable ajaxComplete(), ajaxError(), ajaxSend(), ajaxSuccess(). If you don't use these global events, it seems ok, but when it is needed, you have to come back and change your solution for all pages where you set global: false.
Solution 3: Use global variable
var showLoadingEnabled = true;
$(document).ready(function () {
$('#loading')
.hide() // at first, just hide it
.ajaxStart(function () {
if (showLoadingEnabled) {
$(this).show();
}
})
.ajaxStop(function () {
if (showLoadingEnabled) {
$(this).hide();
}
});
});
function justAnotherFunction() {
window.showLoadingEnabled = false;
$.ajax({
url: 'www.google.com',
type: 'GET',
complete: function (data) {
window.showLoadingEnabled = true;
console.log(data);
}
});
}
Global variables should not be used in javascript files. However, this is the simplest solution, I can find.
I prefered the third solution for my project.

Ajax - prevent click on a successful ajax request

I have a video thumbnail on my page, with a little icon "Thumbs Down". When you click on that, another thumbnail shows, replacing the other. User can do that as much as they want.
My code is now working only the first time. HTML:
AJAX:
$('.dislike_black').click(function(e) {
e.preventDefault();
alert("test");
var $aTag = $(this);
$.ajax({
url: $aTag.attr('href'),
type: "POST",
data: {
"sort": $aTag.data('sort'),
"page": $aTag.data('page')
},
success: function(response) {
$aTag.parents("li").replaceWith(response);
}
});
});
When I click the icon the first time, its all fine, triggers the alert, the second time thought, no alert, and the browser is loading the href link.
I tried .preventDefault(); on the success and the complete event, but its not working.
Any hint on how to do this?
Your content is dynamically created so, depending on the version of jQuery you are using, you need the jQuery.live() or jQuery.on() method
jQuery.live() since jQuery 1.3 an event handler for all elements which match the current selector, now and in the future.
jQuery.on() since jQuery 1.7 - Attach an event handler function for one or more events to the selected elements.
Sample
jQuery.live()
$('.dislike_black').live("click", function(e) {
e.preventDefault();
alert("test");
var $aTag = $(this);
$.ajax({
url: $aTag.attr('href'),
type: "POST",
data: {
"sort": $aTag.data('sort'),
"page": $aTag.data('page')
},
success: function(response) {
$aTag.parents("li").replaceWith(response);
}
});
});
jQuery.on()
$('.dislike_black').on("click", function(e) {
e.preventDefault();
alert("test");
var $aTag = $(this);
$.ajax({
url: $aTag.attr('href'),
type: "POST",
data: {
"sort": $aTag.data('sort'),
"page": $aTag.data('page')
},
success: function(response) {
$aTag.parents("li").replaceWith(response);
}
});
});
More Information
jQuery.live()
jQuery.on()
Because you are replacing the dom which contains the anchor itself by new html in the ajax success handler. In this case you should use on which will attach event handler to parent or document element whatever you pass as the root element but will trigger the event only on the matching selector which you pass as the second argument. Try this.
$(document).on('click', '.dislike_black', function(e) {
e.preventDefault();
alert("test");
var $aTag = $(this);
$.ajax({
url: $aTag.attr('href'),
type: "POST",
data: {
"sort": $aTag.data('sort'),
"page": $aTag.data('page')
},
success: function(response) {
$aTag.parents("li").replaceWith(response);
}
});
});
.on() reference: http://api.jquery.com/on/ (Ver. 1.7+)
If you are using older version of jQuery you can still achieve this using delegate method whose syntax is same as on but just the first 2 arguments are interchanged.
$(document).delegate('.dislike_black', 'click', function(e) {
//Your code here
});
.delegate() reference: http://api.jquery.com/delegate/
try
$(document).delegate('.dislike_black',"click",function(e) {
Try using event delegation.
// older jquery, use this line:
// $( ".dislike_black" ).live( "click", function ( e ) {
$( document ).on( "click", ".dislike_black", function ( e ) {
e.preventDefault();
alert( "test" );
var $aTag = $( this );
$.ajax( {
url : $aTag.attr( 'href' ),
type : "POST",
data : {
"sort" : $aTag.data( 'sort' ),
"page" : $aTag.data( 'page' )
},
success: function ( response ) {
$aTag.parents( "li" ).replaceWith( response );
}
});
});

Crossdomain jQuery.ajax sometimes doesn't work in firefox 8 but works in Chrome/IE

I have this script that queries my Ruby on Rails application (located on a remote domain) using jQuery 1.7.1. The script works fine in Chrome and even in IE9, but not in Firefox.
Here is the script:
Informer= {
getData: function(args)
{
$.ajax({
dataType: 'jsonp',
data: args,
url: 'http://localhost:3000/informer.js',
beforeSend: function () {
alert("beforeSend");
},
error: function () {
alert("error");
},
success: function (data) {
alert("success");
},
complete: function(){
alert("complete");
}
});
}
}
I call it like this
$(document).ready(function()
{
Informer.getData(someArgs);
});
So in chrome I get 3 alerts, while in firefox I only get "beforeSend". I also don't see any requests in firebug.
It definitely has something to do with the URL. I changed it to http://jsfiddle.net/echo/jsonp/ and it worked.
But I still have 2 why's:
upd
In short, here's what I have so far:
It didn't work for me yesterday at all (3 hours wasted, sigh) and it does today.
It always works in Chrome and IE
The request is not shown in Firebug
When the script fails (meaning, I only get the beforeSend alert), my app's log doesn't get updated (I assume, FF doesn't send the request)
Tried using jquery-jsonp with no result
10 of 11 users with FF8 reported that the script worked.
Here's the test script for those who are interrested (if any)
Just to make yours valid:(I inserted the howdy part for your ... not knowing what you had there and to bogus args) can you test this:
Informer = {
getData: function(args) {
$.ajax({
dataType: 'jsonp',
data: args,
url: 'http://localhost:3000/informer.js',
beforeSend: function() {
alert("beforeSend");
},
error: function() {
alert("error");
},
success: function(data) {
alert("success");
},
complete: function() {
alert("complete");
}
});
},
howdy: {}
};
var someArgs = {
hi: "me"
};
$(document).ready(function() {
Informer.getData(someArgs);
});
EDIT: Fixed parameter issue in: http://jsfiddle.net/MarkSchultheiss/NKgyM/
and set it to echo the returned value.

jquery bind functions and triggers after ajax call

function bindALLFunctions() {
..all triggers functions related go here
};
$.ajax({
type: 'POST',
url: myURL,
data: { thisParamIdNo: thisIdNo },
success: function(data){
$(".incContainer").html(data);
bindALLFunctions();
},
dataType: 'html'
});
I am new to ajax and JQuery.
I have the above ajax call in my js-jquery code. bindALLFunctions(); is used to re-call all the triggers and functions after the ajax call. It works all fine and good as expected. However, I have read somewhere that is better to load something after the initial action is finished, so I have tried to add/edit the following two without any success.
Any ideas?
1) -> $(".incContainer").html(data, function(){
bindALLFunctions();
});
2) -> $(".incContainer").html(data).bindALLFunctions();
Perhaps you should have a look to the live and delegate functions. You can set a unique event handler at the beggining of your app and all your loaded ajax code will be automatically binded:
$("table").delegate("td", "hover", function(){
$(this).toggleClass("hover");
});
But if you prefer to use Jquery.ajax call you have to do something like this:
$.ajax({
type: 'POST',
url: myURL,
data: { thisParamIdNo: thisIdNo },
success: function(data){
$(".incContainer").html(data);
bindALLFunctions(".incContainer");
},
dataType: 'html'
});
and transform bindALLFunctions as:
function bindALLFunctions(selector) {
..all triggers functions related go here. Example:
$('#foo', selector).bind('click', function() {
alert('User clicked on "foo."');
});
};
that will only bind events "under" the given selector.
Your initial code was fine. The new version does not work because html() function does not have a callback function.
It's hard to tell from your question just what you intend to ask, but my guess is that you want to know about the ready function. It would let you call your bindALLFunctions after the document was available; just do $(document).ready(bindALLFunctions) or $(document).ready(function() { bindALLFunctions(); }).

Resources