/Solutions/Wolfpack.Core.WebUI/Scripts/FlexiJsonEditor/jquery.jsoneditor.js
JavaScript | 218 lines | 151 code | 46 blank | 21 comment | 46 complexity | 3e6d6a6af14ac395e862b4bf8c4549ed MD5 | raw file
Possible License(s): Apache-2.0, BSD-2-Clause, BSD-3-Clause, GPL-2.0, MIT
- // Simple yet flexible JSON editor plugin.
- // Turns any element into a stylable interactive JSON editor.
- // Copyright (c) 2011 David Durman
- // Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php).
- // Dependencies:
- // * jQuery
- // * JSON (use json2 library for browsers that do not support JSON natively)
- // Example:
- // var myjson = { any: { json: { value: 1 } } };
- // var opt = { change: function() { /* called on every change */ } };
- // /* opt.propertyElement = '<textarea>'; */ // element of the property field, <input> is default
- // /* opt.valueElement = '<textarea>'; */ // element of the value field, <input> is default
- // $('#mydiv').jsonEditor(myjson, opt);
- (function( $ ) {
- $.fn.jsonEditor = function(json, options) {
- options = options || {};
- var K = function() {},
- onchange = options.change || K;
- return this.each(function() {
- JSONEditor($(this), json, onchange, options.propertyElement, options.valueElement);
- });
-
- };
-
- function JSONEditor(target, json, onchange, propertyElement, valueElement) {
- var opt = {
- target: target,
- onchange: onchange,
- original: json,
- propertyElement: propertyElement,
- valueElement: valueElement
- };
- construct(opt, json, opt.target);
- $('.property, .value', opt.target).on('blur focus', function() {
- $(this).toggleClass('editing');
- });
- }
- function isObject(o) { return Object.prototype.toString.call(o) == '[object Object]'; }
- function isArray(o) { return Object.prototype.toString.call(o) == '[object Array]'; }
- function isBoolean(o) { return Object.prototype.toString.call(o) == '[object Boolean]'; }
- function isNumber(o) { return Object.prototype.toString.call(o) == '[object Number]'; }
- function isString(o) { return Object.prototype.toString.call(o) == '[object String]'; }
- var types = 'object array boolean number string null';
- // Feeds object `o` with `value` at `path`. If value argument is omitted,
- // object at `path` will be deleted from `o`.
- // Example:
- // feed({}, 'foo.bar.baz', 10); // returns { foo: { bar: { baz: 10 } } }
- function feed(o, path, value) {
- var del = arguments.length == 2;
-
- if (path.indexOf('.') > -1) {
- var diver = o,
- i = 0,
- parts = path.split('.');
- for (var len = parts.length; i < len - 1; i++) {
- diver = diver[parts[i]];
- }
- if (del) delete diver[parts[len - 1]];
- else diver[parts[len - 1]] = value;
- } else {
- if (del) delete o[path];
- else o[path] = value;
- }
- return o;
- }
- // Get a property by path from object o if it exists. If not, return defaultValue.
- // Example:
- // def({ foo: { bar: 5 } }, 'foo.bar', 100); // returns 5
- // def({ foo: { bar: 5 } }, 'foo.baz', 100); // returns 100
- function def(o, path, defaultValue) {
- path = path.split('.');
- var i = 0;
- while (i < path.length) {
- if ((o = o[path[i++]]) == undefined) return defaultValue;
- }
- return o;
- }
- function error(reason) { if (window.console) { console.error(reason); } }
-
- function parse(str) {
- var res;
- try { res = JSON.parse(str); }
- catch (e) { res = null; error('JSON parse failed.'); }
- return res;
- }
- function stringify(obj) {
- var res;
- try { res = JSON.stringify(obj); }
- catch (e) { res = 'null'; error('JSON stringify failed.'); }
- return res;
- }
-
- function addExpander(item) {
- if (item.children('.expander').length == 0) {
- var expander = $('<span>', { 'class': 'expander' });
- expander.bind('click', function() {
- var item = $(this).parent();
- item.toggleClass('expanded');
- });
- item.prepend(expander);
- }
- }
-
- function construct(opt, json, root, path) {
- path = path || '';
- root.children('.item').remove();
-
- for (var key in json) {
- if (!json.hasOwnProperty(key)) continue;
- var item = $('<div>', { 'class': 'item', 'data-path': path }),
- property = $(opt.propertyElement || '<input>', { 'class': 'property' }),
- value = $(opt.valueElement || '<input>', { 'class': 'value' });
- if (isObject(json[key]) || isArray(json[key])) {
- addExpander(item);
- }
-
- item.append(property).append(value);
- root.append(item);
-
- property.val(key).attr('title', key);
- var val = stringify(json[key]);
- value.val(val).attr('title', val);
- assignType(item, json[key]);
- property.change(propertyChanged(opt));
- value.change(valueChanged(opt));
-
- if (isObject(json[key]) || isArray(json[key])) {
- construct(opt, json[key], item, (path ? path + '.' : '') + key);
- }
- }
- }
- function updateParents(el, opt) {
- $(el).parentsUntil(opt.target).each(function() {
- var path = $(this).data('path');
- path = (path ? path + '.' : path) + $(this).children('.property').val();
- var val = stringify(def(opt.original, path, null));
- $(this).children('.value').val(val).attr('title', val);
- });
- }
- function propertyChanged(opt) {
- return function() {
- var path = $(this).parent().data('path'),
- val = parse($(this).next().val()),
- newKey = $(this).val(),
- oldKey = $(this).attr('title');
- $(this).attr('title', newKey);
- feed(opt.original, (path ? path + '.' : '') + oldKey);
- if (newKey) feed(opt.original, (path ? path + '.' : '') + newKey, val);
- updateParents(this, opt);
- if (!newKey) $(this).parent().remove();
-
- opt.onchange();
- };
- }
- function valueChanged(opt) {
- return function() {
- var key = $(this).prev().val(),
- val = parse($(this).val() || 'null'),
- item = $(this).parent(),
- path = item.data('path');
- feed(opt.original, (path ? path + '.' : '') + key, val);
- if ((isObject(val) || isArray(val)) && !$.isEmptyObject(val)) {
- construct(opt, val, item, (path ? path + '.' : '') + key);
- addExpander(item);
- } else {
- item.find('.expander, .item').remove();
- }
- assignType(item, val);
- updateParents(this, opt);
-
- opt.onchange();
- };
- }
-
- function assignType(item, val) {
- var className = 'null';
-
- if (isObject(val)) className = 'object';
- else if (isArray(val)) className = 'array';
- else if (isBoolean(val)) className = 'boolean';
- else if (isString(val)) className = 'string';
- else if (isNumber(val)) className = 'number';
- item.removeClass(types);
- item.addClass(className);
- }
- })( jQuery );