Ajax keeps rewriting html - javascript

On my html page there is some jquery that puts out a get request to a php page and then loops through the returned object and appends the table in the html.
At the bottom of the jquery is an ajax script that sends a value from the above jquery to another php page . This page ends up getting a value from amazon and sends it back to the html.
The problem is that if the number of objects/ items in the table is more than one , the ajax will overwrite itself in the html.
HTML
<table class="normal">
<thead>
<tr>
<th>Image</th>
<th style="width: 45%;">Item</th>
<th>Argos Price</th>
<th>Amazon Price</th>
<th>URL</th>
</tr>
</thead>
</table>
JS/AJAX
<script>
$.get("Extract_DataT2.php", function (data) {
var JSON = jQuery.parseJSON(data); // it will be an object
// loop through each item in the JSON object
$.each(JSON.deals.items, function (index, value) {
tr = $('<tr/>');
tr.append("<td>" + "<img class='dealimg' src='" + value.deal_image + "' >" + "</td>");
tr.append("<td>" + "<h3>" + value.title + "</h3>" + "<p>" + value.description + "</p>" + "</td>");
//tr.append("<td>" + value.description + "</td>");
tr.append("<td> £" + value.price + "</td>");
tr.append("<td id='amazon'>Loading</td>");
// take deal image url and remove unwanted bits
// This means we have the product id to take us to the Argos website
var str = value.deal_image;
var res = str.match(/.*\/(.*)_1.jpg/);
//more jquery here , but removed for stack. same as above
// Add to table
$('table').append(tr);
$.ajax({
type: "POST",
url: 'Task2.php',
data: {pid:res[1]},
success: function(data) {
//alert(data);
$("#amazon").html(data);
console.log( data );
}
});
});
});
</script>

