append data loaded problem - javascript

My html is like this
<div id="rsContainer">
<table id="rsTable"><!-- DATA HERE --></table>
</div>
and my javascript is like this
$('#UpdateAll').click(function() {
$('#status').fadeIn('500').text('Loading... This may take a while.');
$.ajax({
type: 'post',
url: 'func.php',
data: 'action=updateAll',
success: function(response) {
$('#response').fadeOut('500').fadeIn('500').append(response);
$('#rsTable').slideUp('1000').load('index.php #rsTable', function() {
$(this).appendTo('#rsContainer').slideDown('1000');
});
$('#status').fadeOut('500').empty();
}
});
});
This works fine and but after appening the html looks like this
<div id="rsContainer">
<table id="rsTable">
<table id="rsTable"><!--data--></table>
</table>
</div>
As you can see it actually appends it to rsTable how can i maintain the original structure?
Thank You.

In the tests I've run, doing a .emtpy() before a .prepend() was about 20% faster over 200 iterations than doing a .html(). Strange but true.
If your intent is to have both rsTable's in there, you should add a counter to the id or use a class, since ids must be unique.
It looks like you want to do this though:
$('#rsContainer').empty();
$('#rsContainer').prepend($('#rsTable'));

$('#rsContainer').slideUp('1000').load('index.php #rsTable', function() {
$(this).slideDown('1000');
});
change the slideUp id to parent id.

Related

How to receive AJAX (json) response in a divs with same class name individually?

