Asynchronously remove JSON object from screen - javascript

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();
});
}
});
});

Related

unexpected end of input error while passing json data from a JS each loop to a JS function

I have a jquery foreach appended list in a table. What I want is to pass the full object that I am getting from an ajax success function. But when I try to pass the Object as a parameter to a different JS function, the parameter gets unexpected end of input.
This is my appended table:
$.ajax({
type: "post",
url: "#Url.Content("~/Estimate/GetOffsetLetterHeadCost")",
data: $('#OffLetterHeadForm').serialize(),
datatype: "json",
traditional: true,
success: function(data) {
var Json = data;
$.each(Json, function(index, obj) {
var row = '<tr>' + '<td><b>' + obj.VendorName + '</b></td>'
+ '<td><label id="machineId' + index + '">'
+ obj.MachineName + ' </label></td>'
+ '<td><input type="button" value="Order" id="btn'
+ index + '"onclick="SaveOffsetOrder('
+ JSON.stringify(obj) + ')"/></td></tr>';
$("#AllVendorsList").append(row);
});
}
});
<table id="AllVendorsList"></table>
function SaveOffsetOrder(obj) {
// do something with obj
}
At input close I am getting unexpexted end of input. Please help. I am new to javascript
enter image description here
Problem is that JSON.stringify(obj) doesn't escape quotes like this \" and the result is invalid html.
I suggest using jQuery onclick binding, so you don't have to stringify obj and then parse it.
Solution: https://jsfiddle.net/xpvt214o/452188/
var Json = [{
VendorName: 'kia',
MachineName: 'ceed'
}, {
VendorName: 'dacia',
MachineName: 'logan'
}];
$.each(Json, function(index, obj) {
var row = '<tr>' + '<td> <b>' + obj.VendorName + '</b></td>' + '<td><label id="machineId' + index + '">' + obj.MachineName + '</label></td>' + '<td><input type="button" value="Order" id="btn' + index + '"/></td></tr >';
$("#AllVendorsList").append(row);
$("#btn" + index).on('click', $.proxy(SaveOffsetOrder, this, obj));
});
function SaveOffsetOrder(obj) {
console.info(obj);
}
<table id="AllVendorsList"></table>
there are a lot of syntax problem. First of all, It's not clear where you have putted your js functions. If it's an .html file, your code should be:
<table id="AllVendorsList"></table>
<script type="text/javascript">
$.ajax({
type: "post",
url: "#Url.Content("~/Estimate/GetOffsetLetterHeadCost
")",
data: $('#OffLetterHeadForm').serialize(),
datatype: "json",
traditional: true,
success: function(data) {
var Json = data;
$.each(Json, function(index, obj) {
var row = '<tr>' + '<td> <b>' + obj.VendorName + '</b> </td> ' +
'<td><label id="machineId' + index + '">' + obj.MachineName + '
< / label > < /td > ' + '<td> <input type="button" value="Order"
id="btn' + index + '"onclick ="SaveOffsetOrder(' +
JSON.stringify(obj) + ')" / > < /td></tr > ';
$("#AllVendorsList").append(row);
});
}
});
function SaveOffsetOrder(obj) {
// do something with obj
}
</script>
So your error is related to syntax problems.

Ajax keeps rewriting html

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);
}
});
});
});

Why javascript actionlink function under ajax not work in mvc