It's wrong to give the same id to many elements. You should assign different id's (maybe you should concatenate with the product's id). This is causing your problem all the last "td" elements have the same id and js just picks the first one and assign the value you go from your request
Try this:
$.get("Extract_DataT2.php", function (data) {
var JSON = jQuery.parseJSON(data); // it will be an object
// loop through each item in the JSON object
$.each(JSON.deals.items, function (index, value) {
var str = value.deal_image;
var res = str.match(/.*\/(.*)_1.jpg/);
tr = $('<tr/>');
tr.append("<td>" + "<img class='dealimg' src='" + value.deal_image + "' >" + "</td>");
tr.append("<td>" + "<h3>" + value.title + "</h3>" + "<p>" + value.description + "</p>" + "</td>");
tr.append("<td> £" + value.price + "</td>");
tr.append("<td id='amazon_" + res + "'>Loading</td>");
// Add to table
$('table').append(tr);
$.ajax({
type: "POST",
url: 'Task2.php',
data: { pid: res[1] },
success: function (data) {
$("#amazon_" + res).html(data);
console.log(data);
}
});
});
});

Related

Sort table column by date in ajax

I have a table that's displayed on button click using ajax. Here's a code snippet:
myBtn.on("click", function() {
displayTable();
});
function displayTable(){
$.ajax({
url:'url to a function in controller',
type: "GET",
//data: {val : val},
dataType: 'json',
success: function(data){
// some codes here
$.each(data.documents, function(key, value){
$("#myTable")
.append(
"<tr class='" + rowClass + "'><td class='text-center'>" +
value.title +
"</td><td class='text-center'>" +
value.time1.replace(/-/g, "/") +
"</td><td class='text-center'>" +
value.time2.replace(/-/g, "/") +
"</td></tr>"
);
});
}
});
}
After this, a table is displayed but it is not sorted by date (value.time2). I tried this but not working:
$("#myTable thead tr").find('th').eq(3).sort(function(a,b){
return new Date($(a).value.time2) > new Date($(b).value.time2);
});
Do you have any idea how to do this? How do I sort it by date (value.time2)?
The best way would be to request the server to sort the values for you. However, if you need to perform this on client side, you can simply sort data.documents before adding it to the page. For example:
data.documents = data.documents.map(function(item) {
// Fix display
item.time1 = item.time1.replace(/-/g, "/");
item.time2 = item.time2.replace(/-/g, "/");
return item;
});
data.documents.sort(function(a, b) {
// Custom sorting function
return new Date(a.time2) > new Date(b.time2);
});
$.each(data.documents, function(key, value){
$("#myTable")
.append(
"<tr class='" + rowClass + "'><td class='text-center'>" +
value.title +
"</td><td class='text-center'>" +
value.time1 +
"</td><td class='text-center'>" +
value.time2 +
"</td></tr>"
);
});

How to append row data to table one by one?

Here is my html code
<tr id="tHead">
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
Here is my js code
$(document).ready(function(){
$.ajax({
url: "data.json",
dataType: "json",
success: function(obj) {
for(i=0;i<obj.data.length;i++){
$("#tHead").after("<tr>" +
"<td>" + obj.data[i].name1 +
"</td><td>" + obj.data[i].name2 +
"</td><td>" + obj.data[i].name3 +
"</td><td>" + obj.data[i].name4 +
"</td><td>" + obj.data[i].name5 +
"</td></tr>");
}
}
});
});
Now I can append data after "tHead" tr.
Because I use .after in my js code, so the data row will append one by one after"tHead" which will make my first data row become the last one in table.
I need first data row will be first row on table when I append it.
What can I do to make it correct?
I try to use .append but not work, the new row will directly append in the end of "tHead" row.
You simply need to use .append() on the parent table, instead of using .after() on the #tHead
success: function(obj) {
for(var i = 0; i < obj.data.length; i++) {
$("#tHead").parent("table").append("<tr>" +
"<td>" + obj.data[i].name1 +
"</td><td>" + obj.data[i].name2 +
"</td><td>" + obj.data[i].name3 +
"</td><td>" + obj.data[i].name4 +
"</td><td>" + obj.data[i].name5 +
"</td></tr>");
}
}
your rows will now be appended in chronological order.
A second solution would be to use .after() on the :last psuedo selector together with the .siblings() selector used with #tHead.
success: function(obj) {
for(var i = 0; i < obj.data.length; i++) {
$("#tHead").siblings("tr:last").after("<tr>" +
"<td>" + obj.data[i].name1 +
"</td><td>" + obj.data[i].name2 +
"</td><td>" + obj.data[i].name3 +
"</td><td>" + obj.data[i].name4 +
"</td><td>" + obj.data[i].name5 +
"</td></tr>");
}
}
Invert your loop , and it will work as you want
$(document).ready(function()
{
$.ajax(
{
url: "data.json",
dataType: "json",
success: function(obj)
{
for(i=obj.data.length-1;i>=0;i--)
{
$("#tHead").after("<tr>" +
"<td>" + obj.data[i].name1 +
"</td><td>" + obj.data[i].name2 +
"</td><td>" + obj.data[i].name3 +
"</td><td>" + obj.data[i].name4 +
"</td><td>" + obj.data[i].name5 +
"</td></tr>");
}
}
});
});
Something like this maybe:
$(document).ready(function(){
$.ajax({
url: "data.json",
dataType: "json",
success: function(obj) {
$("#tHead").append("<tr>");//----------- open new row.
obj.forEach(function(row) {
$("#tHead").append("<td>");
$("#tHead").append(row);//---------- actual info.
$("#tHead").append("</td>");
});
$("#tHead").append("</tr>");//---------- close new row.
}
}
});
});
An excellent read can be found here : https://stackoverflow.com/a/9329476/2645091
on the different ways to iterate arrays.

Asynchronously remove JSON object from screen

