Due to the limitations of the deign of a current system, I need to pass data to a select element as json, reset each option in the select object with the 'id' value from the json and populate a second select element with 'sid' data from the json to create a dynamic parent-child pair of select elements.
However I seem to be unable to successfully parse the option value and push it into an array for use in later code.
<select id="Sector">
<option value="{'id':'Fruit','sid':['Apple','Orange']}"></option>
<option value="{'id':'Veg','sid':['Tomato','Carrot']}"></option>
</select>
<script language="JavaScript" type="text/javascript">
var plist = document.getElementById('Sector');
var opts = plist.options;
var x =[];
for(i=0;i<opts.length;i++){
x.push(opts[i].value);
}
alert(x[0]['id']);
</script>
What am I doing wrong ??i
The option values are strings. If you want to treat them as JavaScript objects, you have to run them through a JSON parser.
You will then run into another problem as the option values are not JSON. Use JSON Lint to find your errors (I can't see any aside from you using a ' every place you should be using a "). If you are dealing with JSON, you should almost always be building a data structure in a programming language and then running it through a JSON serializer, handcrafting JSON is asking for trouble.
this line is an issue
x.push(opts[0]);
first off, I think you need to do opts[0].value, then I think you need to use eval or JSON.parse to turn it into an object.
Related
I think this may be classified as basic but I was curious. Why do you have to parse json encoded data returned from ajax calls but not if it is echoed by php in the main loading document?
Edit: Basically the question is, if I have an object called data with a property id in both cases, why I can type
data.id
and have the value returned when the json object has been echoed out while loading the main document, but have it throw an error when returned from an ajax call and not parsed?
By echoed, I assume you mean you did something like this:
<script>
var data = <? echo json_encode($data) ?>;
alert(data.id);
</script>
If that's the case, the browser knows that the echoed json is code because it's contained by script tags. JSON is a subset of JavaScript, so what you're really doing here is generating JavaScript code that the browser then interprets.
Ajax, on the other hand is different. When you load something with ajax, it might be text, xml, csv, html, svg, or any of dozens of different formats. JSON is just a data format like all the others I listed, so you've got to tell the javascript engine what it is. That's why you have to parse it. It needs to know the format of the text so it can interpret it correctly.
You don't have to, and JSON-encoded strings still need to be "decoded" from Javascript. It's just a faster way of being able to access array elements/properties in the returned string for ajax calls.
I have a form with fields and a text-area that allows any characters to be entered. I can't just submit the form, because the form is being recycled many times over, so the form values are being stored in associative arrays:
<form name='Theform'>
<input type="text" id="VISITOR_DETAILS_NAME" value="Joe">
<input type="text" id="VISITOR_DETAILS_SIZE" value="Large">
<textarea id='VISITOR_DETAILS_INFO'>
User can enter anything here including double " and single ' quotes
</textarea>
<input type="hidden" name="package" id="package" value="" />
</form>
The text-area value are stored in a JavaScript array along with the other form values:
myArray[0]['VISITOR_DETAILS_NAME'] = document.getElementById('VISITOR_DETAILS_NAME').value;
myArray[0]['VISITOR_DETAILS_SIZE'] = document.getElementById('VISITOR_DETAILS_SIZE').value;
myArray[0]['VISITOR_DETAILS_INFO'] = document.getElementById('VISITOR_DETAILS_INFO').value;
I end up with an array something like this:
{
VISITOR_DETAILS_NAME : "Joe",
VISITOR_DETAILS_SIZE : "Large",
VISITOR_DETAILS_INFO : "User can enter anything here including double " and single ' quotes"
};
I then pass this JavaScript array to the hidden form field using JSON.stringify and then POST this to PHP:
document.getElementById('package').value = JSON.stringify(myArray[0]);
Theform.submit();
(For now I'm just posting to an iframe to test that the JSON is passing the JavaScript arrays properly through POST).
When I get it on the PHP side - it seems good to go. It looks like the JSON.stringify has added the backslash to the double quote (\" ) - and now I want to store the values in MySQL. But I want to first test that I can send/reconstruct the JSON back to the javascript as an array - so I try this:
parent.myArray[0] = JSON.parse('<?php echo $_POST['package']; ?>');
I get an ERROR: SyntaxError: Expected token ')' OR SyntaxError: missing ) after argument list
This is strange to me - because when I try it without POSTING - It seems to work fine like this:
document.getElementById('package').value = JSON.stringify(myArray[0]);
now if I try to just pass back the stringified value back to the array
myArray[0] = JSON.parse(document.getElementById('package').value);
- it seems to work fine - no errors
QUESTIONS:
Why am I getting this error when trying to reconstruct the ARRAY from the
POSTED JSON.stringify() value?
Do I save this JSON.stringify() value in MySQL as is?
Or do I PHP json_decode() it first?
I want to grab the form data - handle it properly - store it in MySQL and then read it back into the form when I need it.
Thanks All :)
parent.myArray[0] = JSON.parse('<?php echo $_POST['package']; ?>');
Here you are are trying to convert a JSON text into an HTML representation of a JavaScript string representation of a JSON text, but you aren't doing anything to escape it for either.
If you have any ' characters in the JSON data, then they will terminate the JavaScript string.
If you have any " characters in the JSON data, then they will be represented as \", but \" is a JavaScript string representation of ". Since you don't do anything to escape the text you put in the JS string, the slash character will be consumed by the JavaScript parser and will be gone before it reached the JSON parser.
If you want to convert data for placing in a JavaScript string then you need to escape it.
However, JSON is a subset (almost) of JavaScript. So the process of converting a JSON text to a JavaScript string so it can be parsed into a JavaScript object is over-complicated. You can skip that can just go straight to:
<script>
var foo = <?php echo $json; ?>
</script>
However, since you are taking in the JSON from the client, echoing out directly will expose you to XSS attacks. In order to deal with this you should filter the data on the server.
This will:
Fail to parse any invalid JSON and so not output bad JSON (but it might output nothing, giving you a JSON syntax error, you should apply tests to see if the parse was successful and output a sensible default case if it fails).
Convert any </script> in the data to <\/script> making it safe to place in a script element (because that is how PHP's json_encode works
Such:
<!-- I don't do PHP, this is untested -->
<script>
var foo = <?php
$unsafe_json = $_POST['package'];
$data_structure = json_parse($unsafe_json);
$safe_json = json_encode($data_structure);
echo $safe_json;
?>;
</script>
Do I save this JSON.stringify() value in MySQL as is? Or do I PHP json_decode() it first?
That depends on what you intend to do with the data. In general when putting things into a database it is a good idea to extra the data from the data format and normalize it. That way you can run queries over it.
If you are only going to store the data and then retrieve it, you might be able to get away with not doing that and storing strings of JSON in the database. That loses you a lot of flexibility though and might bite you in the future.
So I am using FLOT to generate some bar graphs and it uses some javascript arrays to allow for the data. I have a query that spits out the correct labels and values as so:
while ($row = mysql_fetch_array($chart_stats)){
printf("Race is: %s Percentage: %s", $row['Race'],$row['Percentage'] ."<br/>");
}
My question is can I get the values of my array from php into the array of Javascript (if that makes sense)
var d1 =[0, 72]; //instead of static value maybe var d1 = [0,<?printf($row['Percentage'])?>];
var d2 =[1,3];
var d3 = [2,40];
Thanks in advance!
Yes, you can echo stuff from PHP wherever you like. When putting it into a block of JavaScript, though, you have to be careful that:
The resulting output is ALWAYS valid code
There is no way for user-generated input to be placed into code and run
The second one is simple: never put anything you got from $_POST into a <script> tag.
As for the first, json_encode is a big help. With it, you can output almost any kind of PHP variable as a valid JavaScript one.
Looking for a way to setup a server-side datatable using PHP to parse XML json?
Okay, I'm getting the data from wufoo and so I am also able to pull json. How can I get started with the following data?
{"Entries":[{"EntryId":"33","Field71":"","Field41":"John","Field42":"Smith","Field55":"","Field34":"2004","Field375":"Arts, Design, Entertainment, Sports and Media","Field378":"Select One","Field4":"Kayak Outfitter","Field3":"Kayak Tours, Inc","Field7":"123 Main Street","Field8":"","Field9":"New York","Field10":"New York","Field11":"54209","Field12":"United States","Field19":"(555)555-5555","Field23":"contact#email.com","Field46":"http:\/\/www.website.com","Field21":"","Field49":"","Field6":"May>September","Field65":"","Field69":"","Field25":"","Field37":"Its all about Self-Motivation.","Field30":"Yes","Field31":"Yes","Field172":"","Field39":"","DateCreated":"2009-01-30 05:46:02","CreatedBy":"public","DateUpdated":"2010-08-08 22:23:30","UpdatedBy":"User"}]}
As Charles suggests DataTables will currently only accept a JSON input with a specific format. The reason for this is that supporting abstract formats would add a lot of overhead to both the internals and the initialisation (i.e. you'd need to tell it that you want it to use //articles/book#author or whatever).
So one option is to use fnServerData ( http://datatables.net/usage/callbacks#fnServerData ) to make your own Ajax call and get the XML - than transform it into the JSON format that DataTables needs with a simple loop.
Allan
Thanks for the sample data.
You're going to need to convert the data slightly.
DataTables can take a Javascript data structure (JSON), but it has to be an array of arrays.
Your sample data has a root element called Entries, which contains an array. That's great. Unfortunately each element in that array is currently a hash -- a key/value pair.
You need only the values from that pair, not the keys.
This Javascript will convert your Entries array-of-hashes into a plain old array-of-arrays. I'm using the Javascript 1.6 for each ... in syntax here because I had a brainfart and didn't remember that we're talking about a jQuery plugin here, and wrote it without that dependency.
var entries = /* JSON as provided in question */;
var new_array = new Array();
var el = entries['Entries'].length;
for(i = 0; i < el; i++) {
var inner_array = new Array();
for each (var value in entries['Entries'][i]) {
inner_array[ inner_array.length ] = value;
}
new_array[ new_array.length ] = inner_array;
}
You can then pass new_array into the initial options hash's aaData option, as documented in the link I provided above. You will need to work out how to present the column headings yourself, given that you seem to have fallen into the anti-pattern of useless key names.
I've got an associative array in php that I want to stick into a hidden form input so that I can later get the values in javascript. Because of quoting issues, I need to urlencode the json, or htmlentity it. Once I have the object in javascript, though, what's the easiest way to get it back to plain ol' json?
OR is there a better way to approach this issue? AJAX seems like overkill here -- I'd rather pre-populate the data on the page, rather than setting up multiple requests. I suppose I could write the php object to the page inside a php-generated script tag, but that seems a bit messy, and I'm not certain that [scripts] will be parsed in every possible situation where this might be used.
If you stick the data within a field you could use decodeURIComponent to decode the value. Example:
decodeURIComponent("%5b'hello'%2c%20'world'%5d"); // ['hello', 'world']
Another approach might be to embed the JSON object in a <script> element in the PHP output. You could even go as far as to make the JSON object an argument to a function that stores it away somewhere.
<script>setupData(<?= toJSON(['hello', 'world']) ?>)</script>
When the page loads the setupData would be called with the literal ['hello', 'world'].
Oh. I guess I should have tested first. I'm using dojo, and this Just Works:
PHP:
$arr = array('nyc'=>'big apple', 'boss'=>'big banana', 'lion'=>'big cat');
$json = htmlentities(json_encode($arr));
echo '<input type="hidden" id="myHidden" value="' . $json . '" />';
Javascript:
var raw = dojo.byId('myHidden').value;
var arr = dojo.fromJson(raw);
for (var i in arr) {
console.log(i + " => " + arr[i]);
}
[sheepish grin]