Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 52 additions & 5 deletions demo/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
<meta charset="utf-8">
<title>AngularJS directive demo</title>

<script src="../bower_components/angular/angular.js"></script>
<script src="../bower_components/angular-sanitize/angular-sanitize.js"></script>
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="../dist/json-formatter.min.css"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular-sanitize.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.2.0/ui-bootstrap-tpls.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="../dist/json-formatter.min.css">
<link rel="stylesheet" href="demo.css">
</head>
<body ng-controller="MainCtrl">
Expand Down Expand Up @@ -43,6 +46,50 @@ <h4>How to use</h4>
</p>
<p><code>open</code> attribute accepts a number that indicated how many levels JSON should be open</p>

<hr>
<div style="background-color: wheat; padding: 10px">
<h3 style="color: blue">Branch Specific Tests</h3>
<hr>

<h4>Deep JSON</h4>
<button class="btn btn-default" style="float: left; margin-right: 5px" type="button" ng-click="iLevels=1"
uib-tooltip="Collapse"
tooltip-placement="left"
tooltip-popup-delay="500">
<i class="fa fa-solo fa-compress"></i>
</button>
<button class="btn btn-default" style="float: left; margin-right: 5px" type="button" ng-click="decLevel()"
uib-tooltip="Collapse One Level ({{iLevels}})"
tooltip-placement="left"
tooltip-popup-delay="500">
<i class="fa fa-solo fa-minus"></i>
</button>

<button class="btn btn-default" style="float: left; margin-right: 5px" type="button" ng-click="incLevel()"
uib-tooltip="Expand One Level ({{iLevels}})"
tooltip-placement="left"
tooltip-popup-delay="500">
<i class="fa fa-solo fa-plus"></i>
</button>
<button class="btn btn-default" style="float: left; margin-right: 5px" type="button" ng-click="iLevels=testObjDepth"
uib-tooltip="Expand ({{testObjDepth}})"
tooltip-placement="left"
tooltip-popup-delay="500">
<i class="fa fa-solo fa-expand"></i>
</button>
<h5 style="float: left; margin-left: 10px">(Depth = {{iLevels}} of {{testObjDepth}})</h5>
<div class="result" style="clear: both; background-color: white">
<json-formatter json="testObj" open="iLevels"></json-formatter>
</div>

<h4>Show Hex</h4>
<div class="result" style="clear: both; background-color: white">
<json-formatter json="complex" open="1" show-hex="true"></json-formatter>
</div>

</div>
<hr>

<h4>Configuration</h4>
<p>You can set following configurations via <code>JSONFormatterConfig</code> provider.</p>
<p>Changing these configurations will impact all demos</p>
Expand Down Expand Up @@ -252,7 +299,7 @@ <h4>Giant JSON</h4>
</div>

</div>
<script src="../dist/json-formatter.min.js"></script>
<script src="../dist/json-formatter.js"></script>
<script src="demo.js"></script>
</body>
</html>
39 changes: 39 additions & 0 deletions demo/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,45 @@ app.controller('MainCtrl', function ($scope, $http, JSONFormatterConfig) {
JSONFormatterConfig.hoverPreviewFieldCount = newValue;
});

////http://stackoverflow.com/questions/13523951/how-to-check-the-depth-of-an-object
function depthOf( obj ) {

var level = 1;
var key;

if (!angular.isObject( obj )) {
return level;
}

for (key in obj) {
if (!obj.hasOwnProperty(key)) {
continue;
}

if (angular.isObject( obj[key] )) {
var depth = depthOf(obj[key]) + 1;
level = Math.max(depth, level);
}
}
return level;
} // depthOf

$scope.iLevels = 1;
$scope.testObj = { lvl0: { num: 12, lvl1: { lvl2: { lvl3: { lvl4: { lvl5: { lvl6: { lvl7: { lvl8: { lvl9: { lvl10: { lvl11: { lvl12: { end:true } } } } } } } } } } } } } };
$scope.testObjDepth = depthOf($scope.testObj);
$scope.incLevel = function() {
$scope.iLevels++;
if ($scope.iLevels > $scope.testObjDepth) {
$scope.iLevels = $scope.testObjDepth;
}
}
$scope.decLevel = function() {
$scope.iLevels--;
if ($scope.iLevels < 0) {
$scope.iLevels = 0;
}
}

$scope.undef = undefined;
$scope.textarea = '{}';
$scope.complex = {
Expand Down
57 changes: 49 additions & 8 deletions dist/json-formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,35 @@ angular.module('jsonFormatter', ['RecursionHelper'])
return str.replace('"', '\"');
}

