Json object doubles on each return - javascript

Each time data returns from the PHP file, it seems like the json object are doubled is some way!? When I run the script for the first time I get 5 rows which is the same amount of rows in the table. But the second time, I get the result twice! What have I done wrong in my script?
function readData() {
$.ajax({
url: "read.php",
type: "POST",
dataType: "json",
data: {
input: 1
},
cache: false,
success: function(data) {
var html = "";
for (i = 0; i < data.length; i++) {
html += "<tr><td>" + data[i].text + "</td></tr>";
}
$(".contentList table").append(html);
},
});
}

Try changing
$(".contentList table").append(html);
to
$(".contentList table").html(html);
.append() will just append more results to the end of the content inside the tag, while .html() will completely replace the content.

Related

How to save the data into database in jquery and display upon the screen using web api

I want to add the values inot the database but I am not to able to do that.
var Array;
$(document).ready(function ()
{
$.ajax({
url: '../api/Emp/GetAll',
type: 'Get',
cache: false,
datatype: 'json',
success: function (text) {
Array = text.Table;
var List = JSON.stringify(text);
for (var i = 0; i < data.length; i++) {
var Id = Array[i].id;
var Name =Array[i].name;
var city = Array[i].city;
$('#table body').append('<tr><td>' + Id + '</td><td><input type="text" value="' + Name + '" id="txt' + Id + '" /></td><td>' + city + '</td> </tr>');
}
}
})
If you need to put it back into the database you just need to reverse the process.
Use post for your type and send the data back with ajax to a php script page that inserts the data into your database.
You can edit the data on the php page before you insert it into the database or you can edit the data with javascript then send it back to php page.
Create an ajax post
$.ajax({
type: "post",
datatype: "json",
url: "insertPage.php",
data: {dataNameHere: editedDataGoesHere},
success: function(data){
alert("SUCCESS");
},
error: function(e){
alert("ERROR");
}
});
And then in your PHP:
$obj = $_POST['dataNameHere'];
and insert it into your database like you normally would.

jQuery reading multiple XML files and remove duplicates when inserting into HTML for Display

I have a total of 4 XML files in same format representing 4 different categories of project contents. However some projects does have more than 1 category.
I want to merge all 4 XML files using jQuery and display all projects contents in a single page within a , but due to the fact that some projects have more than 1 category, the displayed results show duplicates of project contents.
How do I remove duplicates within the combined extracted XML files?
Here is my jQuery Code:
XMLLIST = {
//general settings
xml1: 'xml/structural_steel.xml?' + Math.random(0,1), //solve ie weird caching issue
xml2: 'xml/building_work_id.xml?' + Math.random(0,1), //solve ie weird caching issue
xml3: 'xml/shear_stud_welding.xml?' + Math.random(0,1), //solve ie weird caching issue
xml4: 'xml/custom_solution.xml?' + Math.random(0,1), //solve ie weird caching issue
appendTo: '#list', //set the id/class to insert XML data
init: function () {
//jQuery ajax call to retrieve the XML file
$.ajax({
type: "GET",
url: XMLLIST.xml1,
dataType: "xml",
success: XMLLIST.parseXML
});
$.ajax({
type: "GET",
url: XMLLIST.xml2,
dataType: "xml",
success: XMLLIST.parseXML
});
$.ajax({
type: "GET",
url: XMLLIST.xml3,
dataType: "xml",
success: XMLLIST.parseXML
});
$.ajax({
type: "GET",
url: XMLLIST.xml4,
dataType: "xml",
success: XMLLIST.parseXML
});
}, // end: init()
parseXML: function (xml) {
//Grab every single ITEM tags in the XML file
var data;
data = $('item', xml).get();
var i = 1;
//Loop through all the ITEMs
$(data).each(function () {
//Parse data and embed it with HTML
XMLLIST.insertHTML($(this));
i++;
});
}, // end: parseXML()
insertHTML: function (item) {
//retrieve each of the data field from ITEM
var url = item.find('url').text();
var image = item.find('image').text();
var title = item.find('title').text();
var html;
//Embed them into HTML code
html = '<div class="item">';
html += '<img src="' + image + '"><br>';
html += '<span class="contentsubtitle">' + title + '</span><br><br>';
html += '</div>';
//Append it to user predefined element
$(html).appendTo(XMLLIST.appendTo);
}, // end: insertHTML()
}
//Run this script
XMLLIST.init();
I hope my code is correct. Had no data to test with, but I think the idea of it should be a bit more clear.
edited: Now working, version after receiving xml test-data
<html>
<head>
<title>asdasd</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
</head>
<body>
<div id="list">
</div>
<script>
XMLLIST = {
dataToLoad: [
'test.xml'
],
loadedData: [],
appendTo: '#list',
rand: function() {
return new Date().getTime();
},
loadData: function(file) {
$.ajax({
type: "GET",
url: file + "?" + XMLLIST.rand(),
dataType: "xml",
success: XMLLIST.parseXML,
error: function(r) {
console.error(r);
}
});
},
init: function () {
XMLLIST.dataToLoad.forEach(function(file) {
XMLLIST.loadData(file);
});
},
parseXML: function (xml) {
var data = $('item', xml).get();
$(data).each(function (i, value) {
var $value = $(value),
item = {
url: $value.find('url').text(),
image: $value.find('image').text(),
title: $value.find('title').text()
};
if (!XMLLIST.itemIsInList(item)) {
XMLLIST.loadedData.push(item);
XMLLIST.insertHTML(item);
}
});
},
itemIsInList: function(item) {
var hits = XMLLIST.loadedData.filter(function(value){
return XMLLIST.compareItem(item, value);
});
return hits.length > 0
},
compareItem: function(item1, item2) {
return item1.url === item2.url && item1.image === item2.image && item1.title === item2.title;
},
insertHTML: function (item) {
var html = '<div class="item">';
html += '<img src="' + item.image + '"><br>';
html += '<span class="contentsubtitle">' + item.title + '</span><br><br>';
html += '</div>';
$(html).appendTo(XMLLIST.appendTo);
}
};
XMLLIST.init();
</script>
</body>
</html>
You have a list, where you push your objects to. This list has a checkFunction "itemIsInList". Additionally you need a seperate check-function "compareItem", because indexOf won't work with objects
Managed to modify my original script by adding a masterArr for comparison of duplicated data received accross the 4 XMLs.
Here's the codes:
XMLLIST = {
//general settings
xml1: 'xml/structural_steel.xml?' + Math.random(0,1), //solve ie weird caching issue
xml2: 'xml/building_work_id.xml?' + Math.random(0,1), //solve ie weird caching issue
xml3: 'xml/shear_stud_welding.xml?' + Math.random(0,1), //solve ie weird caching issue
xml4: 'xml/custom_solution.xml?' + Math.random(0,1), //solve ie weird caching issue
appendTo: '#list', //set the id/class to insert XML data
//end general settings
masterArr: [],
init: function () {
//jQuery ajax call to retrieve the XML file
$.ajax({
type: "GET",
url: XMLLIST.xml1,
dataType: "xml",
success: XMLLIST.parseXML
});
$.ajax({
type: "GET",
url: XMLLIST.xml2,
dataType: "xml",
success: XMLLIST.parseXML
});
$.ajax({
type: "GET",
url: XMLLIST.xml3,
dataType: "xml",
success: XMLLIST.parseXML
});
$.ajax({
type: "GET",
url: XMLLIST.xml4,
dataType: "xml",
success: XMLLIST.parseXML
});
}, // end: init()
parseXML: function (xml) {
//Grab every single ITEM tags in the XML file
var data;
data = $('item', xml).get();
var i = 1;
//Loop through all the ITEMs
$(data).each(function () {
//Check if masterArr[] already contains a duplicate of the item by checking using the XML label <image> or any other value/label that is unique.
//Insert into masterArr[] if not duplicate and publish HTML if not duplicate.
var string1 = $(this).find('image').text();
if( jQuery.inArray(string1, XMLLIST.masterArr) == -1){
XMLLIST.masterArr.push(string1);
//Parse data and embed it with HTML
XMLLIST.insertHTML($(this));
};
//If it reached user predefined total of display item, stop the loop, job done.
//if (i == XMLLIST.display) return false;
i++;
});
}, // end: parseXML()
insertHTML: function (item) {
//retrieve each of the data field from ITEM
var url = item.find('url').text();
var image = item.find('image').text();
var title = item.find('title').text();
var html;
//Embed them into HTML code
html = '<div class="item">';
html += '<img src="' + image + '"><br>';
html += '<span class="contentsubtitle">' + title + '</span><br><br>';
html += '</div>';
//Append it to user predefined element
$(html).appendTo(XMLLIST.appendTo);
}, // end: insertHTML()
}
//Run this script
XMLLIST.init();

how to count total number of ajax response data sets inside for loop?

i am calling an ajax and output api response in textbox. I want count total number of data sets received(counteri) and display it each time i click a button. For example if i click the button first time i want to an alert display counteri=20 and next time i click button it display counteri=40 and... counteri=60.
Currently my code keeps showing 20 each time and not adding the values. could any one tell me how to fix this.Thanks
<script>
var maxnumId = null;
var counteri= null;
function callApi() {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: "https://api.somesite.com/......"),
success: function(data) {
maxnumId = data.pagination.next_num_id;
for (var i = 0; i < 100; i++) {
$(".galaxy").append("<div class='galaxy-placeholder'><a target='_blank' href='" + data.data[i].link +"'><img class='galaxy-image' src='" + ok.images.standard_resolution.url +"' /></a></div>");
document.myform.outputtext.value = document.myform.outputtext.value+data.data[i].images.ok.url+'\n' ;
//alert('www!'+i);
counteri=i;
}
}
});
counteri=counteri+counteri;
alert('counteri is now: ' + counteri);
}
</script>
<body>
<br>
<center>
<div id="myDiv"></div>
<div class="galaxy"></div>
<button id="mango" onclick="callApi()">Load More</button>
</html>
EDIT:
Adding this in start of success added up total number of records from ajax response
var num_records = Object.keys(data.data).length;
num_records2=num_records2+num_records;
alert('number of records:'+ num_records2);
and
var num_records2 =null; // outside function
Ajax are async calls.
Move the alert to just after the for. Not outside the success callback.
Looks like the problem is that you are setting counteri to the value of i instead of adding the value of i. Try this instead:
counteri += i;
Ajax calls are asynchronous. You should increment your counter on success, not outside of the ajax call. Something like this:
function callApi() {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: "https://api.somesite.com/......",
success: function(data) {
maxnumId = data.pagination.next_num_id;
for (var i = 0; i < 100; i++) {
document.myform.outputtext.value = document.myform.outputtext.value+data.data[i].images.ok.url+'\n' ;
}
counteri=counteri+i;
alert('counteri is now: ' + counteri);
}
});
}
Considering that your ajax request is executed with success, to get what you want you need to declare the i variable before for ( ....) loop as is the follow script:
var counteri = 0;
function callApi() {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: "https://api.somesite.com/......",
success: function(data) {
var i,
maxnumId = data.pagination.next_num_id;
for (i = 0; i < 100; i++) {
document.myform.outputtext.value = document.myform.outputtext.value+data.data[i].images.ok.url+'\n' ;
}
counteri=counteri+i;
alert('counteri is now: ' + counteri);
}
});
}
Please ses here demo
EDIT
Also i have rechecked if the variable i is not declared before for(...) loop and works OK. So, the only fix is to remove counter=i from for(...) loop and to change the counteri=counteri+counteri; to counteri+=i;
Take in consideration that the ajax requests produce a number of different events that you can subscribe to. Depending of your needs you can combine this events to accomplish the desired behavior. The complete list of ajax events is explained here
EDIT2
After reading your comments, i see that you need the last value of i globally,
you need to add a second global variable too keep the sum of last i during all ajax requests.
To do this, id have added a minor change to answer:
var counteri = 0,
totali =0;
function callApi() {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: "https://api.somesite.com/......",
success: function(data) {
var i,
maxnumId = data.pagination.next_num_id;
for (i = 0; i < 100; i++) {
document.myform.outputtext.value = document.myform.outputtext.value+data.data[i].images.ok.url+'\n' ;
}
counteri = i;
totali = totali + i;
alert('totali is now: ' + totali );
}
});
}
JSFiddle demo
EDIT 3
After your last comment, you need to add in the API response the number of returned rows. For this, you need to change for (i = 0; i < 100; i++) { to something like this:
var num_records = data.num_rows;
for (i = 0; i < num_records ; i++) {
or, without adding the number of rows in response
var num_records = Object.keys(data.data).length;
for (i = 0; i < num_records ; i++) {

loop ajax calls to fill multiple divs

I've got two divs on my page
<div id="1"></div>
<div id="2"></div>
That I'm trying to dynamically fill with the following php call.
<script>
var queries = ["SELECT * from table1", "SELECT * from table2"]
for (var i = 0; i < queries.length; i++) {
$.ajax({
url: "querySQL.php",
type: "GET",
cache: false,
data: {query: queries[i]},
success: function(data) {
$("#" + i).html(data);
}
});
}
</script>
It looks like it's looping through the queries properly, however it 'erases' the first one and when I view the page, only the results of the second query remain. What am I doing wrong?
Notwithstanding the warnings about exposing a raw SQL interface in your API, the problem you have is that i in the callback once the AJAX call completes doesn't have the same value it did when you initiated the call.
The easiest solution is to use $.each or Array#forEach instead of a for loop, and use the index parameter that is then correctly bound to the current value in the callback:
$.each(queries, function(i, query) {
$.ajax({
url: "querySQL.php",
type: "GET",
cache: false,
data: { query: query },
success: function(data) {
$("#" + (i + 1)).html(data); // NB: i starts at 0, not 1
}
});
});
This will work
var queries = ["SELECT * from table1", "SELECT * from table2"];
function callAjax(i){
$.ajax({
url: "querySQL.php",
type: "GET",
cache: false,
data: {query: queries[i]},
success: function(data) {
console.log(i)
$("#" + (i+1).html(data);
}
});
}
for (var i = 0; i < queries.length; i++) {
callAjax(i)
}
It looks that you have only 2 results. The problem here is your var i. it starts with i=0 and ends in i=1. So only div $("#" + 0).html(data) and $("#" + 1).html(data).
To fix this start with
i=1; i <= queries.length; i++
i guess you need to send only one request on page load.And in your php file that is ajax url,you need to execute the both queries one by one and then populate data in the div in the same file.and just return all data.On ajax success,you just populate a div with returned data.
I would set the datatype to application/json, so the answer can be a json object, not only text/html. I would return the following parameters from the php as a json via json_encode, something like this:
{firstResult:{divToUse: "#1", dataToFill: "#1 content"},
secondResult:{divToUse: "#2", dataToFill: "#2 content"},
....
}
I hope it helps.

Text Area interfering with Ajax Code

I am just trying to clear the text area with an id of "discussion" it clears the textbox but it does not load the data from the server with the ajax statement. When I remove the line that clears that text area it loads all the data in fine but just adds to the current data.
Here is my code:
function LoadRoomMessages(id)
{
$.ajax(
{
type: "Get",
url: "#Url.Action("GetMessages", "Home")",
data: { roomId: id },
success: function (data)
{
// Here is the line that causes issues.
$('#discussion').val('');
json = data;
var obj = JSON.parse(json);
for (var i = 0; i < data.length; i++)
{
$('#discussion').append(htmlEncode(obj[i].Author) + " : " + htmlEncode(obj[i].Message) + "\r\n");
}
}
});
}
You may also try (as you asked to answer it)
$('#discussion').empty();

Categories