Manipulating JSON arrays with jquery - php

I'm printing a <ul> of array $_SESSION['words'] in PHP.
// PHP print new words as links
echo '<ul id="wordlist">';
foreach($_SESSION['words'] as $word => $description) {
echo '<li id="wordlist">' . $word . '</li>';
}
The array is simple - words are stored as keys and the descriptions for words will be values, e.g.
array(5) { ["word1"]=> int(1) ["word2"]=> int(2) ["word3"]=> int(3) ["word4"]=> int(4) ["word5"]=> int(5) }
I plan to manipulate items in the array by selecting a $word and adding a $description and adding it to the array, so I'm thinking I'll use jQuery to do it.
My question is: if I create a JSON array from this PHP array, can I print it out in the same way and manipulate it? I encoded it with $myJSON = json_encode($_SESSION['words']); but I'm already stuck attempting to print out the keys/values from the JSON! Thanks...

You can use $.parseJSON:
var json = $.parseJSON('your json');
alert(json.word1);
alert(json.word2);
If your JSON data is available via a URL, you can use $.getJSON

You description indicates to me that you are not using JSON in any way, other than to use PHP's JSON encoding function. It sounds like you are encoding your PHP associative array into a JSON string and then writing that string into your HTML output. If this is the case, then your JSON is really a JavaScript object.
So let's assume your resulting markup is this:
<script>
// Using a global here, which is not good,
// but this is an example.
var myWordList = {"word1":1,"word2":2,"word3":3};
</script>
<ul id="wordlist">
<li id="word1">1</li>
<li id="word2">2</li>
<li id="word3">3</li>
</ul>
Notice that my id attribute values are unique. You used the same id attribute value multiple times; that is invalid markup. Also, I kept the markup in each list element simple for this example (just text).
So, given this markup, we could write the following JavaScript:
<script>
// Update our wordlist object with some descriptions
myWordList.word1 = {
"value": myWordList.word1,
"description": "This is word 1."
};
myWordList.word2 = {
"value": myWordList.word2,
"description": "This is word 2."
};
myWordList.word3 = {
"value": myWordList.word3,
"description": "This is word 3."
};
// Now lets update the unordered list with jQuery
for (var i = 1; i < 4; i += 1) {
$('#word' + i).html(myWordList['word' + i].description);
}
</script>
In this JavaScript, I first update the myWordList values by assigning a new object to each value. These new objects have two properties: a value property that is assigned the old myWordList.word# value, and a new description property that describes the word. Next, I update the unordered list by replacing the word values with the word descriptions.
Edit:
If you want to loop over the properties in the object, you can do this:
for (var key in myWordList) {
if (myWordList.hasOwnProperty(key)) {
console.dir(myWordList[key]);
}
}

if not used to $.each method, may also try old array loop:
$.ajax({
url: '',
dataType: 'json',
success: function(arrayData) {
var i,max=arrayData.length;
for(i=0;i<max;i++){
var rowItem = arrayData[i];
try{
console.log(rowItem.attr1);
}catch(ex){
alert(ex);///in case data is not complete
}
});
}
});
if you already have the JSON string , say strJson = '[{attr1:"hello"},{attr1:"world"}]';
var tmp = 'var data = '+strJson;
///so you got : var data = [{attr1:"hello"},{attr1:"world"}]
eval(tmp);/// execute the above line
alert(data.length + "first item:"+data[0].attr1);

You need to get that JSON via AJAX and the
$.ajax({
url: '',
dataType: 'json',
success: function(response) {
$.each(response, function(key, val) {
console.log(key); // word1, word2, word3...
console.log(val); // 1, 2, 3...
....
});
}
});

Related

appending $.ajax response to Jquery UI dialog box in table format

