Fix json components

This commit is contained in:
Tamius Han 2020-03-11 23:12:18 +01:00
parent e9dfd834f7
commit b353e6f34d
4 changed files with 128 additions and 69 deletions

View File

@ -1,32 +1,34 @@
<template> <template>
<div class="flex flex-column"> <div class="flex flex-column">
<div class="flex flex-row" @click="_expanded = !_expanded"> <div class="flex flex-row" @click="expanded_internal = !expanded_internal">
<div v-if="_value.key" class="item-key"> <div v-if="value_internal.key" class="item-key">
"{{_value.key}}" <b>:</b> "{{value_internal.key}}" <b>:</b>
<span v-if="!_expanded"><b> [</b> ... <b>]</b>,</span> <span v-if="!expanded_internal"><b> [</b> ... <b>]</b>,</span>
<template v-else><b>[</b></template> <template v-else><b>[</b></template>
</div> </div>
</div> </div>
<div v-for="(row, key) of _value.value" <div v-for="(row, key) of value_internal.value"
:key="key" :key="key"
> >
<JsonArray v-if="Array.isArray(row)" <JsonArray v-if="Array.isArray(row)"
value="{'key': key', 'value': row}" :value="row"
@change="changeItem(key, value)" @change="changeItem(rowKey, $event)"
> >
</JsonArray> </JsonArray>
<JsonObject v-else-if="typeof row === 'object' && row !== null" <JsonObject v-else-if="typeof row === 'object' && row !== null"
value="{'key': key, 'value': row}" :value="row"
@change="changeItem(key, value)" :label="rowKey"
@change="changeItem(rowKey, $event)"
> >
</JsonObject> </JsonObject>
<JsonElement v-else <JsonElement v-else
value="{'key': key, 'value': row}" :value="row"
@change="changeItem(key, value)" :label="rowKey"
@change="changeItem(rowKey, $event)"
> >
</JsonElement> </JsonElement>
</div> </div>
<div v-if="expanded"><b>],</b> <div v-if="expanded_internal"><b>],</b></div>
</div> </div>
</template> </template>
@ -46,25 +48,34 @@ export default {
}, },
data() { data() {
return { return {
_value: undefined, value_internal: undefined,
_expanded: true, expanded_internal: true,
} }
}, },
created() {
this.value_internal = this.value;
},
watch: { watch: {
value: function(val) { value: function(val) {
this._value = val; this.value_internal = val;
}, },
expanded: function(val) { expanded: function(val) {
if (val !== undefined && val !== null) { if (val !== undefined && val !== null) {
this._expanded = !!val; this.expanded_internal = !!val;
} }
} }
}, },
methods: { methods: {
changeItem(key, value) { changeItem(key, value) {
this._value.value[key] = value; this.value_internal[key] = value;
this.$emit('change', this._value.value); this.$emit('change', this.value_internal);
} }
} }
} }
</script> </script>
<style lang="scss" scoped>
@import url('./json.scss');
@import url('../../../res/css/flex.scss');
</style>

View File

@ -1,39 +1,42 @@
<template> <template>
<div class="flex flex-row"> <div class="flex flex-row json-level-indent">
<div v-if="_value.key" class="item-key"> <div>
"{{_value.key}}" <b>:</b> <b>
<span v-if="label" class="item-key">"{{label}}" </span>
:
</b>
</div> </div>
<div v-if="typeof _value.value === 'boolean'" <div v-if="typeof value_internal === 'boolean'"
class="json-value-boolean" class="json-value-boolean"
@click="toggleBoolean" @click="toggleBoolean"
> >
<template v-if="_value.value">true</template> <template v-if="value_internal">true</template>
<template v-else>false</template> <template v-else>false</template>
</div> </div>
<div v-else <div v-else
class="flex flex-row inline-edit" class="flex flex-row inline-edit"
:class="{ :class="{
'json-value-number': typeof _value.value === 'number', 'json-value-number': typeof value_internal === 'number',
'json-value-string': typeof _value.value === 'string' 'json-value-string': typeof value_internal === 'string'
}" }"
> >
<template v-if="editing"> <template v-if="editing">
<div ref="element-edit-area" <div ref="element-edit-area"
:contenteditable="editing" :contenteditable="editing"
> >
{{_value.value}} {{value_internal}}
</div> </div>
<div class="btn" @click="changeValue"> <div class="btn" @click="changeValue">
</div> </div>
</template> </template>
<template v-else> <template v-else>
<template v-if="typeof _value.value === 'string'"> <template v-if="typeof value_internal === 'string'">
"{{_value.value}}" "{{value_internal}}"
</template> </template>
<template v-else> <template v-else>
{{_value.value}} {{value_internal}}
</template> </template>,
</template> </template>
</div> </div>
</div> </div>
@ -44,34 +47,42 @@ export default {
name: 'json-element', name: 'json-element',
props: [ props: [
'value', 'value',
'label',
], ],
data() { data() {
return { return {
_value: undefined, value_internal: undefined,
editing: false, editing: false,
} }
}, },
created() {
this.value_internal = this.value;
},
watch: { watch: {
value: function(val) { value: function(val) {
this._value = val; this.value_internal = val;
} }
}, },
methods: { methods: {
toggleBoolean() { toggleBoolean() {
this._value.value = !this._value.value; this.value_internal = !this.value_internal;
this.$emit('change', this._value.value); this.$emit('change', this.value_internal);
}, },
changeValue() { changeValue() {
const newValue = this.$refs['element-edit-area'].textContent; const newValue = this.$refs['element-edit-area'].textContent;
if (isNaN(newValue)) { if (isNaN(newValue)) {
this._value.value = newValue; this.value_internal = newValue;
this.$emit('change', newValue); this.$emit('change', newValue);
} else { } else {
this._value.value = +newValue; this.value_internal.value = +newValue;
this.$emit('change', +newValue); this.$emit('change', +newValue);
} }
this.editing = false; this.editing = false;
} }
} }
} }
</script> </script>
<style lang="scss" scoped>
@import url('./json.scss');
</style>

