Add json structure editor

This commit is contained in:
Tamius Han 2020-03-11 00:15:53 +01:00
parent 7b845553e2
commit c9b354e06a
3 changed files with 217 additions and 0 deletions

View File

@ -0,0 +1,70 @@
<template>
<div class="flex flex-column">
<div class="flex flex-row" @click="_expanded = !_expanded">
<div v-if="_value.key" class="item-key">
"{{_value.key}}" <b>:</b>
<span v-if="!_expanded"><b> [</b> ... <b>]</b>,</span>
<template v-else><b>[</b></template>
</div>
</div>
<div v-for="(row, key) of _value.value"
:key="key"
>
<JsonArray v-if="Array.isArray(row)"
value="{'key': key', 'value': row}"
@change="changeItem(key, value)"
>
</JsonArray>
<JsonObject v-else-if="typeof row === 'object' && row !== null"
value="{'key': key, 'value': row}"
@change="changeItem(key, value)"
>
</JsonObject>
<JsonElement v-else
value="{'key': key, 'value': row}"
@change="changeItem(key, value)"
>
</JsonElement>
</div>
<div v-if="expanded"><b>],</b>
</div>
</template>
<script>
import JsonObject from './JsonObject';
import JsonElement from './JsonElement';
export default {
name: 'JsonArray',
props: [
'value',
'expanded',
],
components: {
JsonObject,
JsonElement,
},
data() {
return {
_value: undefined,
_expanded: true,
}
},
watch: {
value: function(val) {
this._value = val;
},
expanded: function(val) {
if (val !== undefined && val !== null) {
this._expanded = !!val;
}
}
},
methods: {
changeItem(key, value) {
this._value.value[key] = value;
this.$emit('change', this._value.value);
}
}
}
</script>

View File

@ -0,0 +1,77 @@
<template>
<div class="flex flex-row">
<div v-if="_value.key" class="item-key">
"{{_value.key}}" <b>:</b>
</div>
<div v-if="typeof _value.value === 'boolean'"
class="json-value-boolean"
@click="toggleBoolean"
>
<template v-if="_value.value">true</template>
<template v-else>false</template>
</div>
<div v-else
class="flex flex-row inline-edit"
:class="{
'json-value-number': typeof _value.value === 'number',
'json-value-string': typeof _value.value === 'string'
}"
>
<template v-if="editing">
<div ref="element-edit-area"
:contenteditable="editing"
>
{{_value.value}}
</div>
<div class="btn" @click="changeValue">
</div>
</template>
<template v-else>
<template v-if="typeof _value.value === 'string'">
"{{_value.value}}"
</template>
<template v-else>
{{_value.value}}
</template>
</template>
</div>
</div>
</template>
<script>
export default {
name: 'json-element',
props: [
'value',
],
data() {
return {
_value: undefined,
editing: false,
}
},
watch: {
value: function(val) {
this._value = val;
}
},
methods: {
toggleBoolean() {
this._value.value = !this._value.value;
this.$emit('change', this._value.value);
},
changeValue() {
const newValue = this.$refs['element-edit-area'].textContent;
if (isNaN(newValue)) {
this._value.value = newValue;
this.$emit('change', newValue);
} else {
this._value.value = +newValue;
this.$emit('change', +newValue);
}
this.editing = false;
}
}
}
</script>

View File

@ -0,0 +1,70 @@
<template>
<div class="flex flex-column">
<div class="flex flex-row" @click="_expanded = !_expanded">
<div v-if="_value.key" class="item-key">
"{{_value.key}}" <b>:</b>
<span v-if="!_expanded"><b> {</b> ... <b>}</b>,</span>
<template v-else><b>{</b></template>
</div>
</div>
<div v-for="(row, key) of _value.value"
:key="key"
>
<JsonArray v-if="Array.isArray(row)"
value="{'value': row}"
@change="changeItem(key, value)"
>
</JsonArray>
<JsonObject v-else-if="typeof row === 'object' && row !== null"
value="{'key': key, 'value': row}"
@change="changeItem(key, value)"
>
</JsonObject>
<JsonElement v-else
value="{'key': key, 'value': row}"
@change="changeItem(key, value)"
>
</JsonElement>
</div>
<div v-if="expanded"><b>},</b>
</div>
</template>
<script>
import JsonArray from './JsonArray';
import JsonElement from './JsonElement';
export default {
name: 'JsonObject',
props: [
'value',
'expanded',
],
components: {
JsonArray,
JsonElement,
},
data() {
return {
_value: undefined,
_expanded: true,
}
},
watch: {
value: function(val) {
this._value = val;
},
expanded: function(val) {
if (val !== undefined && val !== null) {
this._expanded = !!val;
}
}
},
methods: {
changeItem(key, value) {
this._value.value[key] = value;
this.$emit('change', this._value.value);
}
}
}
</script>