Executing Javascript on return from Ajax - javascript

My page makes an Ajax call which returns some HTML to embed in the page and a script to run, attaching JQuery tooltips to various elements of the embedded HTML. The HTML and script are returned as JSON objects by my Django backend, and appear OK in the page, but the Javascript doesn't seem to work when I evaluate it:
$.ajax({
type: "GET",
url: "/url/to/ajax",
data: {
"foo": bar
},
success: function (data) {
$("#my-table").html(data['html']);
// alert(data['script']); // this works: I can see the script
eval(data['script']);
},
error: function () {
$("#my-table").html('');
}
});
The script itself looks like a series of expressions such as:
$(".foobar1").tooltip({
content: "The <em>foo</em> to the <strong>bar</strong>.",
tooltipClass: "tt-ref",
show: null,
close: function (event, ui) {
ui.tooltip.hover(
function () {
$(this).stop(true).fadeTo(400, 1);
},
function () {
$(this).fadeOut("400", function () {
$(this).remove();
})
});
}
});
where foobar1 is a class in the HTML just added to the #my-table HTML.
Can anyone see where I'm going wrong here? Both jquery and jquery-ui are loaded on my page.

You don't need to eval anything, let browser execute it. For this create script element, set its content and append it to DOM:
success: function(data) {
$("#my-table").html(data.html);
$('<script>').html(data.script).appendTo('body');
},
Another, probably better option is to make script a part of the returned HTML.

You might try :
eval("data['script']");

Related

How to check if my container fully load is completed?

I have an issue, do not know if it possible or not, how to check if my container is already loaded or not, because sometimes it is being loaded faster, sometimes slower and if it does not succeed in time getting an error in javaScript where gridview some functions are not recognizable(because the gridview is not loaded fast enough). Hope it is clear. Thanks for Your time.
Code:
function LoadPartial(partialUrl, container) {
$.ajax({
type: 'POST',
url: partialUrl,
success: function (returnData) {
$(container).html(returnData);
}
});
//.done(function () {
// return;
//});
}
you can use something like this.
$(".container").load(function (){
alert("Loaded :)");
});
Let me know in-case this doesn't work.
You can try using .data()
if ($('#mycontainer').data('loaded')) {
// your code
}
If you mean to find event when data received use "complete" function:
$.ajax({
type: 'POST',
url: partialUrl,
success: function (returnData) {
$(container).html(returnData);
},
complete: function() {
console.log('container filled with data');
}
});

Use geocomplete function after ajax event

I have a button that adds an input box where you can type an address. For the address, I'm using the geocomplete plugin. In all input boxes that were not generated with ajax the geocomplete works. If the input was generated by ajax, it doesnt.
This is my code to generate the input box:
$('.add-drop').on('click', function(){
$.ajax({
url : '/ajax/get-location-input',
success : function(data){
$('#additional-drop').append(data);
}
});
});
This is my geocomplete code:
$(".get-location").geocomplete({
details : "form",
types : ["geocode", "establishment"]
}).bind("geocode:result", function(event, result){
console.log(result);
});
The problem is not with the class. I was trying to do something like $(".get-location").on("geocomplete"... but it wasn't working. Any idea? Thanks
AJAX is Asynchronous (Asynchronous JavaScript and XML) That means it might execute after the main code has been finished processing
$.ajax({
url: '/ajax/get-location-input',
success:function(data){
alert(data);
}
});
alert('Hi ');
In this case, Hi will alert first, then data. In your case, the inputs might not even be generated yet and so the geolocation code won't see them
The correct code:
$.ajax({
url: '$('#additional-drop').append(data);',
success:function(data){
$('#additional-drop').append(data);
$(".get-location").geocomplete({
details: "form",
types: ["geocode", "establishment"]
});
}
});
Will make the code run after the data has been fetched from the server
This is me recommended way to do this:
(function () {
$.fn.addGeolocation = function () { this.geocomplete({ details: "form", types: ["geocode", "establishment"] }).bind("geocode:result", function(e, a){ console.log(a); }); }
$.get('/ajax/get-location-input', function (a) {
$('#additional-drop').append(data);
$(".get-location").addGeolocation();
});
/* You may or may not need this */
window.onload = function () { $(".get-location").addGeolocation(); }
}());

Modify text with jQuery for dynamically added elements in DOM

I have a page http://www.projectdemocracy.in/ where some elements are dynamically added (example - CSS class ".fyre-comment-count" showing "X Comment").
I wanted to modify the text once page is loaded.
I was able to change the text using console of jQuery
$(".fyre-comment-count").html($(".fyre-comment-count").text().split(" ")[0]+" Conversations");
When I type the same in my page, it doesn't work.
I also tried $(document).ready(function(){}); but no luck (same with document.ajaxSuccess).
Similarly, document.on would be working only with 'click' events but I want it to be done by default.
$(document).on('click', '.fyre-comment-article', function() {
//Code
});
Does it have any 'load' type event in document.on?
What should I do to accomplish this?
Thanks,
I analyzed your web page and saw the following code:
var articleId = fyre.conv.load.makeArticleId(null);
fyre.conv.load({}, [{
el: 'livefyre-comments',
network: "livefyre.com",
siteId: "351251",
articleId: articleId,
signed: false,
collectionMeta: {
articleId: articleId,
url: "http://projectdemocracy.in",//fyre.conv.load.makeCollectionUrl(),
}
}], function() {});
It seems like the 3rd argument of fyre.conv.load method is a callback function that will be executed when all elements are generated.
So put your code inside this function. It will be like this:
...
}], function() {
console.log('callback');
$(".fyre-comment-count").html($(".fyre-comment-count").text().split(" ")[0]+" Conversations");
});
Hope this helps!
EDIT
If it still doesn't work it may be because livefyre runs this callback before DOM elements are being created. The workaround is to put $(".fyre-comment-count").html(...); inside setTimeout with minimal delay:
...
}], function() {
setTimeout(function() {
$(".fyre-comment-count").html($(".fyre-comment-count").text().split(" ")[0]+" Conversations");
}, 10); //minimal delay. wait till livefyre generates all needed elements
});
EDIT 2
This is another variant how to make it work:
...
}], function(widget) {
widget.on('commentCountUpdated', function() {
setTimeout(function() {
$(".fyre-comment-count").html($(".fyre-comment-count").text().split(" ")[0]+" Conversations");
}, 10);
});
});
This widget has a commentCountUpdated event, so you have to subscribe on it, and every time the comments number is changing, your callback will be executed
By the way, commentCountUpdated callback recieves a single argument - the number of comments, so you can rewrite your code as follows:
}], function(widget) {
widget.on('commentCountUpdated', function(commentsNum) {
setTimeout(function() {
$(".fyre-comment-count").html(commentsNum + " Conversations");
}, 10);
});
});
jQuery has a on load event, if this is what you are looking for:
$(window).load(function(){ ... });