View File

@ -1,32 +1,45 @@
<template> <template>
<div class="flex flex-column"> <div class="flex flex-column json-level-indent">
<div class="flex flex-row" @click="_expanded = !_expanded"> <div class="flex flex-row" @click="expanded_internal = !expanded_internal">
<div v-if="_value.key" class="item-key"> <div class="item-key-line">
"{{_value.key}}" <b>:</b> <template v-if="label">
<span v-if="!_expanded"><b> {</b> ... <b>}</b>,</span> <b>
<span class="item-key">"{{label}}"</span>
:
</b>
</template>
<span v-if="!expanded_internal"><b> {</b> ... <b>}</b>,</span>
<template v-else><b>{</b></template> <template v-else><b>{</b></template>
</div> </div>
</div> </div>
<div v-for="(row, key) of _value.value" <template v-if="expanded_internal">
:key="key" <div v-for="(row, rowKey) of value_internal"
> :key="rowKey"
<JsonArray v-if="Array.isArray(row)"
value="{'value': row}"
@change="changeItem(key, value)"
> >
</JsonArray> <pre>
<JsonObject v-else-if="typeof row === 'object' && row !== null" {label: {{rowKey}}, value: {{row}}}
value="{'key': key, 'value': row}" </pre>
@change="changeItem(key, value)" <JsonArray v-if="Array.isArray(row)"
> :value="row"
</JsonObject> @change="changeItem(rowKey, $event)"
<JsonElement v-else >
value="{'key': key, 'value': row}" </JsonArray>
@change="changeItem(key, value)" <JsonObject v-else-if="typeof row === 'object' && row !== null"
> :value="row"
</JsonElement> :label="rowKey"
</div> @change="changeItem(rowKey, $event)"
<div v-if="expanded"><b>},</b> >
</JsonObject>
<JsonElement v-else
:value="row"
:label="rowKey"
@change="changeItem(rowKey, $event)"
>
</JsonElement>
</div>
<div><b>},</b></div>
</template>
</div> </div>
</template> </template>
@ -38,6 +51,7 @@ export default {
name: 'JsonObject', name: 'JsonObject',
props: [ props: [
'value', 'value',
'label',
'expanded', 'expanded',
], ],
components: { components: {
@ -46,25 +60,32 @@ export default {
}, },
data() { data() {
return { return {
_value: undefined, value_internal: undefined,
_expanded: true, expanded_internal: true,
} }
}, },
created() {
this.value_internal = this.value;
},
watch: { watch: {
value: function(val) { value: function(val) {
this._value = val; this.value_internal = val;
}, },
expanded: function(val) { expanded: function(val) {
if (val !== undefined && val !== null) { if (val !== undefined && val !== null) {
this._expanded = !!val; this.expanded_internal = !!val;
} }
} }
}, },
methods: { methods: {
changeItem(key, value) { changeItem(key, value) {
this._value.value[key] = value; this.value_internal[key] = value;
this.$emit('change', this._value.value); this.$emit('change', this.value_internal);
} }
} }
} }
</script> </script>
<style lang="scss" scoped>
@import url('./json.scss');
</style>

View File

@ -0,0 +1,16 @@
.json-level-indent {
padding-left: 2em !important;
}
.item-key {
color: #fa6;
}
.json-value-boolean {
color: rgb(53, 179, 120);
}
.json-value-number {
color: rgb(73, 73, 160);
}
.json-value-string {
color: rgb(195, 35, 35);
}