I'm trying to create a single-page app that pulls information from a JSON file, displays it on the screen, and perform a few actions.
Right now, I have all of the information being displayed on the screen properly: http://jsfiddle.net/rcsayf7t/3/
I need the "Remove" button to asynchronously remove the JSON object from the screen when it's clicked, but unfortunately have no idea how to go about accomplishing it.
HTML:
<table>
<thead>
<tr>
<th scope="col"></th>
<th scope="col">Name</th>
<th scope="col">Message</th>
<th scope="col">Date</th>
<th scope="col"></th>
</tr>
</thead>
<tbody class="tweets-result"></tbody>
</table>
jQuery:
// helper function for formatting date
function formatDate(date) {
var dateSplit = date.split(" ");
var displayDate = dateSplit[0] + ", " + dateSplit[1] + " " + dateSplit[2];
// return the result
return displayDate;
}
$(document).ready(function () {
// start ajax request
$.ajax({
url: "https://gist.githubusercontent.com/arlodesign/7d80edb6e801e92c977a/raw/24605c9e5de897f7877b9ab72af13e5b5a2e25eb/tweets.json",
dataType: "text",
success: function (data) {
// store the JSON data
var tweetData = $.parseJSON(data);
// loop through json values and build the table
$.each(tweetData.tweets, function (index, item) {
$('.tweets-result').append(
'<tr>' +
'<td><img src="' + item.profile_image_url + '" alt="#' + item.screen_name + ' avatar"></td>' +
'<td>#' + item.screen_name + '</td>' +
'<td>' + item.text + '</td>' +
'<td>' + formatDate(item.created_at) + '</td>' +
'<td>Remove</td>' +
'</tr>');
// WHEN YOU CLICK "REMOVE", THE TWEET SHOULD
// ASYNCHRONOUSLY BE REMOVED FROM THE SCREEN
});
}
});
});
Live demo
Just add the following inside ajax success:
$('.remove_row').click(function(){
$(this).closest('tr').remove();
});
and the following code as remove attribute:
class="remove_row"
Full JS (read my comments):
// helper function for formatting date
function formatDate(date) {
var dateSplit = date.split(" ");
var displayDate = dateSplit[0] + ", " + dateSplit[1] + " " + dateSplit[2];
// return the result
return displayDate;
}
$(document).ready(function () {
// start ajax request
$.ajax({
url: "https://gist.githubusercontent.com/arlodesign/7d80edb6e801e92c977a/raw/24605c9e5de897f7877b9ab72af13e5b5a2e25eb/tweets.json",
dataType: "text",
success: function (data) {
// store the JSON data
var tweetData = $.parseJSON(data);
// loop through json values and build the table
$.each(tweetData.tweets, function (index, item) {
$('.tweets-result').append(
'<tr>' +
'<td><img src="' + item.profile_image_url + '" alt="#' + item.screen_name + ' avatar"></td>' +
'<td>#' + item.screen_name + '</td>' +
'<td>' + item.text + '</td>' +
'<td>' + formatDate(item.created_at) + '</td>' +
'<td class="remove_row">Remove</td>' + // ## Here add the class remove_row
'</tr>');
// WHEN YOU CLICK "REMOVE", THE TWEET SHOULD
// ASYNCHRONOUSLY BE REMOVED FROM THE SCREEN
});
//## Here assign the even on click for the remove button
$('.remove_row').click(function(){
$(this).closest('tr').remove();
});
}
});
});

On initial select change, jquery does not update/render html in the view

My view seems to be one step behind after a select change. I have a select/dropdown list that is populated with a getJSON request. After an initial selection, I verified in fiddler that the request was successful, but my view does not update. The crazy thing is that when I make another selection, thereafter, the view is then updated with the previous data, and continues on in this fashion. What am I missing?
Here is my HTML:
<div id="ClientSection">
<p>
#Html.Label("clientId", "Client")
#Html.DropDownListFor(x => x.PrimaryClient, Enumerable.Empty<SelectListItem>(),
"Choose Client", new {id = "clientId"})
</p>
<table id="clientLocationsTable">
<thead>
<tr>
<th>Region</th>
<th>Location</th>
<th>Address</th>
<th>Suite</th>
<th>City</th>
<th>State</th>
<th>Zip Code</th>
<th>Phone #</th>
<th>Email</th>
<th>Contact</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
And my JavaScript:
#section scripts
{
<script>
$(document).ready(function () {
// populate main client dropdown
$(function() {
$.getJSON("/api/client/getclients/", function(data) {
$.each(data, function (index, clientObj) {
$("#clientId").append(
$("<option/>").attr("value", clientObj.Id)
.text(clientObj.CompanyName)
);
});
});
});
// create new array
var otherClientLocations = new Array();
$("#clientId").change(function () {
// clear table body
$("#clientLocationsTable > tbody").empty();
// create new array
var clientList = new Array();
// set the id
var primaryId = $("#clientId").val();
$.getJSON("/api/client/getclientotherlocations/" + primaryId, function (data) {
// populate otherClientLocations Array
$.each(data, function(key, val) {
clientList.push(val);
});
otherClientLocations = clientList;
});
// create rows if needed
if(otherClientLocations.length > 0) {
$.each(otherClientLocations, function(key, val) {
$("#clientLocationsTable tbody")
.append("<tr><td>" + val.CompanyRegion +
"</td><td>" + val.CompanyLocationCode + "</td>"
+ "<td>" + val.CompanyAddress + "</td>" + "<td>" +
val.CompanySuite + "</td><td>" + val.CompanyCity +
"</td><td>" + val.CompanyState + "</td><td>" +
val.CompanyZipCode + "</td><td>" + val.CompanyPhoneNumber
+ "</td><td>" + val.CompanyEmail + "</td><td>" +
val.CompanyContactFn + " " + val.CompanyContactLn +
"</td>" + "</tr>");
});
}
});
});
</script>
}
You're not accounting for the fact that the json is being fetched asynchronously. You update the dom before the json has been returned from the server.
Try:
$(document).ready(function () {
// populate main client dropdown
$(function() {
$.getJSON("/api/client/getclients/", function(data) {
$.each(data, function (index, clientObj) {
$("#clientId").append(
$("<option/>").attr("value", clientObj.Id)
.text(clientObj.CompanyName)
);
});
});
});
// create new array
var otherClientLocations = new Array();
$("#clientId").change(function () {
// clear table body
$("#clientLocationsTable > tbody").empty();
// create new array
var clientList = new Array();
// set the id
var primaryId = $("#clientId").val();
$.getJSON("/api/client/getclientotherlocations/" + primaryId, function (data) {
// populate otherClientLocations Array
$.each(data, function(key, val) {
clientList.push(val);
});
otherClientLocations = clientList;
// create rows if needed (the section below has now been moved inside the callback
if(otherClientLocations.length > 0) {
$.each(otherClientLocations, function(key, val) {
$("#clientLocationsTable tbody")
.append("<tr><td>" + val.CompanyRegion +
"</td><td>" + val.CompanyLocationCode + "</td>"
+ "<td>" + val.CompanyAddress + "</td>" + "<td>" +
val.CompanySuite + "</td><td>" + val.CompanyCity +
"</td><td>" + val.CompanyState + "</td><td>" +
val.CompanyZipCode + "</td><td>" + val.CompanyPhoneNumber
+ "</td><td>" + val.CompanyEmail + "</td><td>" +
val.CompanyContactFn + " " + val.CompanyContactLn +
"</td>" + "</tr>");
});
}
});
});
});
Clarification: While the http request is underway, javascript execution continues concurrently. Your version went something like this:
$.getJSON("/api/client/getclientotherlocations/" + primaryId, function (data) {
// update array AFTER request is complete
});
// update dom based on value of array while request is still in progress
I've moved some brackets around so that now it is:
$.getJSON("/api/client/getclientotherlocations/" + primaryId, function (data) {
// update array AFTER request is complete
// then update dom based on new version of array
});