function isFloat(n) {
return Number(n) === n && n % 1 !== 0;
}

function toHex(val, padLen) {

if (typeof val == 'undefined') {
return "";
}

if (typeof val == 'string') {
val = parseInt(val);
}

var sVal = (val < 0 ? (0xFFFFFFFF + val + 1) : val).toString(16);

if (typeof padLen != 'undefined') {

if (sVal.length < padLen) {
// +1 because the Array gives one less that you want
var len = (padLen - sVal.length) + 1;
sVal = Array(len).join("0") + sVal;
}
}

return sVal.toUpperCase();

}; // toHex

// From http://stackoverflow.com/a/332429
function getObjectName(object) {
if (object === undefined) {
Expand All @@ -79,14 +108,19 @@ angular.module('jsonFormatter', ['RecursionHelper'])
return typeof object;
}

function getValuePreview (object, value) {
function getValuePreview (scope, object, value) {
var type = getType(object);

if (type === 'null' || type === 'undefined') { return type; }

if (type === 'string') {
value = '"' + escapeString(value) + '"';
}
if ((type === 'number') && (!isFloat(value))) {
if (scope.showHex) {
value = value + ' (0x' + toHex(value) + ')';
}
}
if (type === 'function'){

// Remove content of the function
Expand All @@ -98,14 +132,14 @@ angular.module('jsonFormatter', ['RecursionHelper'])
return value;
}

function getPreview(object) {
function getPreview(scope, object) {
var value = '';
if (angular.isObject(object)) {
value = getObjectName(object);
if (angular.isArray(object))
value += '[' + object.length + ']';
} else {
value = getValuePreview(object, object);
value = getValuePreview(scope, object, object);
}
return value;
}
Expand Down Expand Up @@ -171,7 +205,7 @@ angular.module('jsonFormatter', ['RecursionHelper'])
};

scope.parseValue = function (value){
return getValuePreview(scope.json, value);
return getValuePreview(scope, scope.json, value);
};

scope.showThumbnail = function () {
Expand All @@ -185,7 +219,9 @@ angular.module('jsonFormatter', ['RecursionHelper'])
if (scope.json.length > JSONFormatterConfig.hoverPreviewArrayCount) {
return 'Array[' + scope.json.length + ']';
} else {
return '[' + scope.json.map(getPreview).join(', ') + ']';
return '[' + scope.json.map(function(obj) {
return getPreview(scope, obj);
} ).join(', ') + ']';
}
} else {

Expand All @@ -196,14 +232,18 @@ angular.module('jsonFormatter', ['RecursionHelper'])

// json value schematic information
var kvs = narrowKeys
.map(function (key) { return key + ':' + getPreview(scope.json[key]); });
.map(function (key) { return key + ':' + getPreview(scope, scope.json[key]); });

// if keys count greater then 5 then show ellipsis
var ellipsis = keys.length >= 5 ? '…' : '';

return '{' + kvs.join(', ') + ellipsis + '}';
}
};

scope.$watch('open', function(value) {
scope.isOpen = !!scope.open;
}, false);
}

return {
Expand All @@ -213,7 +253,8 @@ angular.module('jsonFormatter', ['RecursionHelper'])
scope: {
json: '=',
key: '=',
open: '='
open: '=',
showHex: '='
},
compile: function(element) {

Expand Down Expand Up @@ -275,4 +316,4 @@ angular.module('RecursionHelper', []).factory('RecursionHelper', ['$compile', fu
};
}]);

angular.module("jsonFormatter").run(["$templateCache", function($templateCache) {$templateCache.put("json-formatter.html","<div ng-init=\"isOpen = open && open > 0\" class=\"json-formatter-row\"><a ng-click=\"toggleOpen()\"><span class=\"toggler {{isOpen ? \'open\' : \'\'}}\" ng-if=\"isObject()\"></span> <span class=\"key\" ng-if=\"hasKey\"><span class=\"key-text\">{{key}}</span><span class=\"colon\">:</span></span> <span class=\"value\"><span ng-if=\"isObject()\"><span class=\"constructor-name\">{{getConstructorName(json)}}</span> <span ng-if=\"isArray()\"><span class=\"bracket\">[</span><span class=\"number\">{{json.length}}</span><span class=\"bracket\">]</span></span></span> <span ng-if=\"!isObject()\" ng-click=\"openLink(isUrl)\" class=\"{{type}}\" ng-class=\"{date: isDate, url: isUrl}\">{{parseValue(json)}}</span></span> <span ng-if=\"showThumbnail()\" class=\"thumbnail-text\">{{getThumbnail()}}</span></a><div class=\"children\" ng-if=\"getKeys().length && isOpen\"><json-formatter ng-repeat=\"key in getKeys() track by $index\" json=\"json[key]\" key=\"key\" open=\"childrenOpen()\"></json-formatter></div><div class=\"children empty object\" ng-if=\"isEmptyObject()\"></div><div class=\"children empty array\" ng-if=\"getKeys() && !getKeys().length && isOpen && isArray()\"></div></div>");}]);
angular.module("jsonFormatter").run(["$templateCache", function($templateCache) {$templateCache.put("json-formatter.html","<div ng-init=\"isOpen = open && open > 0\" class=\"json-formatter-row\"><a ng-click=\"toggleOpen()\"><span class=\"toggler {{isOpen ? \'open\' : \'\'}}\" ng-if=\"isObject()\"></span> <span class=\"key\" ng-if=\"hasKey\"><span class=\"key-text\">{{key}}</span><span class=\"colon\">:</span></span> <span class=\"value\"><span ng-if=\"isObject()\"><span class=\"constructor-name\">{{getConstructorName(json)}}</span> <span ng-if=\"isArray()\"><span class=\"bracket\">[</span><span class=\"number\">{{json.length}}</span><span class=\"bracket\">]</span></span></span> <span ng-if=\"!isObject()\" ng-click=\"openLink(isUrl)\" class=\"{{type}}\" ng-class=\"{date: isDate, url: isUrl}\">{{parseValue(json)}}</span></span> <span ng-if=\"showThumbnail()\" class=\"thumbnail-text\">{{getThumbnail()}}</span></a><div class=\"children\" ng-if=\"getKeys().length && isOpen\"><json-formatter ng-repeat=\"key in getKeys() track by $index\" json=\"json[key]\" key=\"key\" show-hex=\"showHex\" open=\"childrenOpen()\"></json-formatter></div><div class=\"children empty object\" ng-if=\"isEmptyObject()\"></div><div class=\"children empty array\" ng-if=\"getKeys() && !getKeys().length && isOpen && isArray()\"></div></div>");}]);
2 changes: 1 addition & 1 deletion src/json-formatter.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</span>
</a>
<div class="children" ng-if="getKeys().length && isOpen">
<json-formatter ng-repeat="key in getKeys() track by $index" json="json[key]" key="key" open="childrenOpen()"></json-formatter>
<json-formatter ng-repeat="key in getKeys() track by $index" json="json[key]" key="key" show-hex="showHex" open="childrenOpen()"></json-formatter>
</div>
<div class="children empty object" ng-if="isEmptyObject()"></div>
<div class="children empty array" ng-if="getKeys() && !getKeys().length && isOpen && isArray()"></div>
Expand Down
38 changes: 37 additions & 1 deletion src/json-formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,35 @@ angular.module('jsonFormatter', ['RecursionHelper'])
return str.replace('"', '\"');
}