Binding two JQuery and ajax functions

I have the follwoing JQuery/AJAX code:
<script>
$('.warning-dialog').click(function () {
alert($(this).data("id"));
});
$(function () {
//twitter bootstrap script
$("button#delete").click(function () {
$.ajax({
type: "GET",
url: "deleteArticleType.php",
data: { 'typeID': $('.warning-dialog').data("id") },
success: function (msg) {
$("#thanks").html(msg)
$("#form-content").modal('hide');
},
error: function () {
alert("failure");
}
});
});
});
</script>
The first function gets the data-id of a button . The second function calls a PHP page and with the method GET should get the value from the first function.
I tried the code above but it didn't work.
My question is why and how can I fix it?
If these are two separate events, disconnected in time and you want to store the value from the first click and then use it in the second click, then you will have to store it somewhere. There are several options, the simplest being a variable.
$(function () {
var lastClickId;
$('.warning-dialog').click(function () {
lastClickId = $(this).data("id");
});
//twitter bootstrap script
// FIXME: you need to add logic here for what to do if lastClickId isn't set yet
// or create a default behavior in that case
$("button#delete").click(function () {
$.ajax({
type: "GET",
url: "deleteArticleType.php",
data: { 'typeID': lastClickId },
success: function (msg) {
$("#thanks").html(msg)
$("#form-content").modal('hide');
},
error: function () {
alert("failure");
}
});
});
});
Since it looks like you are requiring the first click to happen before the second click can have something to operate on, then you should probably either modify the UI to use different types of controls or you will need to add some error handling if the user doesn't click in the right order.
Actually it should have worked using $('.warning-dialog').data("id")
If your page contains only a single class warning-dialog, you approach will be worked. It seems you're referring this class to many elements.

Using autocomplete (Jquery) on AJAX loaded partial view (MVC4)

I've got a view to create Project models which contains (among other things) a table of company-related data.
I've added a button that does an AJAX call to retrieve a partial view and adds it to the table:
$("#addCompanyRoleProject").click(function () {
cache: false,
$.get('CompanyRoleProjectEntryRow', function (result) {
$("#companyTable").append(result); // Add the row to the table
}, "html").done(function (result) {
});
return false;
});
The partial view is a < tr > in wich one of the < td >'s has an input field:
<input class="company-role-project-company" type="text" data-containerPrefix="#ViewData["ContainerPrefix"]" />
I want that input field inside the partial view received by ajax to be an autocomplete (http://jqueryui.com/autocomplete/) so that the user is able to select from a set of options on each < input > for each row of the table.
I can't seem to access the correspondent field on my AJAX call inside the main view. I've tried using "filter()" and "find()" on both the success and done functions.
I could put my javascript code inside the partial view, but it would then be replicated, not to mention possible ID colisions =\
Any ideias on how to achieve this?
EDIT:
I believe I have everything properly referenced in my view:
#section Scripts {
#Styles.Render("~/Content/themes/base/css")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryui")
#Scripts.Render("~/bundles/jqueryval")
<<<< My JS code is here >>>>
}
And in my page's source code I can see:
<script src="/Scripts/jquery-1.7.1.js"></script>
<script src="/Scripts/jquery-ui-1.8.20.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
EDIT 2:
I followed Darin Dimitrov's advice and added this on the ajax success callback, after appending the result to the table:
$('input.company-role-project-company', result).autocomplete({
...define source etc...
});
But when I type something in the input field, it behaves like a regular text field...
Is there something wrong in my process of using an ajax call to: request a partial view, append it to the table, make it an autocomplete ?
Try like this inside your AJAX success callback after you append the new partial markup to the DOM:
$('input.company-role-project-company', result).autocomplete({
...
});
I ended up doing it like this:
// Add entry to table
$(function () {
$("#addItemButton").click(function () {
cache: false
$.get('URL.......', function (template) {
$('#table> tbody:last').append(template);
});
return false;
});
});
$(".the-class-used-in-the-desired-field-from-partial-view").live("click", function () {
$(this).autocomplete({
source: function (request, response) {
$.ajax({
url: "URL.........", type: "GET", dataType: "json",
data: { term: request.term },
success: function (data) {
response($.map(data, function (item) {
return { ....... };
}))
}
})
},
minLength: 1,
select: function (event, ui) {
... Do some magic ...
}
});
});
I.E., I bound the autocomplete with a .live function, outside the AJAX.
Probably not the best way, but so far it's working as I want it to, for multiple entries.
Thanks to Darin Dimitrov anyway for pointing me to the right direction with the
$('input.company-role-project-company', result)

Categories

Resources