The Cache: Technology Expert's Forum
 
*
Welcome, Guest. Please login or register. December 01, 2008, 04:00:50 PM

Login with username, password and session length


Pages: [1]
  Print  
Author Topic: JSON Encoder for Javascript  (Read 939 times)
perkiset
Olde World Hacker
Administrator
Lifer
*****
Online Online

Posts: 5211


:sniffle: Humor was so much easier before.


View Profile
« on: July 29, 2008, 01:47:43 PM »

OK, so you're sending data to a client via AJAX and JSON. Now, you want to send a big multipli-nested array back up to the server. So, where's the json_encode for Javascript?

There isn't one. That's because the JSON notation was written for loading objects up in Javascript, not preparing them for AJAX. So this little chunk repairs that small but significant oversite. It uses reentrance to be fast and will handle normal indexed arrays and associative arrays. You simply say, var myStr = json_encode(theArr) and you're all set.

Enjoy!

/p

Code:
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) compVal++;
if (testVal != compVal)
{
// Associative
out.push('{');
i = 0;
for (var key in inVal)
{
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 (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)
{
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;
}
}
« Last Edit: July 29, 2008, 02:53:43 PM by perkiset » Logged

If I can't be Mr. Root then I don't want to play.
perkiset
Olde World Hacker
Administrator
Lifer
*****
Online Online

Posts: 5211


:sniffle: Humor was so much easier before.


View Profile
« Reply #1 on: July 29, 2008, 01:49:11 PM »

And another version:

If you're shipping this function out via PHP, then there will be problems with the regexs because of the PHP parser. The following version of the function is ok to do a HEREDOC and output to your client via PHP:

Code:
<?php

$stript 
= <<<JS
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) compVal++;
if (testVal != compVal)
{
// Associative
out.push('
{');
i = 0;
for (var key in inVal)
{
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 (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) 
{
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;
}
}
JS;
?>


/p
Logged

If I can't be Mr. Root then I don't want to play.
nutballs
Administrator
Lifer
*****
Online Online

Posts: 3431


View Profile
« Reply #2 on: July 29, 2008, 02:23:59 PM »

cool thanks. I was just about to post a question asking about this lol.
Logged
vsloathe
vim ftw!
Global Moderator
Lifer
*****
Online Online

Posts: 626



View Profile
« Reply #3 on: July 29, 2008, 03:11:18 PM »

very nice sir. tyvm
Logged

Pages: [1]
  Print  
 
Jump to:  

Perkiset's Place Home   Best of The Cache   phpMyIDE: MySQL Stored Procedures, Functions & Triggers
Politics @ Perkiset's   Pinkhat's Perspective   
cache
mart
coder
programmers
ajax
php
javascript
Powered by MySQL Powered by PHP Powered by SMF 1.1.2 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks


Valid XHTML 1.0! Valid CSS!