I've been getting crazier day after day with this, I can't find an answer, I've spent like 100h+ with this... I hope someone could help me out!
UPDATE:
So to make myself more clear on this issue and be able to get help from others, I basically have 3 containers named "main-container" they all have 3 containers as childs all with the same class name, and when I submit the button, I trigger an ajax function to load the JSON strings comming from php into the child divs, the problem is that I get the 3 "main_containers" to load the ajax at the same time, I only want to load the ajax if I press the button of each "main_container" individually.
I've been using jquery and vanilla JS as well but seems I just can't get it done!
This is how I currently trigger the button with jquery:
$('.trigger_button_inside_divs').click(my_ajax_function);
And this is how my ajax looks like:
function my_ajax_function(){
$.ajax({
dataType: "JSON",
type: 'POST',
url: test.php,
success: function(data) {
$('.div_to_render_JSON_1').html(data.PHP_JSON_1_RECEIVED);
$('.div_to_render_JSON_2').html(data.PHP_JSON_2_RECEIVED);
$('.div_to_render_JSON_3').html(data.PHP_JSON_3_RECEIVED);
}
});
}
HTML looks like this:
<div class="main_container">
<div class="my_div">
//div_to_render_JSON_1
</div>
<div class="my_div">
//div_to_render_JSON_2
</div>
<div class="my_div">
//div_to_render_JSON_3
</div>
<button class="trigger_ajax_function_btn">Click to load ajax</button> //this btn loads ajax into the div class "my_div"
</div>
<div class="main_container">
<div class="my_div">
//div_to_render_JSON_1
</div>
<div class="my_div">
//div_to_render_JSON_2
</div>
<div class="my_div">
//div_to_render_JSON_3
</div>
<button class="trigger_ajax_function_btn">Click to load ajax</button> //this btn loads ajax into the div class "my_div"
</div>
<div class="main_container">
<div class="my_div">
//div_to_render_JSON_1
</div>
<div class="my_div">
//div_to_render_JSON_2
</div>
<div class="my_div">
//div_to_render_JSON_3
</div>
<button class="trigger_ajax_function_btn">Click to load ajax</button> //this btn loads ajax into the div class "my_div"
</div>
So in conclusion, each of those 6 "divs" has a button that triggers an function containing my ajax to render inside that particular div. But what I get is that every time I click that triggering button, I get the ajax to render in all of the 6 divs, instead of render on each particular div only when I click its particular button.
Thanks a lot people, I really hope to get this done!
Cheers.
PD:
This is something a programmer did to achieve what I'm trying to achieve but I just can't figure out what in this code is that is making possible clicking 1 button and affect THAT html element , even though they all have the same class.
(function(){
$("form input[type=submit]").click(function() {
$("input[type=submit]", $(this).parents("form")).removeAttr("clicked");
$(this).attr("clicked", "true");
});
var xhr = new XMLHttpRequest();
var el;
function SetDataInTheForm()
{
var resp = JSON.parse(xhr.response)
var pt=0
var ct=0
var gt=0
Array.prototype.forEach.call(el.querySelectorAll(".test"),function(e,i){
e.innerHTML=resp[i].name
})
Array.prototype.forEach.call(el.querySelectorAll(".p"),function(e,i){
e.innerHTML=parseFloat(resp[i].p).toFixed(0)
pt+=parseFloat(resp[i].p)
})
Array.prototype.forEach.call(el.querySelectorAll(".c"),function(e,i){
e.innerHTML=parseFloat(resp[i].c).toFixed(0)
ct+=parseFloat(resp[i].c)
})
Array.prototype.forEach.call(el.querySelectorAll(".g"),function(e,i){
e.innerHTML=parseFloat(resp[i].g).toFixed(0)
gt+=parseFloat(resp[i].g)
})
el.querySelector(".wtp").innerHTML=parseFloat(resp[0].total).toFixed(0)+" "+resp[0].unit
el.querySelector(".wtc").innerHTML=parseFloat(resp[1].total).toFixed(0)+" "+resp[1].unit
el.querySelector(".wtg").innerHTML=parseFloat(resp[2].total).toFixed(0)+" "+resp[2].unit
el.querySelector(".pt").innerHTML=pt.toFixed(0)
el.querySelector(".ct").innerHTML=ct.toFixed(0)
el.querySelector(".gt").innerHTML=gt.toFixed(0)
}
function HandleSubmit(e)
{
el=e.currentTarget
e.preventDefault();
xhr.open("POST","/url_here.php",true)
xhr.setRequestHeader("content-type","application/x-www-form-urlencoded")
xhr.onload=SetDataInTheForm
var button=e.currentTarget.querySelector("input[type=submit][clicked=true]")
button.removeAttribute("clicked")
xhr.send($("#"+e.currentTarget.id).serialize()+"&"+button.getAttribute("name")+"=on")
}
[].forEach.call(document.querySelectorAll("._form_"),function(form){
form.addEventListener("submit",HandleSubmit,false);
})
})()
Remember that $('.div_container_to_render_JSON') is a new selector that selects all elements with a class div_container_to_render_JSON. What you want to happen is figuring out where that click came from, and find the corresponding div_container_to_render_JSON.
Luckily for you, a jQuery click handler sets the this keyword to the HTMLElement where the click was captured. You can use this to get the parent element.
$('.your-button').on('click', function () {
const myButton = $(this);
$.ajax({
// ...
success (data) {
myButton.parent().html(data.PHP_JSON_RECEIVED);
// or if you need to find a parent further up in the chain
// myButton.parents('.div_container_to_render_JSON').html(data.PHP_JSON_RECEIVED);
}
});
});
The problem is that your class selector is indeed selecting all your divs at the same time.
Solution, set identifiers for your divs as such:
<div class="my_div" id="my_div_1">
and then you can use those id's to fill in the data:
$('#my_div_1').html(data.PHP_JSON_1_RECEIVED);
and repeat for your 6 divs (notice the change from class selector '.' to identifier selector '#')
Thanks for the replies people. I finally figured it out after days of hard work, it was something really simple.. here's the answer:
$('.trigger_button_inside_divs').click(my_ajax_function);
var thisButton = $(this);
var thisDiv = thisButton.closest(".main_container");
function my_ajax_function(){
$.ajax({
dataType: "JSON",
type: 'POST',
url: test.php,
success: function(data) {
thisDiv.find('.div_to_render_JSON_1').html(data.PHP_JSON_1_RECEIVED);
thisDiv.find('.div_to_render_JSON_2').html(data.PHP_JSON_2_RECEIVED);
thisDiv.find('.div_to_render_JSON_3').html(data.PHP_JSON_3_RECEIVED);
}
});
}

Jquery AJAX id selector and post with change class