Under an ajax get method i need to generate table programatically.why actionlink not work with my table
ajax method
$(document).ready(function () {
//click event
$('.delete-logo').on('click', function () {
var id = $(this).data('key');
alert(id);
});
//click event
$('.edit-logo').on('click', function () {
var id = $(this).data('key');
alert(id);
});
$('.submitDetailForm').on('click', function () {
//get value from control
var ProductID = $('#ProductID').val();
var Qty = $('#Qty').val();
var Unit = $('#Unit').val();
var Amount = $('#Amount').val();
var ICMS = $('#ICMS').val();
var IPI = $('#IPI').val();
var ProductName = $('#ProductID option:selected').text();
var booksDiv = $("#booksDiv");
$.ajax({
cache: false,
type: "GET",
url: '#Url.Action("AddToCard", "Sales")',
data: { ProductID: ProductID, ProductName: ProductName, Qty: Qty, Unit: Unit, Amount: Amount, ICMS: ICMS, IPI: IPI },
success: function (data) {
console.log(data);
var result = "";
booksDiv.html('');
$.each(data, function (SalesOrderID, OrderDetails) {
result += '<tr> <td>' + OrderDetails.Name + '</td>' +
'<td>' + OrderDetails.Qty + '</td>' +
'<td>' + OrderDetails.Unit + '</td>' +
'<td>' + OrderDetails.Amount + '</td>' +
'<td>' + OrderDetails.ICMS + '</td>' +
'<td>' + OrderDetails.IPI + '</td>' +
'<td><a class="edit-logo" data-key=' + OrderDetails.SalesOrderDetailID + ' href="javascript:void(0);">' + 'Edit' + '</a></td>' +
'<td><a class="delete-logo" data-key=' + OrderDetails.SalesOrderDetailID + ' href="javascript:void(0);">' + 'Delete' + '</a></td>' +
' </tr>';
});
booksDiv.html(result);
},
error: function (xhr, AJAXOptions, thrownError) {
alert('Failed to retrieve books.');
}
});
});
});
Hyper link content
'<td><a class="edit-logo" data-key=' + OrderDetails.SalesOrderDetailID + ' href="javascript:void(0);">' + 'Edit' + '</a></td>'
'<td><a class="delete-logo" data-key=' + OrderDetails.SalesOrderDetailID + ' href="javascript:void(0);">' + 'Delete' + '</a></td>'
hyperlink display perfectly in browser but can not invoke click events
why my actionlink click event are not fired?
You need to use event delegation (using the .on() function) when adding dynamic content
$('#booksDiv').on('click', '.delete-logo', function() {
....
});
$('#booksDiv').on('click', '.edit-logo', function() {
....
});
where the element with id="booksDiv" is the closest ancestor that exists when the page is first generated.
Side note: Rather than manually generating your javascript object, you can simply use data: $('form').serialize(),

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 table row with animation upon AJAX request

I'm creating a 'live' leaderboard table. Every X seconds, an AJAX request is sent to the server to load the latest leaderboard data.
If there's a change in data, the leaderboard will instantly update upon the AJAX request.
However - If there IS a change, instead of instantly showing the new data, I want to animate the table row to its new position instead of instantly reloading it. What is the best way of achieving something like this?
I'm updating the leaderboard at the moment like so:
$(document).ready(function() {
showLeaderboard();
if (autoUpdate != false) {
window.setInterval(function(){
$('#wrapper h2, #leaderboard tbody tr').remove(updateLeaderboard());
}, reloadInterval);
}
});
function updateLeaderboard() {
leaderBoardType;
numRecords;
quizIDs;
topListTitle;
latestTitle;
$.webMethod({
url: 'xxx',
data: '{quizIDs:"'+quizIDs+'",numRecords:"'+numRecords+'"}',
type: 'POST',
cache: false,
beforeSend: function () {
$('body').append('<div class="loading"></div>');
},
success: function (ret)
{
$('.loading').remove();
$('#wrapper').prepend(topListTitle);
$.each(ret.leaderboard,function(i){
pos = i + 1;
str = '<td class="position">' + pos + '</td>';
str += '<td class="name">' + ret.leaderboard[i].first_name + ' ' + ret.leaderboard[i].last_name + '</td>';
str += '<td class="time">' + getTime(ret.leaderboard[i].time_taken) + '</td>';
str += '<td class="points">' + ret.leaderboard[i].points + '</td>';
//str += '<td>' + ret.leaderboard[i].last_name + '</td>';
//str += '<td>' + ret.leaderboard[i].incorrect_attempts + '</td>';
//str += '<td>' + ret.leaderboard[i].user_id + '</td>';
$('#leaderboard tbody').append('<tr>'+str+'</tr>');
});
},
error: function (response) { alert(response.responseText); }
});
}
HTML
<table id="leaderboard">
<thead>
<tr>
<th class="position">Position</th>
<th class="name">Name</th>
<th class="time">Time Taken</th>
<th class="points">Points</th>
</tr>
</thead>
<tbody>
</tbody>
</table>

Categories