Slick Little JSON Viewer
Late yesterday I found a slick little javascript-based JSON formatter and syntax highlighter. What I was looking for was a simple and easy way to get the JSON data out of the demand service and display it to the user. The point was to have a clean way for the users to be able to see the low-level data for a specific demand in a nice way so that they can look into problems without having to go to a developer or support person.
The project manager said that we didn't need to have anything fancy - just display the JSON data for the object as it's reasonably self-documenting, and most of the folks could figure out what they needed from that. For the more serious use-cases, we're still going to need to have a more comprehensive dashboard, but for now, this would be something we could whip up pretty easily and solve 90% of the need.
The code was really amazingly simple:
<html> | |
<head> | |
<title>Dark Magic Query Tools for Quantum Lead</title> | |
<link href='//fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'> | |
<script type='text/javascript' src='zingchart/resources/jquery.min.js'></script> | |
<script type='text/javascript'> | |
// This is a clever little function I found that does a very simplistic | |
// syntax coloring scheme for JSON. What it really is doing is to classify | |
// all the elements, and then with CSS we can color them. Very slick. | |
function syntaxHighlight(json) { | |
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); | |
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { | |
var cls = 'number'; | |
if (/^"/.test(match)) { | |
if (/:$/.test(match)) { | |
cls = 'key'; | |
} else { | |
cls = 'string'; | |
} | |
} else if (/true|false/.test(match)) { | |
cls = 'boolean'; | |
} else if (/null/.test(match)) { | |
cls = 'null'; | |
} | |
return '<span class="' + cls + '">' + match + '</span>'; | |
}); | |
} | |
// This function takes an object, converts it to it's pretty JSON view, | |
// runs it through the highlighter, and then throws it into the output div | |
// so that it can be seen. All in one step. Nice. | |
function render(data) { | |
var str = JSON.stringify(data, undefined, 4); | |
document.getElementById('json_output').innerHTML = '<pre>' + syntaxHighlight(str) + '</pre>'; | |
} | |
// There are times we need to render an error message in the window, and | |
// this function puts a warning message along with this text in the right | |
// place. | |
function report_error(txt) { | |
document.getElementById('json_output').innerHTML = '<h1>Error!</h1><h2>' + txt + '</h2>'; | |
} | |
// This function takes the type of data we're looking for, and the id to | |
// get, and hits the selected Dark Magic server to get it. | |
function getData(type, id) { | |
var svr_opt = document.getElementById('server_opt'); | |
var id_input = document.getElementById('demand_id'); | |
var url = '/' + type + '/' + svr_opt.value + '/' | |
+ encodeURI(id_input.value) + '?callback=?'; | |
$.getJSON(url, function(data) { | |
if (data == null) { | |
report_error("We received nothing from the server! Probably need to have that looked at."); | |
} else { | |
render(data); | |
} | |
}); | |
} | |
// This function gets the specifics of the Dark Magic corrections for the | |
// specific demand id. This is a subset of the entire demand, and as | |
// such, it's a lot quicker and smaller than the whole deal. | |
function getSpells(id) { | |
getData('spells', id); | |
} | |
// This function gets the entire demand unit from Dark Magic. This has | |
// everything in it and so can be a little confusing if you don't know | |
// what's important and what's not. | |
function getDemand(id) { | |
getData('demand', id); | |
} | |
</script> | |
<style media="screen" type="text/css"> | |
/* | |
Add a style elements for the JSON to make it a little nicer | |
*/ | |
pre { | |
outline: 1px solid #ccc; | |
padding: 5px; | |
margin: 5px; | |
font-family: 'Ubuntu', sans-serif; | |
font-size: 10px; | |
} | |
.string { color: green; } | |
.number { color: darkorange; } | |
.boolean { color: blue; } | |
.null { color: magenta; } | |
.key { color: red; } | |
h1 { | |
font-family: 'Ubuntu', sans-serif; | |
font-size: 24px; | |
color: red; | |
text-align: center; | |
} | |
h2 { | |
font-family: 'Ubuntu', sans-serif; | |
font-size: 14px; | |
color: black; | |
text-align: center; | |
} | |
</style> | |
</head> | |
<body> | |
<p align="center"> | |
Server: | |
<select id="server_opt"> | |
<option value='prod' selected="selected">Production</option> | |
<option value='uat'>UAT</option> | |
<option value='dev'>Dev</option> | |
</select> | |
Demand ID: <input type="text" id="demand_id" size="50" maxlength="50" /> | |
<input type="button" id="spells_btn" value="Spells" onclick="getSpells()" /> | |
<input type="button" id="demand_btn" value="Everything" onclick="getDemand()" /> | |
</p> | |
<div id='json_output' style="width:600px; margin-top:10px; margin-left:auto; margin-right:auto;"></div> | |
</body> | |
</html> |
I have the classifier and then the CSS for the individual classes. Then I just have to hit the server based on the demand ID and show the results. Very nice and clean.
Pretty stylish, too! I'm impressed.