I have implemented a jquery plugin ratings widget. It works great until i make an ajax call to go get data. I need the plugin to add to the new elements.
I have tried to encapsulate the script in a function and call the function again on success but with no luck.
I also cant call the function without the success so that is my main issue.
How would I turn this into a function and call it on page load and ajax call. As you can see below i tried surrounding it.
function RatingWidget(e) {
// jQuery.noConflict();
$(document).ready(function() {
//we bind only to the rateit controls within the products div
//$('#products .rateit').bind('rated reset', function (e) {
$(".rateit").bind('over', function(event, value) {
$(this).attr('title', value);
});
$(" .rateit").bind('rated reset', function(e) {
var ri = $(this);
// var msg = ri.next();
// var msg = ri.next('div .ratemsg');
var msg = $(this).parents().nextAll("div.ratemsg:first")
//if the use pressed reset, it will get value: 0 (to be patible with the HTML range control), we could check if e.type == 'reset', and then set the value to null .
var value = ri.rateit('value');
//var productID = ri.data('productid'); // if the product id was in some hidden field: ri.closest('li').find('input[name="productid"]').val()
var ratingid = ri.data('ratingid');
// var ratingtest = ri.data('ratingtest');
var currentTime = new Date()
var month = currentTime.getMonth() + 1
var day = currentTime.getDate()
var year = currentTime.getFullYear()
var dateoftweet = (month + "/" + day + "/" + year)
// var dateoftweetparse = Date.parse(dateoftweet);
var hours = currentTime.getHours()
var minutes = currentTime.getMinutes()
if (minutes < 10) {
minutes = "0" + minutes
}
var timeoftweet = (hours + ":" + minutes + " ")
// var timeoftweetparse = Date.parse(timeoftweet);
//maybe we want to disable voting?
ri.rateit('readonly', true);
$.ajax({
url: '/Home/GetRating',
//your server side script
data: {
id: ratingid,
value: value,
tweetday: dateoftweet,
tweettime: timeoftweet
},
//our data
type: 'POST',
success: function(data) {
//$('#ratemsg').html(data);
msg.html("<B>The TweetId is " + ratingid + " the vote value is " + value + " " + dateoftweet + " " + timeoftweet + "</b>");
},
error: function(jxhr, msg, err) {
// $('#response').append('<li style="color:red">' + msg + '</li>');
msg.html(data);
}
});
});
});
}
I have implemented a jquery plugin ratings widget. It works great until i make an ajax call to go get data. I need the plugin to add to the new elements.
I have tried to encapsulate the script in a function and call the function again on success but with no luck.
I also cant call the function without the success so that is my main issue.
How would I turn this into a function and call it on page load and ajax call. As you can see below i tried surrounding it.
function RatingWidget(e) {
// jQuery.noConflict();
$(document).ready(function() {
//we bind only to the rateit controls within the products div
//$('#products .rateit').bind('rated reset', function (e) {
$(".rateit").bind('over', function(event, value) {
$(this).attr('title', value);
});
$(" .rateit").bind('rated reset', function(e) {
var ri = $(this);
// var msg = ri.next();
// var msg = ri.next('div .ratemsg');
var msg = $(this).parents().nextAll("div.ratemsg:first")
//if the use pressed reset, it will get value: 0 (to be patible with the HTML range control), we could check if e.type == 'reset', and then set the value to null .
var value = ri.rateit('value');
//var productID = ri.data('productid'); // if the product id was in some hidden field: ri.closest('li').find('input[name="productid"]').val()
var ratingid = ri.data('ratingid');
// var ratingtest = ri.data('ratingtest');
var currentTime = new Date()
var month = currentTime.getMonth() + 1
var day = currentTime.getDate()
var year = currentTime.getFullYear()
var dateoftweet = (month + "/" + day + "/" + year)
// var dateoftweetparse = Date.parse(dateoftweet);
var hours = currentTime.getHours()
var minutes = currentTime.getMinutes()
if (minutes < 10) {
minutes = "0" + minutes
}
var timeoftweet = (hours + ":" + minutes + " ")
// var timeoftweetparse = Date.parse(timeoftweet);
//maybe we want to disable voting?
ri.rateit('readonly', true);
$.ajax({
url: '/Home/GetRating',
//your server side script
data: {
id: ratingid,
value: value,
tweetday: dateoftweet,
tweettime: timeoftweet
},
//our data
type: 'POST',
success: function(data) {
//$('#ratemsg').html(data);
msg.html("<B>The TweetId is " + ratingid + " the vote value is " + value + " " + dateoftweet + " " + timeoftweet + "</b>");
},
error: function(jxhr, msg, err) {
// $('#response').append('<li style="color:red">' + msg + '</li>');
msg.html(data);
}
});
});
});
}
Share
Improve this question
edited Apr 15, 2012 at 18:19
Joseph
120k30 gold badges184 silver badges237 bronze badges
asked Apr 15, 2012 at 18:12
Michael HahnMichael Hahn
1431 gold badge5 silver badges12 bronze badges
2
- 3 You need to delegate to make your script work with dynamic elements inserted with Ajax. Replace bind() with on(), and use delegation. – adeneo Commented Apr 15, 2012 at 18:14
- can you talk less about your current solution, and tell us what should happen, when it should happen and how it should happen. – Joseph Commented Apr 15, 2012 at 18:22
2 Answers
Reset to default 3When you read the documentation here: (http://api.jquery./Ajax_Events/)
Every time ajax events are called it triggers a global event handler called "ajaxComplete"
So what I do is use the ".on" function to then listen for that event and do whatever code I want to run.
I'll put an example below:
$(".date").mask("9999/99/99 99:99:99");
$(".expiredate").mask("99/9999");
$(".phone").mask("(999) 999-9999");
$(document).on("ajaxComplete",function(){
$(".date").mask("9999/99/99 99:99:99");
$(".expiredate").mask("99/9999");
$(".phone").mask("(999) 999-9999");
});
In my example, I just run some masks on some fields to insure they still act correctly after the AJAX call. Since I wanted these calls on both the AJAX call and when it was off, I changed my code to this to be more efficient so I would not have to write the code above twice.
$(document).on("ready ajaxComplete",function(){
$(".date").mask("9999/99/99 99:99:99");
$(".expiredate").mask("99/9999");
$(".phone").mask("(999) 999-9999");
});
Hope this helps!
The ready()
event gets fired once the DOM is loaded; from the documentation:
Specify a function to execute when the DOM is fully loaded.
Rather than having your RatingWidget()
function re-bind the ready
event once the AJAX call is done, you should have it bind the elements, e.g.
function RatingWidget() {
$(".rateit").bind( ... )
}
$(document).ready(RatingWidget);
As @adeneo mentioned, using jQuery's on()
method (documentation here) allows you to latch on to events matching a selector regardless of which elements existed when the event was binded, so if you add new elements matching the selector, the events will trigger for them as well. This will save you the trouble of figuring out when you need to re-bind event because your elements were replaced. e.g. you may call this once and not worry about it again:
$(".rateit").on("over", function() { ... } )
Since on
works differently than bind
, this might introduce a performance penalty, but that depends on how often you replace elements, how many elements there are etc. -- it could just might be a performance gain.