I have one question. I am trying to make a ajax post with id and also trying to change the class which data-id selected.
I have created this DEMO from codepen.io
In this demo you can see there is a two container div and the container divs inside some different color div.
So what i am trying to do. When i click .change_pri then that clicked (.style, style1, style2) will automatically change .type style like:
<div class="test" id="1">
<div class="type style">selected color</div> <-- class is style
<div class="select_types">
<div class="type_s"><div class="change_pri style" data-id="0">0</div></div>
<div class="type_s"><div class="change_pri style1" data-id="1">1</div></div>
<div class="type_s"><div class="change_pri style2" data-id="2">2</div></div>
</div>
</div>
after clicking change_pri style2 then it need to looks like this:
<div class="test" id="1">
<div class="type style2">selected color</div> <-- after clicking class is style2
<div class="select_types">
<div class="type_s"><div class="change_pri style" data-id="0">0</div></div>
<div class="type_s"><div class="change_pri style1" data-id="1">1</div></div>
<div class="type_s"><div class="change_pri style2" data-id="2">2</div></div>
</div>
</div>
and post the data-id with ajax.
I do not know how the rest of that section, but I was able to do so. Anyone can help me in this regard ?
$(function() {
var i;
i = $(this).attr('id');
});
$('.change_pri').on('click', function(e) {
e.preventDefault();
$.ajax({
type: "POST",
url: "chage_number.php",
data: {
id: i,
},
});
});
The Javascript with the AJAX request should probably look something like this:
$('.change_pri').click(function(){
var dataid = $(this).attr('data-id');
var id = $(this).closest('.test').attr('id');
$.ajax({
type: "POST",
url: "chage_number.php",
data: { dataid : dataid, id: id }
}).success(function(result){
alert(result);
});
});
And then depending on what you want to do back-end, you can access that variable in chage_number.php via $_POST['id'].
So a simple example would be
chage_number.php
echo $_POST['id'] . ", ". $_POST['dataid'];
This should alert() both ids.
you can try this..
$('.change_pri').on('click', function(e) {
var styletype = $(this).attr('class').split(' ')[1];
var ctoremove = $('.type').attr('class').split(' ')[1];
$('.type').removeClass(ctoremove).addClass(styletype);
$.ajax({
type: "POST",
url: "chage_number.php",
data: { id: i }
}).success(function(result){
alert(result);
});
});
and here is the FIDDLE
I take it as the second container should be an example of what happens clicking the div's of the first one.
See this working example, it should do what you asked for: http://codepen.io/anon/pen/qdxVzW
This is where you get an alert telling you which data-id you clicked and then it changes the class of the .type element
alert($(this).attr('data-id')); //this can be removed, it's just a test
$('#test-1 > .type') //remove styleN and add the needed one
.removeClass('style0')
.removeClass('style1')
.removeClass('style2')
.addClass('style'+$(this).attr('data-id'))
The part about the ajax call remains almost the same, with a little modification when it comes to setting the id to be sent:
$('.change_pri').on('click', function(e) {
//As suggested by #Mackan, a little modification: store data-id
var dataId = $(this).attr('data-id');
$.ajax({
type: "POST",
url: "chage_number.php",
data: {
id: dataId //send the correct id
}
});
});
The function at the beginning of the script can be safely removed, it doesn't affect the rest of the code :)
I was almost forgetting: add a 0 to the style which doesn't have a number, like:
<div class="change_pri style0" data-id="0">0</div></div>
Otherwise when it come's to data-id=0 the script doesn't know what to do. Of course, same thing should be done into css code:
.style0{
background-color:red;
color:#ffffff;
margin:5px;
}

too much HTML in an ajax script?

