Sorting object keys or array items via the context menu is now also naturally sorted (see #288)
This commit is contained in:
parent
a97be17ed3
commit
e7b7362fc2
|
@ -6,11 +6,14 @@ https://github.com/josdejong/jsoneditor
|
|||
## not yet released, version 5.3.0
|
||||
|
||||
- Implemented support for sorting object keys naturally. Thanks @edufelipe.
|
||||
- Sorting object keys or array items via the context menu is now also naturally
|
||||
sorted.
|
||||
- Fixed #283: improved JSON schema error message in case of no
|
||||
additionalProperties.
|
||||
- Fixed #286: Calling `get()` or `getText()` caused the editor to lose focus.
|
||||
A regression introduced in v5.2.0.
|
||||
|
||||
|
||||
## 2016-03-20, version 5.2.0
|
||||
|
||||
- Implemented method `editor.destroy()` to properly cleanup the editor (#278).
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"ajv": "3.4.0",
|
||||
"brace": "0.7.0"
|
||||
"brace": "0.7.0",
|
||||
"javascript-natural-sort": "0.7.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "3.9.0",
|
||||
|
|
164
src/js/Node.js
164
src/js/Node.js
|
@ -1,3 +1,4 @@
|
|||
var naturalSort = require('javascript-natural-sort');
|
||||
var ContextMenu = require('./ContextMenu');
|
||||
var appendNodeFactory = require('./appendNodeFactory');
|
||||
var util = require('./util');
|
||||
|
@ -299,46 +300,30 @@ Node.prototype.setValue = function(value, type) {
|
|||
else if (this.type == 'object') {
|
||||
// object
|
||||
this.childs = [];
|
||||
var props = [];
|
||||
for (var childField in value) {
|
||||
if (value.hasOwnProperty(childField)) {
|
||||
props.push(childField);
|
||||
childValue = value[childField];
|
||||
if (childValue !== undefined && !(childValue instanceof Function)) {
|
||||
// ignore undefined and functions
|
||||
child = new Node(this.editor, {
|
||||
field: childField,
|
||||
value: childValue
|
||||
});
|
||||
this.appendChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.editor.options.sortObjectKeys === true) {
|
||||
props = this._naturalSort(props);
|
||||
}
|
||||
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var childField = props[i];
|
||||
childValue = value[childField];
|
||||
if (childValue !== undefined && !(childValue instanceof Function)) {
|
||||
// ignore undefined and functions
|
||||
child = new Node(this.editor, {
|
||||
field: childField,
|
||||
value: childValue
|
||||
});
|
||||
this.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
this.value = '';
|
||||
|
||||
// sort object keys
|
||||
if (this.editor.options.sortObjectKeys === true) {
|
||||
this.sort('asc');
|
||||
}
|
||||
}
|
||||
else {
|
||||
// value
|
||||
this.childs = undefined;
|
||||
this.value = value;
|
||||
/* TODO
|
||||
if (typeof(value) == 'string') {
|
||||
var escValue = JSON.stringify(value);
|
||||
this.value = escValue.substring(1, escValue.length - 1);
|
||||
console.log('check', value, this.value);
|
||||
}
|
||||
else {
|
||||
this.value = value;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
this.previousValue = this.value;
|
||||
|
@ -2761,41 +2746,41 @@ Node.prototype._onChangeType = function (newType) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Sort the childs of the node. Only applicable when the node has type 'object'
|
||||
* Sort the child's of the node. Only applicable when the node has type 'object'
|
||||
* or 'array'.
|
||||
* @param {String} direction Sorting direction. Available values: "asc", "desc"
|
||||
* @private
|
||||
*/
|
||||
Node.prototype._onSort = function (direction) {
|
||||
if (this._hasChilds()) {
|
||||
var order = (direction == 'desc') ? -1 : 1;
|
||||
var prop = (this.type == 'array') ? 'value': 'field';
|
||||
this.hideChilds();
|
||||
|
||||
var oldChilds = this.childs;
|
||||
var oldSort = this.sort;
|
||||
|
||||
// copy the array (the old one will be kept for an undo action
|
||||
this.childs = this.childs.concat();
|
||||
|
||||
// sort the arrays
|
||||
this.childs.sort(function (a, b) {
|
||||
if (a[prop] > b[prop]) return order;
|
||||
if (a[prop] < b[prop]) return -order;
|
||||
return 0;
|
||||
});
|
||||
this.sort = (order == 1) ? 'asc' : 'desc';
|
||||
|
||||
this.editor._onAction('sort', {
|
||||
node: this,
|
||||
oldChilds: oldChilds,
|
||||
oldSort: oldSort,
|
||||
newChilds: this.childs,
|
||||
newSort: this.sort
|
||||
});
|
||||
|
||||
this.showChilds();
|
||||
Node.prototype.sort = function (direction) {
|
||||
if (!this._hasChilds()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var order = (direction == 'desc') ? -1 : 1;
|
||||
var prop = (this.type == 'array') ? 'value': 'field';
|
||||
this.hideChilds();
|
||||
|
||||
var oldChilds = this.childs;
|
||||
var oldSortOrder = this.sortOrder;
|
||||
|
||||
// copy the array (the old one will be kept for an undo action
|
||||
this.childs = this.childs.concat();
|
||||
|
||||
// sort the arrays
|
||||
this.childs.sort(function (a, b) {
|
||||
return order * naturalSort(a[prop], b[prop]);
|
||||
});
|
||||
this.sortOrder = (order == 1) ? 'asc' : 'desc';
|
||||
|
||||
this.editor._onAction('sort', {
|
||||
node: this,
|
||||
oldChilds: oldChilds,
|
||||
oldSort: oldSortOrder,
|
||||
newChilds: this.childs,
|
||||
newSort: this.sortOrder
|
||||
});
|
||||
|
||||
this.showChilds();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -3105,13 +3090,13 @@ Node.prototype.showContextMenu = function (anchor, onClose) {
|
|||
}
|
||||
|
||||
if (this._hasChilds()) {
|
||||
var direction = ((this.sort == 'asc') ? 'desc': 'asc');
|
||||
var direction = ((this.sortOrder == 'asc') ? 'desc': 'asc');
|
||||
items.push({
|
||||
text: 'Sort',
|
||||
title: 'Sort the childs of this ' + this.type,
|
||||
className: 'jsoneditor-sort-' + direction,
|
||||
click: function () {
|
||||
node._onSort(direction);
|
||||
node.sort(direction);
|
||||
},
|
||||
submenu: [
|
||||
{
|
||||
|
@ -3119,7 +3104,7 @@ Node.prototype.showContextMenu = function (anchor, onClose) {
|
|||
className: 'jsoneditor-sort-asc',
|
||||
title: 'Sort the childs of this ' + this.type + ' in ascending order',
|
||||
click: function () {
|
||||
node._onSort('asc');
|
||||
node.sort('asc');
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -3127,7 +3112,7 @@ Node.prototype.showContextMenu = function (anchor, onClose) {
|
|||
className: 'jsoneditor-sort-desc',
|
||||
title: 'Sort the childs of this ' + this.type +' in descending order',
|
||||
click: function () {
|
||||
node._onSort('desc');
|
||||
node.sort('desc');
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -3399,57 +3384,6 @@ Node.prototype._escapeJSON = function (text) {
|
|||
return escaped;
|
||||
};
|
||||
|
||||
/**
|
||||
* sorts an array of strings using natural sort.
|
||||
* Natural sort resuls in the array `['100', '2', '1']` being sorted as
|
||||
* `['1', '2', '100']` instead of `['1', '100', '2']`, making it more readable.
|
||||
* This implementation is an adaptation of Brian Huisman implementation of the
|
||||
* Alphanum Algorithm by David Koelle.
|
||||
* @param {Array[String]} array
|
||||
* @return {String} sortedArray
|
||||
* @private
|
||||
*/
|
||||
Node.prototype._naturalSort = function(array) {
|
||||
var sortedArray = array.slice();
|
||||
|
||||
for (var z = 0, t; t = sortedArray[z]; z++) {
|
||||
sortedArray[z] = [];
|
||||
var x = 0, y = -1, n = 0, i, j;
|
||||
|
||||
while (i = (j = t.charAt(x++)).charCodeAt(0)) {
|
||||
var m = (i == 46 || (i >=48 && i <= 57));
|
||||
if (m !== n) {
|
||||
sortedArray[z][++y] = '';
|
||||
n = m;
|
||||
}
|
||||
sortedArray[z][y] += j;
|
||||
}
|
||||
}
|
||||
|
||||
sortedArray.sort(function(a, b) {
|
||||
for (var x = 0, aa, bb; (aa = a[x]) && (bb = b[x]); x++) {
|
||||
aa = aa.toLowerCase();
|
||||
bb = bb.toLowerCase();
|
||||
if (aa !== bb) {
|
||||
var c = Number(aa), d = Number(bb);
|
||||
if (c == aa && d == bb) {
|
||||
return c - d;
|
||||
}
|
||||
else {
|
||||
return (aa > bb) ? 1 : -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return a.length - b.length;
|
||||
});
|
||||
|
||||
for (var z = 0; z < sortedArray.length; z++) {
|
||||
sortedArray[z] = sortedArray[z].join('');
|
||||
}
|
||||
|
||||
return sortedArray;
|
||||
}
|
||||
|
||||
// TODO: find a nicer solution to resolve this circular dependency between Node and AppendNode
|
||||
var AppendNode = appendNodeFactory(Node);
|
||||
|
||||
|
|
Loading…
Reference in New Issue