I am getting data in a php file from db as
while ($row=mysqli_fetch_row($result))
{
printf ("beacon id : %s \n",$row[2]);
printf ("beacon uuid :(%s)\n",$row[3]);
}
now i want to append that data in table and show in JQueryUI Dialog box like this
In ajax success form i tried to create hardcore table and get data
success: function(response){
for (var i = 0; i < 3; i++) {
var row = $('<tr></tr>').appendTo(mytable);
for (var j = 0; j < 3; j++) {
$('<td></td>').text("text1").appendTo(row);
}
}
$('<table></table>').appendTo("#dialog");
$("#dialog").dialog("open");
}
it is working fine
///////////////
when I tried to get to get my data in table its not working
I tried
success: function(response){
var table = $("#table tbody");
$.each(response, function(idx, elem){
table.append("<tr><td>"+elem.id+"</td></tr>");
});
$('<table></table>').appendTo("#dialog");
$("#dialog").dialog("open");
}
but it is not working ,
console.log is coming like
what can i modify to display data ?
You're not appending the table with data, instead you're creating a new empty table element and appending it.
Edit:
You also can't loop over a string (which is the ajax response). If you output the html in php things will be simpler. This is also untested but hopefully you get the idea.
php:
while ($row = mysqli_fetch_row($result)) {
printf("<tr><th>beacon id :<th> <td>%s</td><tr>", $row[2]);
printf("<tr><th>beacon uuid :<th> <td>(%s)</td><tr>", $row[3]);
};
js:
success: function (response) {
if (response) {
var table = $("#table tbody");
table.append(response);
table.appendTo("#dialog");
$("#dialog").dialog("open");
}
}
First, I would adjust your PHP so that it is sending back JSON data. The data you are sending back now is just text. It will not be read as an Object by JS.
PHP
$beacon = array();
while ($row=mysqli_fetch_row($result)){
$beacon[] = array("id" => $row[2], "uuid" => $row[3]);
}
header('Content-type:application/json;charset=utf-8');
echo json_encode($beacon);
See: Returning JSON from a PHP Script
This creates an array of arrays. The resulting page should be something like:
[
{
"id": "Beacon00UUID::fda50693-a4e2-4fb1-afcf-c6eb07647825",
"uuid": "(Beacon00RSSI::-69)"
},
{
"id": "Beacon01UUID::2f234454-f491-1ba9-ffaf-000000000001",
"uuid": "(Beacon01RSSI::-53)"
},
{
"id": "Beacon02UUID::b9407f30-f5f8-466e-aff9-25556b57fe6d",
"uuid": "(Beacon02RSSI::-75)"
},
{
"id": "Beacon04UUID::00000000-0000-0000-0000-000000000000",
"uuid": "(Beacon04RSSI::-88)"
},
]
This will allow your jQuery to collect the content as JSON. In your success callback, you can handle this better. this is also assuming you have dataType: "json" elsewhere in your AJAX call.
jQuery
success: function(response){
var $tbl = $("<table>");
$.each(response, function(key, val){
var $row = $("<tr>").appendTo($tbl);
if(key % 2 == 0){
$row.addClass("even");
} else {
$row.addClass("odd");
}
var $cell = $("<td>").html(val.id).appendTo($row);
});
$("#dialog").html($tbl.prop("outerHTML")).dialog("open");
}
Now, if your data was coming back with a key of beacon id, you would need to call this exactly. For example, it would not be elem.id, it would have to be elem['beacon id'] to call the right index in the object. You can't use the dot notation that includes a space in the index name. Bare that in mind when naming your indexes.
There is a subtle difference with $.each() and .each(), the former is designed for arrays and objects, with a key and value pair and the latter designed for jQuery objects, with an index and element pair. nothing wrong with what you did, just explaining why you might use one over the other.
Hope this helps. Let me know if something is not clear.

Multidimensional PHP array to jQuery - Only seeing one result

