jquery replaceWith() not working in $.post function [duplicate] - ajax

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 8 years ago.
I'm trying to make a to-do list type thing.
Here, I want the new goal to be saved to the database, and then for only the div with the relevant list to refresh, showing the list with the new goal added.
The database updates fine, the new html with the new list item is returned just fine, but
.replaceWith() doesn't seem to work. Nothing happens.
It works outside of that function, but not inside of it, and I'm not sure why.
$('.addGoal').submit(function(event){
var listid = $(this).attr('id');
var desc = $(this).children('.goalinput').val();
event.preventDefault();
if(desc == "") {
console.log("empty!");
return;
}
var posting = $.post("updatedata.php", { what :'addgoal', id: listid, data: desc});
posting.done(function(data){
console.log("saved!" + data); //this works, the updated html is being returned
$(this).closest('#goallist').replaceWith("Returned data goes here"); //this works outside of this function but not inside of it.
});
});

this doesn't automatically keep its value in the callback function. You need to bind a closure variable:
$('.addGoal').submit(function(event){
var listid = $(this).attr('id');
var desc = $(this).children('.goalinput').val();
event.preventDefault();
if(desc == "") {
console.log("empty!");
return;
}
var that = this; // Closure variable
var posting = $.post("updatedata.php", { what :'addgoal', id: listid, data: desc});
posting.done(function(data){
console.log("saved!" + data);
$(that).closest('#goallist').replaceWith("Returned data goes here");
});
});

Please see
How to access the correct this / context inside a callback? for an explanation and solution for the general problem, and
$(this) inside of AJAX success not working for a similar problem with $.ajax
But since IDs are supposed to be unique in an HTML document anyway, you can replace $(this).closest('#goallist') with $('#goallist') and completely ignore this.

Related

casperjs evaluate function returns invalid value

I'm now using casperjs for web crawling. Almost everything is good, but I faced some trouble. First, my code is like below.
casper.start().each(SOME_URLS, function(self, URL) {
self.thenOpen(URL, function() {
self.then(function() {
var getDatas = function() {
var title = $('SOME_SELECTOR').map(function() {
return $(this).text();
}).get();
return {
title: title
};
}
data = self.evaluate(getDatas);
console.log(JSON.stringify(data));
});
});
}).run();
I want to get some data from webpage to 'data' variable. Sometimes data is perfectly good(on console.log), but sometimes, data is empty!
Why this happening? What did I wrong?
The problem is you cant call casper.start more than once. Your loop needs to inside the casper.start function or inside a casper.then
See this excellent SO answer to help you do this.
Basically only call casper.start once and place your loop inside a casper.then

Ajax / jQuery - append new items but check don't already exist in DOM

I have a container div which includes lots of element divs all of which have a unique ID. I then make an ajax call to get more elements and append these to the DOM.
This works using the function below but I need to check that what I append doesn't already exist in the DOM. I've been looking into using each() and possibly remove() or detach() in order to do this, but I am not sure of jQuery syntax and really need some assistance.
function loadMoreItems(url) {
$.get(url, null, function(data) {
var container = $(data).find('#container');
var newItemsHTML = "";
/*-- not sure what to do in between
container.find('.element').remove();
container.each('.element').detach();
--*/
newItemsHTML = $(container).html();
var $newItems = $(newItemsHTML);
$container.isotope('insert', $newItems, true);
}, 'html');
}
<div class="element" id="id_172977"></div>
Assuming all of appended divs has class element you can do
$(".element").each(function() {
container.find("#" + this.id).remove();
});
Demo

There must be an easier way

I am trying to create an JQM app and are doing so by getting a lot of data from database. When I click on a link from a ajax/json generated calendar list I should then be able to get the info for that event by calling the server and get the data. As it is now I do this in 2 steps like this.
My ajax generated event list:
$.each(groupcalendar, function (i, val) {
output += '<li><h2>' + val.matchformname + '</h2><p><strong>' + val.matchday + '</strong></p><p>' + val.coursename + '</p><p class="ui-li-aside"><strong>' + val.matchtime + '</strong></p></li>';
});
When I click on one of the links I want to goto a page called prematchdata.html and get the data fro that specific event. I do so by first calling the click and get the eventid from data-id like this:
$(document).on('click', '#gotoMatch', function () {
var matchid = $(this).attr("data-id");
$.get("http://mypage.com/json/getmatchinfo.php?matchid="+matchid, function(data) {
localStorage["matchinfo"] = JSON.stringify(data);
$.mobile.changePage( "prematchdata.html", { transition: "slide", changeHash: true} );
}, "json");
});
I save the returned data as localStorage and then uses this data in my pageinit like this:
$(document).on("pageinit", "#prematchdata", function() {
var matchinfo = {};
matchinfo = JSON.parse(localStorage["matchinfo"])
var content = '<h2>'+matchinfo["matchname"]+'</h2>';
$('.infoholder').html(content);
});
It works, although for me it seems like the last 2 steps should be done in one, but i am not sure how to do so? It seems a little bit wrong get data, save locally and then use it? Can't this be done without the $(document).on('click', '#gotoMatch', function () {});?
Hoping for some help and thanks in advance :-)
You could try sending it up using a query string. When you're using changePage, change your code like this :
$(document).on('click', '#gotoMatch', function () {
var matchid = $(this).attr("data-id");
$.get("http://mypage.com/json/getmatchinfo.php?matchid=" + matchid, function (data) {
paramData = data[0];
$.mobile.changePage("prematchdata.html", {
transition: "slide",
changeHash: true,
data: paramData //added this extra parameter which will pass data as a query string
});
}, "json");
});
When you're getting it back,
$(document).on("pageinit", "#prematchdata", function() {
var url = $.url(document.location);
var name= url.param("matchname");
var content = '<h2>'+ name +'</h2>';
$('.infoholder').html(content);
});
Another easy way would be use a singlepage template instead of a multi page template. Then, you could just use a global variable to get and set data.
That said, what you're doing right now is more secure than this query string method. By using this, anyone can see what you are sending over the URL. So I advise you keep using localStorage. For more info on this, look into this question.

ajax call not responding with $.post

What i am trying to do is to get the value of the selected elements by jquery selection. After that, those value are post to php script via ajax and then retrieve the data from the database and display it on the same page (something called autocompete).
var marvalue=$("input[name=m_status]:checked").val();
var fromhvalue=$("#fromheight").val();
var tohvalue=$("#toheight").val();
var value = $("#edu_det1").val();
alert (value);
var regvalue = $("#religion").val();
alert (regvalue);
var occvalue = $("#occupation").val();
alert (occvalue);
var convalue = $("#country").val();
alert (convalue);
Alert is there to check the correct values. As you see the code above this will get the values from the different input elements.
Below is the code i used to post to php
/*
$.post("regsearch.php", {queryString: ""+value+"",queryString1: ""+marvalue+"",queryStringfage: ""+fage+"",queryStringtage: ""+tage+""+queryStringfromh: ""+fromhvalue+""+queryStringtoh: ""+tohvalue+""+}, function(data) { // Do an AJAX call
$('#suggestions').fadeIn(); // Show the suggestions box
$('#suggestions').html(data); // Fill the suggestions box
});
*/
The problem :
when the comment is removed nor the alert popup and neither the result displayed. Ok about the result as no query is posted.
Major part is that when i use the below code which hold only m_status and edu_det1 it works.
marvalue=$("input[name=m_status]:checked").val();
alert (marvalue);
var value = $("#edu_det1").val();
alert (value);
The post code for above is
$.post("regsearch.php", {
queryString: ""+value+"",
queryString1: ""+marvalue+"",
queryStringfage: ""+fage+"",queryStringtage: ""+tage+""
}, function(data) {
// Do an AJAX call
$('#suggestions').fadeIn(); // Show the suggestions box
$('#suggestions').html(data); // Fill the suggestions box
});
The code for age and it verification is not added here. What is the problem and how to sort this out?
It will be better if you use jquery serialize() function. This will make your life easier to work with forms.
var querstring = $(form).serialize();
above will help
I guess using ajax post jQuery.ajax() will do the same thing and you can even serialize the fields in your page.
http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
I have done similar type of code
UserName is the field Which I am passing
var data = $('#Username').serialize();
$('#usernameCheck').empty();
if (!$("form").validate().element("#Username"))
return;
$.ajax({
url: '/SignUp/CheckUsername',
type: 'POST',
data: data,
async: true,
success: function (result) {
if (result == 1) {
$('#usernameCheck').html('<font color=green>Username available</font>');
usernameOK = true;
}
else if (result == 2) {
$('#usernameCheck').html('<font color=red>Username not available</font>');
usernameOK = false;
}
else {
$('#usernameCheck').empty();
usernameOK = false;
}
}
});
First of all you should use your console to see Javascript errors, as I'm sure this will generate some. For example that querystring is undefined.
I'd also console.log instead of alert, it is less annoying and more informative.
Then: you dont need to use f.e. ""+marvalue+"" - just use marvalue. On the other hand f.e. queryString should be quoted...
$.post("regsearch.php", {'queryString':value,'queryString1': marvalue,'queryStringfage':fage,'queryStringtage':tage,'queryStringfromh': fromhvalue,'queryStringtoh':tohvalue}, function(data) {
$('#suggestions').fadeIn();
$('#suggestions').html(data);
});

HTML data from multiple ajax requests to javascript array

I'm trying to pre-load some html content using AJAX and jQuery. The AJAX callback function adds the data to an associative array. I'm fine if I do each request individually:
var contentArray = new Object();
var urlA = "includes/contentA.php";
var urlB = "includes/contentB.php";
var urlC = "includes/contentC.php";
$.get(urlA, function(htmlA) {
contentArray["A"] = htmlA;
});
$.get(urlB, function(htmlB) {
contentArray["B"] = htmlB;
});
$.get(urlC, function(htmlC) {
contentArray["C"] = htmlC;
});
Since I am likely to have a few of these (more than three), I tried to do it a for loop:
var contentArray = new Object();
var pages = new Object();
pages["A"] = "includes/contentA.php";
pages["B"] = "includes/contentB.php";
pages["C"] = "includes/contentC.php";
for (var key in pages) {
var URL = pages[key];
$.get(URL, function(html) {
contentArray[key] = html;
});
}
However, this doesn't work. contentArray only has one property containing html data, rather than three. I'm knew to jQuery, particularly the AJAX stuff, so both explanations and solutions (similar or different-method-same-result) are welome.
By the way, I'm aware that one larger AJAX request is preferable to multiple small ones, but I'm trying to retain compatibility for users without JS enabled, and the current php includes are convenient. Any suggestions as how I might satisfy both these requirements are also very welcome.
Thanks.
The callback function for an AJAX request doesn't run until the request returns. In your case each callback function will use key as it exists in the current context, and since there's no key variable in it's local scope it will use the nearest it can find, the key in your for loop.
The problem is by the time the AJAX requests return, the for loop has been fully iterated over and key is equal to the last key in the array. Thus each of the callback functions will receive the same key, overwriting the previous value in your contentArray.
If you're using jQuery 1.5.1 or above a quick and dirty solution (one that doesn't involve changing the current structure of your PHP files) might be to try the following:
for (var key in pages) {
var URL = pages[key];
$.ajax({
url: URL,
xhrFields: {
'customData': key
},
success: function(html, statusText, jqXHR) {
contentArray[jqXHR.customData] = html;
}
});
}
I haven't tested that but according to the documentation page it should work. All you're doing is using the request object created by jQuery to pass your variable along to the callback function.
Hope that helps

Resources