Implemented setMode, setText, getText
This commit is contained in:
parent
b44a465207
commit
804c68010f
|
@ -29,7 +29,11 @@ export default class TextMode extends Component {
|
|||
]),
|
||||
|
||||
h('div', {class: 'jsoneditor-contents'}, [
|
||||
h('textarea', {class: 'jsoneditor-text', value: this.state.text})
|
||||
h('textarea', {
|
||||
class: 'jsoneditor-text',
|
||||
value: this.state.text,
|
||||
onChange: this.handleChange
|
||||
})
|
||||
])
|
||||
])
|
||||
}
|
||||
|
@ -43,6 +47,17 @@ export default class TextMode extends Component {
|
|||
return this.props.options && this.props.options.indentation || 2
|
||||
}
|
||||
|
||||
/**
|
||||
* handle changed text input in the textarea
|
||||
* @param {Event} event
|
||||
* @private
|
||||
*/
|
||||
handleChange = (event) => {
|
||||
this.setState({
|
||||
text: event.target.value
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the json
|
||||
*/
|
||||
|
@ -89,12 +104,18 @@ export default class TextMode extends Component {
|
|||
return parseJSON(this.state.text)
|
||||
}
|
||||
|
||||
// TODO: comment
|
||||
/**
|
||||
* Set a string containing a JSON document
|
||||
* @param {string} text
|
||||
*/
|
||||
setText (text) {
|
||||
this.setState({ text })
|
||||
}
|
||||
|
||||
// TODO: comment
|
||||
/**
|
||||
* Get the JSON document as text
|
||||
* @return {string} text
|
||||
*/
|
||||
getText () {
|
||||
return this.state.text
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import { h, Component } from 'preact'
|
||||
|
||||
import { setIn, updateIn } from './utils/immutabilityHelpers'
|
||||
import {
|
||||
expand, jsonToData, dataToJson, toDataPath, patchData, compileJSONPointer
|
||||
} from './jsonData'
|
||||
import { expand, jsonToData, dataToJson, toDataPath, patchData } from './jsonData'
|
||||
import {
|
||||
duplicate, insert, append, remove, changeType, changeValue, changeProperty, sort
|
||||
} from './actions'
|
||||
import JSONNode from './JSONNode'
|
||||
import { parseJSON } from './utils/jsonUtils'
|
||||
|
||||
const MAX_HISTORY_ITEMS = 1000 // maximum number of undo/redo items to be kept in memory
|
||||
|
||||
|
@ -77,7 +76,7 @@ export default class TreeMode extends Component {
|
|||
]),
|
||||
|
||||
h('div', {class: 'jsoneditor-contents jsoneditor-tree-contents', onClick: JSONNode.hideContextMenu}, [
|
||||
h('ul', {class: 'jsoneditor-list'}, [
|
||||
h('ul', {class: 'jsoneditor-list jsoneditor-root'}, [
|
||||
h(JSONNode, {
|
||||
data: state.data,
|
||||
events: state.events,
|
||||
|
@ -287,6 +286,23 @@ export default class TreeMode extends Component {
|
|||
return dataToJson(this.state.data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a string containing a JSON document
|
||||
* @param {string} text
|
||||
*/
|
||||
setText (text) {
|
||||
this.set(parseJSON(text))
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the JSON document as text
|
||||
* @return {string} text
|
||||
*/
|
||||
getText () {
|
||||
const indentation = this.props.options && this.props.options.indentation || 2
|
||||
return JSON.stringify(this.get(), null, indentation)
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand one or multiple objects or arrays
|
||||
* @param {Path | function (path: Path) : boolean} callback
|
||||
|
@ -307,8 +323,6 @@ export default class TreeMode extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
// TODO: implement getText and setText
|
||||
|
||||
/**
|
||||
* Default function to determine whether or not to expand a node initially
|
||||
*
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<script src="../dist/jsoneditor.js"></script>
|
||||
<style>
|
||||
#container {
|
||||
/*height: 300px;*/
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
@ -18,22 +18,29 @@
|
|||
<p>
|
||||
<button id="setJSON">Set JSON</button>
|
||||
<button id="getJSON">Get JSON</button>
|
||||
|
||||
<label for="mode">mode:
|
||||
<select id="mode">
|
||||
<option value="text">text</option>
|
||||
<option value="tree" selected>tree</option>
|
||||
</select>
|
||||
</label>
|
||||
</p>
|
||||
<div id="container"></div>
|
||||
|
||||
<script>
|
||||
// create the editor
|
||||
const container = document.getElementById('container');
|
||||
const container = document.getElementById('container')
|
||||
const options = {
|
||||
onChange: function (patch, revert) {
|
||||
console.log('onChange patch=', patch, ', revert=', revert)
|
||||
window.patch = patch
|
||||
window.revert = revert
|
||||
},
|
||||
mode: 'text',
|
||||
// mode: 'text',
|
||||
indentation: 4
|
||||
};
|
||||
const editor = jsoneditor(container, options);
|
||||
}
|
||||
const editor = jsoneditor(container, options)
|
||||
const json = {
|
||||
'array': [1, 2, 3],
|
||||
'emptyArray': [],
|
||||
|
@ -43,13 +50,13 @@
|
|||
'number': 123,
|
||||
'object': {'a': 'b', 'c': 'd', 'e': [{"first": true}, {"second": true}]},
|
||||
'string': 'Hello World'
|
||||
};
|
||||
}
|
||||
editor.set(json, {
|
||||
name: 'myObject',
|
||||
expand: function (path) {
|
||||
return true
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// set json
|
||||
document.getElementById('setJSON').onclick = function () {
|
||||
|
@ -57,14 +64,20 @@
|
|||
expand: function (path) {
|
||||
return true
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
// get json
|
||||
document.getElementById('getJSON').onclick = function () {
|
||||
const json = editor.get();
|
||||
alert(JSON.stringify(json, null, 2));
|
||||
};
|
||||
const json = editor.get()
|
||||
alert(JSON.stringify(json, null, 2))
|
||||
}
|
||||
|
||||
// change mode
|
||||
document.getElementById('mode').onchange = function (event) {
|
||||
const mode = event.target.value
|
||||
editor.setMode(mode)
|
||||
}
|
||||
|
||||
const largeJSON = {
|
||||
"version": "1.0",
|
||||
|
|
202
src/index.js
202
src/index.js
|
@ -7,8 +7,7 @@ import '!style!css!less!./jsoneditor.less'
|
|||
// TODO: allow adding new modes
|
||||
const modes = {
|
||||
tree: TreeMode,
|
||||
text: TextMode,
|
||||
default: TreeMode
|
||||
text: TextMode
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,93 +18,154 @@ const modes = {
|
|||
* @constructor
|
||||
*/
|
||||
function jsoneditor (container, options) {
|
||||
const mode = options && options.mode
|
||||
const constructor = modes[mode] || modes['default']
|
||||
|
||||
const elem = render(h(constructor, {options}), container)
|
||||
const component = elem._component
|
||||
|
||||
return {
|
||||
const editor = {
|
||||
isJSONEditor: true,
|
||||
|
||||
_container: container,
|
||||
_options: options,
|
||||
_component: component,
|
||||
_modes: modes,
|
||||
_mode: null,
|
||||
_element: null,
|
||||
_component: null
|
||||
}
|
||||
|
||||
// TODO: implement setMode
|
||||
/**
|
||||
* Set JSON object in editor
|
||||
* @param {Object | Array | string | number | boolean | null} json JSON data
|
||||
* @param {SetOptions} [options]
|
||||
*/
|
||||
editor.set = function (json, options = {}) {
|
||||
editor._component.set(json, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set JSON object in editor
|
||||
* @param {Object | Array | string | number | boolean | null} json JSON data
|
||||
* @param {SetOptions} [options]
|
||||
*/
|
||||
set: function (json, options = {}) {
|
||||
component.set(json, options)
|
||||
},
|
||||
/**
|
||||
* Get JSON from the editor
|
||||
* @returns {Object | Array | string | number | boolean | null} json
|
||||
*/
|
||||
editor.get = function () {
|
||||
return editor._component.get()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get JSON from the editor
|
||||
* @returns {Object | Array | string | number | boolean | null} json
|
||||
*/
|
||||
get: function () {
|
||||
return component.get()
|
||||
},
|
||||
/**
|
||||
* Set a string containing a JSON document
|
||||
* @param {string} text
|
||||
*/
|
||||
editor.setText = function (text) {
|
||||
editor._component.setText(text)
|
||||
}
|
||||
|
||||
// TODO: implement getText
|
||||
// TODO: implement setText
|
||||
/**
|
||||
* Get the JSON document as text
|
||||
* @return {string} text
|
||||
*/
|
||||
editor.getText = function () {
|
||||
return editor._component.getText()
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand one or multiple objects or arrays.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* // expand one item at a specific path
|
||||
* editor.expand(['foo', 1, 'bar'])
|
||||
*
|
||||
* // expand all items nested at a maximum depth of 2
|
||||
* editor.expand(function (path) {
|
||||
* return path.length <= 2
|
||||
* })
|
||||
*
|
||||
* @param {Path | function (path: Path) : boolean} callback
|
||||
*/
|
||||
editor.expand = function (callback) {
|
||||
editor._component.expand(callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand one or multiple objects or arrays.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* // expand one item at a specific path
|
||||
* editor.expand(['foo', 1, 'bar'])
|
||||
*
|
||||
* // expand all items nested at a maximum depth of 2
|
||||
* editor.expand(function (path) {
|
||||
* return path.length <= 2
|
||||
* })
|
||||
*
|
||||
* @param {Path | function (path: Path) : boolean} callback
|
||||
*/
|
||||
expand (callback) {
|
||||
component.expand(callback)
|
||||
},
|
||||
/**
|
||||
* Collapse one or multiple objects or arrays
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* // collapse one item at a specific path
|
||||
* editor.collapse(['foo', 1, 'bar'])
|
||||
*
|
||||
* // collapse all items nested deeper than 2
|
||||
* editor.collapse(function (path) {
|
||||
* return path.length > 2
|
||||
* })
|
||||
*
|
||||
* @param {Path | function (path: Path) : boolean} callback
|
||||
*/
|
||||
editor.collapse = function (callback) {
|
||||
editor._component.collapse(callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Collapse one or multiple objects or arrays
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* // collapse one item at a specific path
|
||||
* editor.collapse(['foo', 1, 'bar'])
|
||||
*
|
||||
* // collapse all items nested deeper than 2
|
||||
* editor.collapse(function (path) {
|
||||
* return path.length > 2
|
||||
* })
|
||||
*
|
||||
* @param {Path | function (path: Path) : boolean} callback
|
||||
*/
|
||||
collapse (callback) {
|
||||
component.collapse(callback)
|
||||
},
|
||||
/**
|
||||
* Apply a JSONPatch to the current JSON document
|
||||
* @param {Array} actions JSONPatch actions
|
||||
* @return {Array} Returns a JSONPatch to revert the applied patch
|
||||
*/
|
||||
editor.patch = function (actions) {
|
||||
return editor._component.patch(actions)
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a JSONPatch to the current JSON document
|
||||
* @param {Array} actions JSONPatch actions
|
||||
* @return {Array} Returns a JSONPatch to revert the applied patch
|
||||
*/
|
||||
patch (actions) {
|
||||
return component.patch(actions)
|
||||
/**
|
||||
* Change the mode of the editor
|
||||
* @param {'tree' | 'text'} mode
|
||||
*/
|
||||
editor.setMode = function (mode) {
|
||||
if (mode === editor._mode) {
|
||||
// mode stays the same. do nothing
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: implement destroy
|
||||
let success = false
|
||||
let element
|
||||
try {
|
||||
// find the constructor for the selected mode
|
||||
const constructor = editor._modes[mode]
|
||||
if (!constructor) {
|
||||
throw new Error('Unknown mode "' + mode + '". ' +
|
||||
'Choose from: ' + Object.keys(modes).join(', '))
|
||||
}
|
||||
|
||||
// create new component
|
||||
element = render(
|
||||
h(constructor, {options: editor._options}),
|
||||
editor._container)
|
||||
|
||||
// set JSON (this can throw an error)
|
||||
const text = editor._component ? editor._component.getText() : '{}'
|
||||
element._component.setText(text)
|
||||
|
||||
// when setText didn't fail, we will reach this point
|
||||
success = true
|
||||
}
|
||||
finally {
|
||||
if (success) {
|
||||
// destroy previous component
|
||||
if (editor._element) {
|
||||
// TODO: call editor._component.destroy() instead
|
||||
editor._element.parentNode.removeChild(editor._element)
|
||||
}
|
||||
|
||||
editor._mode = mode
|
||||
editor._element = element
|
||||
editor._component = element._component
|
||||
}
|
||||
else {
|
||||
// remove the just created component (where setText failed)
|
||||
element.parentNode.removeChild(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement destroy
|
||||
|
||||
editor.setMode(options && options.mode || 'tree')
|
||||
|
||||
return editor
|
||||
}
|
||||
|
||||
module.exports = jsoneditor
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@fontFamily: droid sans mono, consolas, monospace, courier new, courier, sans-serif;
|
||||
@fontSize: 10pt;
|
||||
@black: #1A1A1A;
|
||||
@contentsMinHeight: 150px;
|
||||
|
||||
.jsoneditor {
|
||||
border: 1px solid #3883fa;
|
||||
|
@ -83,7 +84,7 @@
|
|||
.jsoneditor-contents {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 150px;
|
||||
min-height: @contentsMinHeight;
|
||||
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
|
@ -117,7 +118,7 @@ ul.jsoneditor-list {
|
|||
}
|
||||
|
||||
/* no left padding for the root ul element */
|
||||
.jsoneditor > ul.jsoneditor-list {
|
||||
.jsoneditor-contents > ul.jsoneditor-list {
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
|
@ -503,7 +504,7 @@ button.jsoneditor-type-Array.jsoneditor-selected span.jsoneditor-icon {
|
|||
textarea.jsoneditor-text {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 150px;
|
||||
min-height: @contentsMinHeight;
|
||||
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
|
|
Loading…
Reference in New Issue