Note: [updated post - source code formatting]
Nice script.
I am using it with MooTools as their json encode function doesn't appear to do what I want...
Problem is that MooTools extends the arrays and when you run the json_encode() script listed here against the array, it encodes all of the extensions into the json string.
I modified it using the suggestion at
http://onwebdevelopment.blogspot.com/2008/01/prototype-mootools-etc-breaking-for-in.html to deal with this behaviour.
I added either the "if (inVal.hasOwnProperty(key)){}" or "if (inVal.hasOwnProperty(i)){}" wrapper around the contents of the for .. in and for () loops in order to eliminate the extensions to the array from being processed. I have only applied it to the data I am working with so it has not had extensive testing. It works to fix the problem created by the MooTools extensions on my site.
Here is the code as I have modified it in case it is of use to anyone else. No warranty or suggestion that it works on any site other than my own... usual disclaimer... :-)
The format has been changed to the standard that I use... so it looks a little bit different...
NOTE: This POST has been updated to fix the code tags around the source code. Thank you for suggesting that!
START OF MODIFIED VERSION
/**
* JSON Encoder for JavaScript
*
* Modified : 2009.11.01 to work with MooTools Enhanced Arrays
*
* Modification consists of addition of the tests :
* if (inVal.hasOwnProperty(key)) {}
* if (inVal.hasOwnProperty(i)) {}
*
* These are the tests that make the encoder ignore the MooTools array extensions.
*
* Original code found at :
* http://www.perkiset.org/forum/javascript/json_encoder_for_javascript-t1094.0.html
*
*/
function json_encode(inVal) { return _json_encode(inVal).join(''); }
function _json_encode(inVal, out)
{
out = out || new Array();
var undef; // undefined
switch (typeof inVal)
{
case 'object':
if (!inVal)
{
out.push('null');
}
else
{
if (inVal.constructor == Array)
{
// Need to make a decision... if theres any associative
// elements of the array then I will block the whole
// thing as an object {} otherwise, I'll block it
// as a normal array []
var testVal = inVal.length;
var compVal = 0;
for (var key in inVal)
{
if (inVal.hasOwnProperty(key))
{
compVal++;
}
}
if (testVal != compVal)
{
// Associative
out.push('{');
i = 0;
for (var key in inVal)
{
if (inVal.hasOwnProperty(key))
{
if (i++ > 0) out.push(',\n');
out.push('"');
out.push(key);
out.push('":');
_json_encode(inVal[key], out);
}
}
out.push('}');
}
else
{
// Standard array...
out.push('[');
for (var i = 0; i < inVal.length; ++i)
{
if (inVal.hasOwnProperty(i))
{
if (i > 0) out.push(',\n');
_json_encode(inVal[i], out);
}
}
out.push(']');
}
}
else
{
if (typeof inVal.toString != 'undefined')
{
out.push('{');
var first = true;
for (var i in inVal)
{
if (inVal.hasOwnProperty(i))
{
var curr = out.length; // Record position to allow undo when arg[i] is undefined.
if (!first) out.push(',\n');
_json_encode(i, out);
out.push(':');
_json_encode(inVal[i], out);
if (out[out.length - 1] == undef)
{
out.splice(curr, out.length - curr);
}
else
{
first = false;
}
}
}
out.push('}');
}
}
}
return out;
case 'unknown':
case 'undefined':
case 'function':
out.push(undef);
return out;
case 'string':
out.push('"');
out.push(inVal.replace(/(["\\])/g, '\$1').replace(/\r/g, '').replace(/\n/g, '\n'));
out.push('"');
return out;
default:
out.push(String(inVal));
return out;
}
}
END OF MODIFIED VERSION