Update div html and content with ajax

I would yo have a functionality similar to the StackExchange link on the top left of the Stack Overflow site.
As I understand it, after the stack exchange link is clicked, the following things happen:
the hidden div container is shown.
this div is populated with its html and the actual data using ajax (maybe jquery)
I've noticed that the html and data does not appear in the page markup, so I think it is probably fetched using javascript/jquery/ajax.
one note - I'm using asp.net mvc 2 and linq-to-sql.
Please give me examples on how this can be acheived, or maybe links to similar examples,
thanks.
You can achieve this with jQuery and page methods in the code behind.
//Gets the list of requests
function getRequestList() {
// call server-side webmethod using jQuery
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Index.aspx/GetOrdersForApproving",
data: "{ }", // send an empty object for calls with no parameters
dataType: "json",
success: displayRequests,
failure: reportError
});
}
//displays the requests in the ul
function displayRequests(result) {
// ASP.NET encapsulates JSON responses in a property "d"
if (result.hasOwnProperty("d")) { result = result.d; }
// iterate through player list and add info to the markup
var ul = $("#requestsForApproval");
for (i = 0; i < result.length; i++) {
var li = $("<li class='approvalListItem'><div>"
+ "<h3>" + result[i].OrderID + " - " + result[i].Supplier + "</h3>"
+ "</div>"
+ "<div>"
+ result[i].Description
+ "</div>"
+ "<div> "
+ "<table width='100%'>"
+ "<tr>"
+ "<td>"
+ "Quant: " + result[i].Quantity
+ "</td>"
+ "<td>"
+ "Price: " + result[i].UnitPrice
+ "</td>"
+ "<td>"
+ "Total: " + result[i].Value
+ "</td>"
+ "</tr>"
+ "</table>"
+ "</div>"
+ " <div class='approvalButtons' style='display:none'>"
+ "<ul><li class='approveButton'>Approve</li>"
+ "<li class='rejectButton'>Reject</li></ul>"
+ "</div>"
+ "<input type='hidden' class='hiddenID' name='OrderLineID' value='" + result[i].OrderLineID + "'>"
+ "</li>");
ul.append(li);
}
Code Behind:
/// <summary>
/// Gets a list of Request Lines
/// </summary>
/// <returns>List of order lines</returns>
[WebMethod]
public static List<iOrderLine> GetOrdersForApproving()
{
try
{
List<iOrderLine> Lines = new List<iOrderLine>();
foreach (Objects.Database.OrderLine oOrderLine in Objects.Database.OrderLine.GetLinesWaitingFor(StaticStore.CurrentUser.UserID, int.MinValue))
{
Lines.Add(new iOrderLine(oOrderLine));
}
return Lines;
}
catch (Exception)
{
throw;
}

Categories