I read from this page that appending a lot of elements is bad practice and I should build up a string during each iteration of the loop and then set the HTML of the DOM element to that string. Does the same go for using too much HTML in the loop?
I have an AJAX script that parses JSON data. It requires adding data to different existing elements, like this:
$.ajax({
url: "url",
success: function (data) {
$(data.query.results.json.json).each(function (index, item) {
var title = item.title, // A,B,C or D
age = item.age,
background = item.background,
ingredient = item.Ingredient;
$('.'+ title+'_ingredient').html(''+ingredient+'')
$('.'+ title+'_age').html(''+age+'')
$('.'+ title+'_background').html(''+background+'')
});
},
error: function () {}
});
HTML:
<div class="A_ingredient"></div>
<div class="B_ingredient"></div>
<div class="C_ingredient"></div>
<div class="D_ingredient"></div>
<div class="A_age"></div>
<div class="B_age"></div>
<div class="C_age"></div>
<div class="D_age"></div>
<div class="A_background"></div>
<div class="B_background"></div>
<div class="C_background"></div>
<div class="D_background"></div>
Is it necessary to build up a string first? If so, can you show me how to do that?
It is purely about the time it takes to process calls to html() so they simply recommend you reduce the number of calls. In this case you could build them once in a loop then sets the div html once for each.
Update:
Based on your update, aside from all the extra trailing quotes you don't need to add (a string is a string is a string), your code is fine as is. You only hit each item once.
e.g.
$.ajax({
url: "url",
success: function (data) {
$(data.query.results.json.json).each(function (index, item) {
var title = item.title, // A,B,C or D
age = item.age,
background = item.background,
ingredient = item.Ingredient;
$('.'+ title+'_ingredient').html(ingredient);
$('.'+ title+'_age').html(age);
$('.'+ title+'_background').html(background);
});
},
error: function () {}
});
Note: If your item properties (Age, Background, Ingredient) are simple values (not objects or arrays), yo do not need the leading ''+s either.
Previous
Assuming you actually want to concatenate the results (you are only keeping the last ingredient at the moment), you could do something like this:
e.g.
$.ajax({
url: "url",
success: function (data) {
var ingredients = '';
$(data.query.results.json.json).each(function (index, item) {
var title = item.title;
var ingredient = item.Ingredient;
ingredients += ingredient;
});
$('.aclass').html(ingredients);
$('.bclass').html(ingredients);
$('.cclass').html(ingredients);
$('.dclass').html(ingredients);
},
error: function () {}
});
Which can be reduced to:
$('.aclass,.bclass,.cclass,.dclass').html(ingredients);
The contents of each div are identical in your example, so you only need a single string.
In this instance you would probably need some form of delimiter between ingredients, but your example is too vague.
e.g.
ingredients += ingredient + '<br/>';
In your example, you're setting the HTML on many different document elements.
If they're grouped in some way, for example all in a Div with ID #Container, you could build a string of the HTML and set the content of the whole Div at the end of it, something like this:
$.ajax({
url: "url",
success: function (data) {
var sHTML="";
$(data.query.results.json.json).each(function (index, item) {
var title = item.title,
background = item.background,
ingredient = item.Ingredient;
// not sure what your actual HTML is (div/span/td etc) but somethign like this?
sHTML+="<div>"; // an opening container for this item
sHTML+='<div class="'+title+'_ingredient">'+ingredient+'</div>')
sHTML+='<div class="'+title+'_age">'+title+'</div>')
sHTML+='<div class="'+title+'_background">'+background+'</div>')
sHTML+="</div>";
});
$("#Container").html(sHTML);
},
error: function () {}
});
Note I haven't tested this code, but you see the principal hopefully.
That is, build a string of the HTML then set one element at the end with the content.
I have done this a lot in a recent project and haven't seen any speed issues (maybe 50 'items' to set in my case).
HTML will initially look like this :
<div id="container">
</div>
Then end up like this (2 x items in this example) :
<div id="container">
<div>
<div class="<sometitle1>_ingredient">ingredient 1</div>
<div class="<sometitle1>_age">age 1</div>
<div class="<sometitle1>_background">background 1</div>
</div>
<div>
<div class="<sometitle2>_ingredient">ingredient 2</div>
<div class="<sometitle2>_age">age 2</div>
<div class="<sometitle2>_background">background 2</div>
</div>
</div>
subsequent calls will replace the element's content with new values, replacing the old items.
Building a string is, I would imagine, less processor-heavy than setting the html() on lots of elements individually. Each time you use html() I'm guessing that the browser has to go some way towards working out any knock-on effects like expanding the width of an element to accomodate it or whether events will still work as they did, etc - even if actual rendering is only run at the end of the process. This way you use html() once, although what you're setting is more complex.
Hope this helps.

Setting Html On Ajax Success