I'm trying to use PHP and jQuery to create a dynamic search results page.
On the PHP side, a SELECT statement is called, where I check if all variables are set, add my HTML that I want to be used clientside, then put the variables in an array named $result.
Of the results of the database call, I also add the longitude and latitude in their own array, named $pins.
I then create a multidimensional array called $results, and put the array together like so:
$result = array('listing'=>$listing);
$pins = array('lat'=>$lat1,'lng'=>$lon2);
$results = array('listing'=>$result,'pins'=>$pins);
echo json_encode($results);
Now, clientside I use jquery. The issue I'm facing, is there should be 2 results in total. However I see the same result repeated twice (I can confirm they should be unique). Here is my jQuery:
$.ajax({
url: '/updatedsearch.php',
type: 'POST',
data: {
q: search,
lng: coordinates[0],
lat: coordinates[1],
},
dataType: "json",
success: function(data) {
if(data == "undefined" || data == null) {
console.log("There was no search results or something similar");
} else {
var pins = [data.pins.lat, data.pins.lng];
$.each(data, function(key, val) {
$('#listings').append(data.listing.listing);
console.log(pins);
console.log(data);
});
}
},
Everything here works as it should, apart from when $.each() runs, it appears to be appending the same data twice.
I assume it's because of .append(data.listing.listing);, if I understand correctly I'm not looping through the array here, I'm effectively referencing data.listing.listing[0] - have I understood this correctly?
Edit: I now have an issue with my results appearing twice. There should be only two results, however there are four in total, it appears as though these have been duplicated.
{"listing":["<div>This contains my HTML</div>"], "pins":"lat":"50.000000","lng":"-1.000000"}}
I have run this though jsonlint and it appears invalid. Using PHP I have created this data as follows:
while($listrow = mysqli_fetch_assoc($list)) {
$listing[] = '<div>This contains my HTML</div>';
}
$pins = array("lat"=>$lat1, "lng"=>$lon2);
$results = array('listing'=>$listing, 'pins'=>$pins);
echo json_encode($results);
Have I misunderstood using multidimensional arrays, which is causing the error?
You are correct that you are not looping through the array. You are also not referencing the individual array items when you append.
Try:
$.each(data.listing.listing, function(i, item) {
$('#listings').append(item);
});
When you do the following:
$.each(data, function(key, val) {
You are looping through the properties of the data object. It has two properties: listings and pins, so the loop executes twice.
And for each iteration of the loop, you are appending the same value (data.listing.listing), which I assume is an array.
Instead, I think you want to iterate over the array, and append each item in the array.
EDIT: The PHP you show at the top of your question looks like it would generate JSON like this:
{
"listing": { "listing": ["<div>This contains my HTML</div>"] },
"pins": { "lat":"50.000000","lng":"-1.000000" }
}
But with your edit, you show JSON that looks like this:
{
"listing": ["<div>This contains my HTML</div>"],
"pins": { "lat":"50.000000","lng":"-1.000000" }
}
If that is what your JSON looks like, you should use:
$.each(data.listing, function(i, item) {
jsfiddle
It appears that you intend your $.each to loop through the listings placed in $results['listing'] in your PHP, but it's actually looping over the whole $results.
To better see what's going on, use a different name for the current item in your $.each. Because you use data, the same name you use as the argument of your success callback, you're making the code harder to debug. If you want to cycle through your listings, do the following inside the success callback:
$.each(data.listing, function(i, result)){
$('#listings').append(result);
}
The JSON you posted:
{
"listing":["<div>This contains my HTML</div>"],
"pins": "lat":"50.000000","lng":"-1.000000"}
}
Is invalid because you're missing an opening bracket between "pins": and "lat". It should be
{
"listing":["<div>This contains my HTML</div>"],
"pins": {"lat":"50.000000","lng":"-1.000000"}
}

Update DOM with jQuery ajax array results

I have search results generated by a 3rd party script that I would like to add data to. I have parsed the results to get an array of id's, and queried the database for additional fields. The ajax success method receives the formatted array back, but now I'm stuck on how to get those results into the right place in the DOM.
The HTML:
<div class="ihf-results-property-info">
<div class="ihf-results-price">LIST: $2,150,000</div>
<div class="ihf-results-links"> 24 Photos
</div>
<div class="ihf-results-extra-info">
<div class="ihf-results-listingnum hidden-xs">Listing # 727938</div>
</div>
Repeat...
The last div I included in the example has the unique ID I'm using for the query. I'd like to use that to associate the ajax return with proper placement in the DOM. Here is my javascript:
jQuery(document).ready(function($) {
// grab the listings numbers so we can query the db for extra data
var listings = $('.ihf-results-listingnum').map(function() {
// grab just the digits
var listingNum = $(this).text().replace(/[^0-9]/g, '');
// add the listing number to the parent so we can target it later
$( this ).parents('.ihf-results-extra-info').parent().addClass('marketing-details-' + listingNum);
return listingNum;
// use .get to create an array of the listing numbers
}).get();
$.ajax({
type: "GET",
url: "custom/07-idx-queries.php",
data: 'mlsNums=' + listings, // looks like ?mlsNums=735383,727468,699876...
success: function(result) {
// this logic came from here: http://stackoverflow.com/questions/15311320/how-to-work-with-jquery-ajax-and-php-array-return
resultJson = $.parseJSON(result);
if (typeof resultJson == 'object') {
jsObject = eval(resultJson);
jsArray = [];
for(elem in jsObject){
jsArray.push(jsObject[elem]);
}
console.log(jsArray);
// this works as expected, except keys are 0 based
// This is where it all falls apart. I want to extract each object and stick it in the DOM in the correct place
jQuery.each(jsArray, function(key, value) {
$( this ).appendTo('.marketing-details-' + key);
});
}
else {
console.log("error occurred");
}
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
})
});
And the php I'm using produces the desired results from the db, with the exception that it is a numerical array. I think an associative array would work better when trying to put the results into the DOM, tha way I could use the ID's as the key and match them to the classes I added. Here is the relevant code from custom/07-idx-queries.php:
$mls_nums = explode(",",$_GET['mlsNums']);
// removed all of the conditionals to keep the question clean
$html = array();
foreach ($mls_nums as $mls_num) {
// just retreiving a single object from each row for now
$remarks = $mysqli->query("SELECT mr FROM listings WHERE ln = '$mls_num'")->fetch_object()->mr;
// format the data
$my_html = "<p class='marketing-remarks mlsnum-".$mls_num."'>$remarks</p>";
// build an array of the results - necessary?
array_push($html,$my_html);
}
// send the data back in a JSON string
echo json_encode($html);
So my goal is to query the db for up to 10 rows, and insert the results into an equal number of new divs that are children to a div with the same id number in its class. I greatly appreciate any help.
In your PHP do this:
$html[$mls_num] = $my_html;
// this isn't needed
// array_push($html,$my_html);
Now your returned data has a way to tie into the target div.
Not clear if you have control over the HTML in the first part of your example, but this would be one approach.
<div class="ihf-results-listingnum hidden-xs">Listing # 727938</div>
<div class="remarks" id="remarks_<?= $listingid; ?>"></div>
Then in the JavaScript $("#remarks_" + key).html(value);
Otherwise, you need to use jQuery to locate the div with the listing id using the :contains selector:
$("div:contains('# " + key + "')").appendTo(value);
'# " + key + "' would equate to # 1234 or whatever it is. This won't work if the same listing is on the page twice though!
Okay, here is the working success method. Thanks to LG_PDX for the cleaned up php. I eliminated the unnecessary processing as .each() appears to iterate just fine over the JSON response:
success: function(result) {
resultJson = $.parseJSON(result);
if (typeof resultJson == 'object') {
$.each(resultJson, function(key, value) {
$('.marketing-details-' + key).append( value );
});
}
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}

jQuery Looping JSON Data

I have created APIs to retrieve data from my server and then I get the data with json format like this :
{
"items": [
{
"2013-03-28": 1771,
"2013-03-29": 1585,
"2013-03-30": 1582,
"2013-03-31": 1476,
"2013-04-01": 2070,
"2013-04-02": 2058,
"2013-04-03": 1981,
"2013-04-04": 1857,
"2013-04-05": 1806,
"2013-04-06": 1677,
"2013-04-07": 1654,
"2013-04-08": 2192,
"2013-04-09": 2028,
"2013-04-10": 1974,
"2013-04-11": 1954,
"2013-04-12": 1813,
"2013-04-13": 1503,
"2013-04-14": 1454,
"2013-04-15": 1957,
"2013-04-16": 1395
}
]
}
How do I looping with my json data dynamically using jQuery?
My code :
<html>
<head></head>
<body>
<script src="jquery-1.9.1.js"></script>
<script>
$(document).ready(function() {
$.ajax({
type : "GET",
url: "myurl.php",
cache: false,
dataType: "jsonp",
success:function(data){
if(data==''){
alert('Fail');
}else{
alert('Success');
}
}
})
});
</script>
</body>
</html>
How do I modify my jQuery to get data dynamically following the date that the data will change every day as in the example I wrote above data??
Thanks before...
There are a few things to consider with your example data, but in your case, the following will do the trick:
var importantObject = data.items[0];
for(var item in importantObject ){
var theDate = item;//the KEY
var theNumber = importantObject[item];//the VALUE
}
Here is a working example
But what does all this mean?...
First of all, we need to get the object that we want to work with, this is the list of dates/numbers found between a { } (which means an object) - an array is defined as [ ]. With the example given, this is achieved like so:
var importantObject = data.items[0];
because items is an array, and the object we want is the first item in that array.
Then we can use the foreach technique, which effectively iterates all properties of an object. In this example, the properties are the date values:
for(var item in importantObject ){ ... }
Because we are iterating the properties, item will be the property value (i.e. the date bit), so item is the date value:
var theDate = item;//the KEY
Finally we get the number part. We can access the value of any given object property by using the string value of the property index (relative to the object), like so:
var theNumber = importantObject[item];//the VALUE
If you already know which date you want the value for, then you can access it directly like so:
var myValue = data.items[0]["2013-04-16"];//myValue will be 1395 in this example
Using jQuery.each() loop through the items
$.each(data.items[0], function (key, value) {
console.log(key + ": " + value);
var date = key;
var number = value;
});
DEMO HERE
You can use the jQuery each function to do this. For example like this:
$.each(data, function(k, v) {
// Access items here
});
Where k is the key and v is the value of the item currently processed.
//get your detail info.
var detail = data.items[0];
$.each(detail, function(key, val) {
console.log(key + ": " + val);
}

json_encode creating malformed JSON data?

I have a codeigniter application returns some data from my database to a view. I'm trying to send it back as json data.
The problem is that the data that is returned it malformed.
it looks like this:
({'2.5':"Admin1", '2.10':"Admin2"})
When I test this on jsonlint.com, it shows that this is not valid json.
the '2.5' should be in double quotes, not single quotes.
What I don't understand is that I'm calling json_encode on my data before I pass it to the view. My code in my controller looks like this:
public function getbuildings()
{
$buildings = array();
$branchID = $this->uri->segment(3);
$buildingforbranch = array();
$_locations = $this->racktables_model->get_locations();
//print_r($_locations);
foreach ($_locations as $location)
{
if ((isset($location['L2FullID'])) && (!array_key_exists($location['L2FullID'],$buildings))) {
$buildings[$location['L2FullID']] = $location['L2Location'];
}
}
foreach ($buildings as $key => $value)
{
$pattern = "/(".$branchID."\.\d)/i";
if (preg_match($pattern,$key))
{
$buildingforbranch[(string)$key] = $value;
}
}
header ('Content-Type: application/json; charset=UTF-8');
echo json_encode($buildingforbranch);
}
As you can see from the code, I've even tried casting $key explicitly to a string data type. But that doesn't seem to change anything. Any suggestions?
Thanks.
EDIT 1
When I do a var dump on $buildingforbranch right before the header / json_encode() calls, I get the following results:
array(3) {
["2.5"]=>
string(7) "Admin 2"
["2.10"]=>
string(7) "Admin 1"
["2.11"]=>
string(3) "SB4"
}
It looks good here ... but when I do a console.log() and pass in the data from the controller, the browser shows the incorrectly formed json data.
EDIT 2
Here's what i'm trying to accomplish. I need to dynamically create a combo box when a user clicks on a control on my page. If the ajax call results in an empty array, I don't want to display the combo. Otherwise, I try to populate the combo box with the results of the ajax call. Everything is working, except for the part where I'm attempting to check the length of the json data. My app always displays a combo box regardless of what is sent back.
Here's the code:
$.ajax({
url:"<?php echo site_url('switches/getbuildings/');?>" + "/" + $selectedvalue,
type:'GET',
dataType:'json',
success: function(returnDataFromController) {
console.log("getbuildings ajax call successfull");
var htmlstring;
htmlstring="<select name='L2Locations' id='L2Locations'>";
htmlstring = htmlstring + "<option value='all'>All</option>";
//console.log(returnDataFromController);
var JSONdata=[returnDataFromController];
console.log(JSONdata);
if (JSONdata.length != 0)
{
for(var i=0;i<JSONdata.length;i++){
var obj = JSONdata[i];
for(var key in obj){
var locationkey = key;
var locationname = obj[key];
htmlstring = htmlstring + "<option value='" + locationkey + "'>" + locationname + "</option>";
} //end inner for
$('#l2locations').html(htmlstring);
}//end outer for
}
else {
//alert('i think undefined');
$('#l2locations').html('');
}
}//success
});//end ajax
If I call the page that is returning the json data directly, i get [] as the result for an empty array.
[] is actually defines an array with a single element in your particular case. But as I see you are using jQuery ajax with dataType: "json", this means that the returned value is already an object, you don't need to parse it one more time, so just remove []:
var JSONdata=returnDataFromController; // instead of var JSONdata=[returnDataFromController];
As stated in your other question, you need to handle the JSON as JSON.
Basic overview is:
returnDataFromController will be a string, use JSON.parse() or jQuery's parseJson() to convert it to a JSON object
Rewrite your loop that generates the options to iterate over a JSON object, instead of an array. Note that jquery.each() can handle both arrays and objects will handle This appears to be the part that you're missing . . .
The real key here is keeping datatypes straight. You're getting a string back, that contains JSON data. There's no easy way to convert that to an array, so read it in as JSON. Since it's now a JSON object, you have to treat it as a JSON object, not an array.
Check the jQuery Utilities category for other JSON related items.
Use firebug on firefox to see what is shown in "response" tab on "net" tab
This code
<?php
echo json_encode(array(
"2.5" => "Admin 2",
"2.10" => "Admin 1",
"2.11" => "SB4"
));
produces this output {"2.5":"Admin 2","2.10":"Admin 1","2.11":"SB4"} on my server (php5.3) and on this fiddle example
http://www.phpfiddle.org/main/code/xqy-ize

Categories