Implemented `isValueEditable` and `isPropertyEditable`
This commit is contained in:
parent
4a12eed14f
commit
8f6ddf91bc
|
@ -1,7 +1,7 @@
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Custom editable fields | JSONEditor</title>
|
<title>Read-only properties and values | JSONEditor</title>
|
||||||
|
|
||||||
<script src="../dist/jsoneditor.js"></script>
|
<script src="../dist/jsoneditor.js"></script>
|
||||||
|
|
||||||
|
@ -27,26 +27,22 @@
|
||||||
var container = document.getElementById('jsoneditor');
|
var container = document.getElementById('jsoneditor');
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
onEditable: function (node) {
|
// all properties are editable except '_id' and 'name'
|
||||||
// node is an object like:
|
isPropertyEditable: function (path) {
|
||||||
// {
|
if (path.length === 1 && path[0] === '_id' || path[0] === 'name') {
|
||||||
// field: 'FIELD',
|
return false
|
||||||
// value: 'VALUE',
|
|
||||||
// path: ['PATH', 'TO', 'NODE']
|
|
||||||
// }
|
|
||||||
switch (node.field) {
|
|
||||||
case '_id':
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case 'name':
|
|
||||||
return {
|
|
||||||
field: false,
|
|
||||||
value: true
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
age: 32
|
||||||
}
|
}
|
||||||
|
|
||||||
var editor = jsoneditor(container, options, json)
|
var editor = jsoneditor(container, options)
|
||||||
|
editor.set(json)
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -114,7 +114,7 @@ export default class JSONNode extends Component {
|
||||||
this.renderActionMenuButton(),
|
this.renderActionMenuButton(),
|
||||||
this.renderProperty(prop, data, options),
|
this.renderProperty(prop, data, options),
|
||||||
this.renderSeparator(),
|
this.renderSeparator(),
|
||||||
this.renderValue(data.value)
|
this.renderValue(data.value, options)
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
@ -143,35 +143,35 @@ export default class JSONNode extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderProperty (prop, data, options) {
|
renderProperty (prop, data, options) {
|
||||||
if (prop !== null) {
|
if (prop === null) {
|
||||||
const isIndex = typeof prop === 'number' // FIXME: pass an explicit prop isIndex
|
|
||||||
|
|
||||||
if (isIndex) { // array item
|
|
||||||
return h('div', {
|
|
||||||
class: 'jsoneditor-property jsoneditor-readonly',
|
|
||||||
spellCheck: 'false'
|
|
||||||
}, prop)
|
|
||||||
}
|
|
||||||
else { // object property
|
|
||||||
const escapedProp = escapeHTML(prop)
|
|
||||||
|
|
||||||
return h('div', {
|
|
||||||
class: 'jsoneditor-property' + (prop.length === 0 ? ' jsoneditor-empty' : ''),
|
|
||||||
contentEditable: 'true',
|
|
||||||
spellCheck: 'false',
|
|
||||||
onBlur: this.handleChangeProperty
|
|
||||||
}, escapedProp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// root node
|
// root node
|
||||||
const content = JSONNode.getRootName(data, options)
|
const rootName = JSONNode.getRootName(data, options)
|
||||||
|
|
||||||
return h('div', {
|
return h('div', {
|
||||||
class: 'jsoneditor-property jsoneditor-readonly',
|
class: 'jsoneditor-property jsoneditor-readonly',
|
||||||
spellCheck: 'false',
|
spellCheck: 'false',
|
||||||
onBlur: this.handleChangeProperty
|
onBlur: this.handleChangeProperty
|
||||||
}, content)
|
}, rootName)
|
||||||
|
}
|
||||||
|
|
||||||
|
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', {
|
||||||
|
class: 'jsoneditor-property' + (prop.length === 0 ? ' jsoneditor-empty' : ''),
|
||||||
|
contentEditable: 'true',
|
||||||
|
spellCheck: 'false',
|
||||||
|
onBlur: this.handleChangeProperty
|
||||||
|
}, escapedProp)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return h('div', {
|
||||||
|
class: 'jsoneditor-property jsoneditor-readonly',
|
||||||
|
spellCheck: 'false'
|
||||||
|
}, prop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,22 +179,31 @@ export default class JSONNode extends Component {
|
||||||
return h('div', {class: 'jsoneditor-separator'}, ':')
|
return h('div', {class: 'jsoneditor-separator'}, ':')
|
||||||
}
|
}
|
||||||
|
|
||||||
renderValue (value) {
|
renderValue (value, options) {
|
||||||
const escapedValue = escapeHTML(value)
|
const escapedValue = escapeHTML(value)
|
||||||
const type = valueType (value)
|
const type = valueType (value)
|
||||||
const itsAnUrl = isUrl(value)
|
const itsAnUrl = isUrl(value)
|
||||||
const isEmpty = escapedValue.length === 0
|
const isEmpty = escapedValue.length === 0
|
||||||
|
|
||||||
return h('div', {
|
const editable = !options.isValueEditable || options.isValueEditable(this.getPath())
|
||||||
class: JSONNode.getValueClass(type, itsAnUrl, isEmpty),
|
if (editable) {
|
||||||
contentEditable: 'true',
|
return h('div', {
|
||||||
spellCheck: 'false',
|
class: JSONNode.getValueClass(type, itsAnUrl, isEmpty),
|
||||||
onBlur: this.handleChangeValue,
|
contentEditable: 'true',
|
||||||
onInput: this.updateValueStyling,
|
spellCheck: 'false',
|
||||||
onClick: this.handleClickValue,
|
onBlur: this.handleChangeValue,
|
||||||
onKeyDown: this.handleKeyDownValue,
|
onInput: this.updateValueStyling,
|
||||||
title: itsAnUrl ? JSONNode.URL_TITLE : null
|
onClick: this.handleClickValue,
|
||||||
}, escapedValue)
|
onKeyDown: this.handleKeyDownValue,
|
||||||
|
title: itsAnUrl ? JSONNode.URL_TITLE : null
|
||||||
|
}, escapedValue)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return h('div', {
|
||||||
|
class: 'jsoneditor-readonly',
|
||||||
|
title: itsAnUrl ? JSONNode.URL_TITLE : null
|
||||||
|
}, escapedValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -431,6 +440,10 @@ export default class JSONNode extends Component {
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isFieldEditable () {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of the target of an event, and convert it to it's type
|
* Get the value of the target of an event, and convert it to it's type
|
||||||
* @param event
|
* @param event
|
||||||
|
|
|
@ -21,10 +21,6 @@ export default class TreeMode extends Component {
|
||||||
const data = jsonToData(this.props.data || {}, expand, [])
|
const data = jsonToData(this.props.data || {}, expand, [])
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
nodeOptions: {
|
|
||||||
name: null
|
|
||||||
},
|
|
||||||
|
|
||||||
data,
|
data,
|
||||||
|
|
||||||
history: [data],
|
history: [data],
|
||||||
|
@ -65,7 +61,7 @@ export default class TreeMode extends Component {
|
||||||
h(Node, {
|
h(Node, {
|
||||||
data: state.data,
|
data: state.data,
|
||||||
events: state.events,
|
events: state.events,
|
||||||
options: state.nodeOptions,
|
options: props.options,
|
||||||
parent: null,
|
parent: null,
|
||||||
prop: null
|
prop: null
|
||||||
})
|
})
|
||||||
|
@ -322,13 +318,9 @@ export default class TreeMode extends Component {
|
||||||
* @param {SetOptions} [options]
|
* @param {SetOptions} [options]
|
||||||
*/
|
*/
|
||||||
set (json, options = {}) {
|
set (json, options = {}) {
|
||||||
const name = options && options.name || null // the root name
|
|
||||||
const data = jsonToData(json, options.expand || TreeMode.expand, [])
|
|
||||||
|
|
||||||
this.setState({
|
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?
|
// TODO: do we want to keep history when .set(json) is called?
|
||||||
history: [],
|
history: [],
|
||||||
historyIndex: 0
|
historyIndex: 0
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
const mode = document.getElementById('mode').value
|
const mode = document.getElementById('mode').value
|
||||||
const container = document.getElementById('container')
|
const container = document.getElementById('container')
|
||||||
const options = {
|
const options = {
|
||||||
|
name: 'myObject',
|
||||||
onChange: function (patch, revert) {
|
onChange: function (patch, revert) {
|
||||||
console.log('onChange patch=', patch, ', revert=', revert)
|
console.log('onChange patch=', patch, ', revert=', revert)
|
||||||
window.patch = patch
|
window.patch = patch
|
||||||
|
@ -74,7 +75,6 @@
|
||||||
'url': 'http://jsoneditoronline.org'
|
'url': 'http://jsoneditoronline.org'
|
||||||
}
|
}
|
||||||
editor.set(json, {
|
editor.set(json, {
|
||||||
name: 'myObject',
|
|
||||||
expand: function (path) {
|
expand: function (path) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { h, render } from 'preact'
|
||||||
import CodeMode from './CodeMode'
|
import CodeMode from './CodeMode'
|
||||||
import TextMode from './TextMode'
|
import TextMode from './TextMode'
|
||||||
import TreeMode from './TreeMode'
|
import TreeMode from './TreeMode'
|
||||||
|
import { compileJSONPointer, parseJSONPointer } from './jsonData'
|
||||||
|
|
||||||
import '!style!css!less!./jsoneditor.less'
|
import '!style!css!less!./jsoneditor.less'
|
||||||
|
|
||||||
|
@ -29,6 +30,11 @@ function jsoneditor (container, options = {}) {
|
||||||
const editor = {
|
const editor = {
|
||||||
isJSONEditor: true,
|
isJSONEditor: true,
|
||||||
|
|
||||||
|
utils: {
|
||||||
|
compileJSONPointer,
|
||||||
|
parseJSONPointer
|
||||||
|
},
|
||||||
|
|
||||||
_container: container,
|
_container: container,
|
||||||
_options: options,
|
_options: options,
|
||||||
_modes: modes,
|
_modes: modes,
|
||||||
|
|
|
@ -31,17 +31,19 @@
|
||||||
* }} JSONPatchResult
|
* }} JSONPatchResult
|
||||||
*
|
*
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
|
* name: string?,
|
||||||
* mode?: 'code' | 'form' | 'text' | 'tree' | 'view',
|
* mode?: 'code' | 'form' | 'text' | 'tree' | 'view',
|
||||||
* modes?: string[],
|
* modes?: string[],
|
||||||
* indentation?: number | string,
|
* indentation?: number | string,
|
||||||
* onChange?: function (patch: JSONPatch, revert: JSONPatch),
|
* onChange?: function (patch: JSONPatch, revert: JSONPatch),
|
||||||
* onChangeText?: function (),
|
* onChangeText?: function (),
|
||||||
* onChangeMode?: function (mode: string, prevMode: string),
|
* onChangeMode?: function (mode: string, prevMode: string),
|
||||||
* onError?: function (err: Error)
|
* onError?: function (err: Error),
|
||||||
|
* isPropertyEditable?: function (Path) : boolean
|
||||||
|
* isValueEditable?: function (Path) : boolean
|
||||||
* }} Options
|
* }} Options
|
||||||
*
|
*
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
* name: string?,
|
|
||||||
* expand: function (path: Path)?
|
* expand: function (path: Path)?
|
||||||
* }} SetOptions
|
* }} SetOptions
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue