Implemented `isValueEditable` and `isPropertyEditable`

This commit is contained in:
jos 2016-10-28 13:24:51 +02:00
parent 4a12eed14f
commit 8f6ddf91bc
6 changed files with 79 additions and 69 deletions

View File

@ -1,7 +1,7 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Custom editable fields | JSONEditor</title>
<title>Read-only properties and values | JSONEditor</title>
<script src="../dist/jsoneditor.js"></script>
@ -27,26 +27,22 @@
var container = document.getElementById('jsoneditor');
var options = {
onEditable: function (node) {
// node is an object like:
// {
// field: 'FIELD',
// value: 'VALUE',
// path: ['PATH', 'TO', 'NODE']
// }
switch (node.field) {
case '_id':
return false;
case 'name':
return {
field: false,
value: true
// all properties are editable except '_id' and 'name'
isPropertyEditable: function (path) {
if (path.length === 1 && path[0] === '_id' || path[0] === 'name') {
return false
}
default:
return true;
return true
},
// all values are editable except '_id'
isValueEditable: function (path) {
if (path.length === 1 && path[0] === '_id') {
return false
}
return true
}
}
@ -56,7 +52,8 @@
age: 32
}
var editor = jsoneditor(container, options, json)
var editor = jsoneditor(container, options)
editor.set(json)
</script>
</body>
</html>

View File

@ -114,7 +114,7 @@ export default class JSONNode extends Component {
this.renderActionMenuButton(),
this.renderProperty(prop, data, options),
this.renderSeparator(),
this.renderValue(data.value)
this.renderValue(data.value, options)
])
])
}
@ -143,16 +143,21 @@ export default class JSONNode extends Component {
}
renderProperty (prop, data, options) {
if (prop !== null) {
const isIndex = typeof prop === 'number' // FIXME: pass an explicit prop isIndex
if (prop === null) {
// root node
const rootName = JSONNode.getRootName(data, options)
if (isIndex) { // array item
return h('div', {
class: 'jsoneditor-property jsoneditor-readonly',
spellCheck: 'false'
}, prop)
spellCheck: 'false',
onBlur: this.handleChangeProperty
}, rootName)
}
else { // object property
const isIndex = typeof prop === 'number' // FIXME: pass an explicit prop isIndex or editable
const editable = !isIndex && (!options.isPropertyEditable || options.isPropertyEditable(this.getPath()))
if (editable) {
const escapedProp = escapeHTML(prop)
return h('div', {
@ -162,16 +167,11 @@ export default class JSONNode extends Component {
onBlur: this.handleChangeProperty
}, escapedProp)
}
}
else {
// root node
const content = JSONNode.getRootName(data, options)
return h('div', {
class: 'jsoneditor-property jsoneditor-readonly',
spellCheck: 'false',
onBlur: this.handleChangeProperty
}, content)
spellCheck: 'false'
}, prop)
}
}
@ -179,12 +179,14 @@ export default class JSONNode extends Component {
return h('div', {class: 'jsoneditor-separator'}, ':')
}
renderValue (value) {
renderValue (value, options) {
const escapedValue = escapeHTML(value)
const type = valueType (value)
const itsAnUrl = isUrl(value)
const isEmpty = escapedValue.length === 0
const editable = !options.isValueEditable || options.isValueEditable(this.getPath())
if (editable) {
return h('div', {
class: JSONNode.getValueClass(type, itsAnUrl, isEmpty),
contentEditable: 'true',
@ -196,6 +198,13 @@ export default class JSONNode extends Component {
title: itsAnUrl ? JSONNode.URL_TITLE : null
}, escapedValue)
}
else {
return h('div', {
class: 'jsoneditor-readonly',
title: itsAnUrl ? JSONNode.URL_TITLE : null
}, escapedValue)
}
}
/**
* Note: this function manipulates the className and title of the editable div
@ -431,6 +440,10 @@ export default class JSONNode extends Component {
return path
}
isFieldEditable () {
}
/**
* Get the value of the target of an event, and convert it to it's type
* @param event

View File

@ -21,10 +21,6 @@ export default class TreeMode extends Component {
const data = jsonToData(this.props.data || {}, expand, [])
this.state = {
nodeOptions: {
name: null
},
data,
history: [data],
@ -65,7 +61,7 @@ export default class TreeMode extends Component {
h(Node, {
data: state.data,
events: state.events,
options: state.nodeOptions,
options: props.options,
parent: null,
prop: null
})
@ -322,13 +318,9 @@ export default class TreeMode extends Component {
* @param {SetOptions} [options]
*/
set (json, options = {}) {
const name = options && options.name || null // the root name
const data = jsonToData(json, options.expand || TreeMode.expand, [])
this.setState({
nodeOptions: setIn(this.state.nodeOptions, ['name'], name),
data: jsonToData(json, options.expand || TreeMode.expand, []),
data,
// TODO: do we want to keep history when .set(json) is called?
history: [],
historyIndex: 0

View File

@ -41,6 +41,7 @@
const mode = document.getElementById('mode').value
const container = document.getElementById('container')
const options = {
name: 'myObject',
onChange: function (patch, revert) {
console.log('onChange patch=', patch, ', revert=', revert)
window.patch = patch
@ -74,7 +75,6 @@
'url': 'http://jsoneditoronline.org'
}
editor.set(json, {
name: 'myObject',
expand: function (path) {
return true
}

View File

@ -2,6 +2,7 @@ import { h, render } from 'preact'
import CodeMode from './CodeMode'
import TextMode from './TextMode'
import TreeMode from './TreeMode'
import { compileJSONPointer, parseJSONPointer } from './jsonData'
import '!style!css!less!./jsoneditor.less'
@ -29,6 +30,11 @@ function jsoneditor (container, options = {}) {
const editor = {
isJSONEditor: true,
utils: {
compileJSONPointer,
parseJSONPointer
},
_container: container,
_options: options,
_modes: modes,

View File

@ -31,17 +31,19 @@
* }} JSONPatchResult
*
* @typedef {{
* name: string?,
* mode?: 'code' | 'form' | 'text' | 'tree' | 'view',
* modes?: string[],
* indentation?: number | string,
* onChange?: function (patch: JSONPatch, revert: JSONPatch),
* onChangeText?: function (),
* onChangeMode?: function (mode: string, prevMode: string),
* onError?: function (err: Error)
* onError?: function (err: Error),
* isPropertyEditable?: function (Path) : boolean
* isValueEditable?: function (Path) : boolean
* }} Options
*
* @typedef {{
* name: string?,
* expand: function (path: Path)?
* }} SetOptions
*/