I have html that looks like this with several items
<div class="item">
<p class="price">$388.00</p>
<p class="part_number">VM2327T23A00T</p>
<p class="real_price"></p>
</div>
<div class="item">
<p class="price">$88.00</p>
<p class="part_number">AA327T23A00T</p>
<p class="real_price"></p>
</div>
<div class="item">
<p class="price">$38.00</p>
<p class="part_number">AA327T23A00T</p>
<p class="real_price"></p>
</div>
etc..
I am trying to iterate through each item and set its "real_price" to a value here is my code:
jQuery('.part_number').each(function () {
parts.push(SearchSpring.jQuery(this).text());
SearchSpring.jQuery.ajax(
{
type: "POST",
url: "RealTimePricing.aspx/TestInteraction",
data: "{param1:'brit', param2: 'nick'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function (msg) {
jQuery("#real_price").html(msg.d);
}
}
);
});
}
I am getting the correct "msg" on success (I can see this in firebug) but it never sets the html, also it only iterates through the each 1 time..
I am not sure why this isnt setting the html
jQuery("#real_price").html(msg.d);
And why is my code not looping through all the ".part_number" tags in the html?
class="real_price" implies .real_price, but you have to make sure you're updating the correct element as well (there are several elements with that class). I suggest using .next as the element to update is next to each .part_number element:
jQuery(".part_number").each(function() {
var $elem = jQuery(this).next(".real_price");
and then:
$elem.html(msg.d);
Use a . symbol instead of #, which is reserved for querying by id. Also, you should do this in a way that accesses individual prices instead otherwise it will update all elements as stated below.
You are trying to update #real_price, which does not exists in your html. You can use the following:
jQuery(this).parent(".item").find(".real_price").html( msg.d ); which updates the other child .real_price of the .item

How to detect the div in which a link to a javascript function has been clicked

I have the following html code:
<div id="result1" class="result">
... some html ...
... link
... some html ...
</div>
<div id="result2" class="result">
... some html ...
... link
... some html ...
</div>
<div id="result3" class="result">
</div>
<div id="result4" class="result">
</div>
The goal is to update the content of the next div when I click on the link. So for instance, when I click on a link in #result2, the content of #result3 will be updated.
Here is the javascript function:
<script>
function updateNext(elem, uri) {
$.ajax({
url: uri,
success: function(data) {
elem.closest('.result').nextAll().html('');
elem.closest('.result').next().html(data);
}
});
}
</script>
However, when I use the link, elem is set as the window, not the link itself.
The content of the div is generated by a server which should not know the position of the div in which the code he is generating will be.
I also tried with a
<a href="javascript:" onclick="updateNext(...
with no other result...
any idea ? :-)
Thanks,
Arnaud.
this returns the window when used in href, but here it returns the actual link:
... link
Don't forget to use the jQuery $ in:
$(elem).closest('.result').nextAll().html('');
$(elem).closest('.result').next().html(data);
Why do you use inline scripts when you alrady are using jQuery?
I've setup a Fiddle for you which does what you want: http://jsfiddle.net/eLA3P/1/
The example code:
$('div.result a').click(function() {
$(this).closest('div.result').next().html('test');
return false;
});
First, you must remove those href="javascript:..." attributes. Please never use them again, they are evil.
Then, bind a click handler via jQuery, which you are alredy using:
// since you dynamically self-update the a elements, use "live()":
$("div.result a").live("click", function () {
var $myDiv = $(this).closest("div.result");
$.ajax({
url: "/build/some/url/with/" + $myDiv.attr("id"),
success: function(data) {
$myDiv.next("div.result").html(data);
}
});
return false;
});
Done.
Try to use jQuery to bind the event instead putting a javascript link in the href.
<div id="result1" class="result">
link
</div>
$('.resultLink').click(function(){
var elem = $(this);
$.ajax({
url: uri,
success: function(data) {
elem.closest('.result').nextAll().html('');
elem.closest('.result').next().html(data);
}
});
});
You should do it like this:
http://jsfiddle.net/hJhC7/
The inline JavaScript is gone, and the href is being used to store the "uri", whatever that might be. I'm assuming it's different for each link.
The //remove this lines are just to make $.ajax work with jsFiddle.
$('.update').click(function(e) {
e.preventDefault();
var elem = $(this);
$.ajax({
type: 'post', //remove this
data: {html: Math.random() }, //remove this
url: $(this).attr('href'),
success: function(data) {
//not sure why you're doing this
//elem.closest('.result').nextAll().html('');
elem.closest('.result').next().html(data);
}
});
});
with this HTML:
<div id="result1" class="result">
link
</div>
<div id="result2" class="result">
link
</div>
<div id="result3" class="result">
link
</div>

Categories