function isFloat(n) {
return Number(n) === n && n % 1 !== 0;
}

function toHex(val, padLen) {

if (typeof val == 'undefined') {
return "";
}

if (typeof val == 'string') {
val = parseInt(val);
}

var sVal = (val < 0 ? (0xFFFFFFFF + val + 1) : val).toString(16);

if (typeof padLen != 'undefined') {

if (sVal.length < padLen) {
// +1 because the Array gives one less that you want
var len = (padLen - sVal.length) + 1;
sVal = Array(len).join("0") + sVal;
}
}

return sVal.toUpperCase();

}; // toHex

// From http://stackoverflow.com/a/332429
function getObjectName(object) {
if (object === undefined) {
Expand Down Expand Up @@ -79,6 +108,9 @@ angular.module('jsonFormatter', ['RecursionHelper'])
if (type === 'string') {
value = '"' + escapeString(value) + '"';
}
if ((type === 'number') && (!isFloat(value))) {
value = value+' (0x'+toHex(value)+')';
}
if (type === 'function'){

// Remove content of the function
Expand Down Expand Up @@ -196,6 +228,10 @@ angular.module('jsonFormatter', ['RecursionHelper'])
return '{' + kvs.join(', ') + ellipsis + '}';
}
};

scope.$watch('open', function(value) {
scope.isOpen = !!scope.open;
}, false);
}

return {
Expand All @@ -220,4 +256,4 @@ angular.module('jsonFormatter', ['RecursionHelper'])
// angular.module('myApp', [require('jsonformatter')]);
if (typeof module === 'object') {
module.exports = 'jsonFormatter';
}
}