"json-editor"๋ ์น๋ธ๋ผ์ฐ์ ์์ json ๋ฐ์ดํฐ๋ฅผ ํธ์งํ๋ ์๋ํฐ์
๋๋ค.
ํ
์คํธ ํธ์งํด์ ์ฌ์ฉํ ์ ์๊ฑฐ๋ json ๋ฐ์ดํฐ๋ฅผ ์์ฝ๊ฒ ๋ค๋ฃจ๊ธฐ ์ํ์ฌ ๋ง๋ค์ด์ง ํ๋ก๊ทธ๋จ ์
๋๋ค.
์ด ์๋ํฐ๋ ๋
๋ฆฝ์ ์ผ๋ก ๋์ํ๋ฉฐ ๋ฉ์๋๋ฅผ ์คํํ์ฌ ์๋ํฐ์ ๊ธฐ๋ฅ์ ์กฐ์ํ ์ ์์ต๋๋ค.
๊ถ์ฅ๋๋ ์ฌ์ฉํ๊ฒฝ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๋ฐ์คํฌํ
- ํฐ ํ๋ฉด์ ํ๋ธ๋ฆฟ
์๋ํฐ๊ฐ ์ด๋ป๊ฒ ์ฌ์ฉ๋๋์ง ๋ฐ๋ชจ๋ฅผ ํ์ธํด๋ณผ ์ ์์ต๋๋ค. ๋ฐ๋ชจํ์ด์ง์์ ์์๋ก ์๋ํฐ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ฐ๋ชจ๋งํฌ: https://redgoose-dev.github.io/json-editor/
javascript์ css๋ฅผ ๋ถ๋ฌ์์ ํด๋์ค ์ธ์คํด์ค๋ฅผ ๋ง๋๋ ๋ฐฉ์์ผ๋ก ์์ํฉ๋๋ค.
import JsonEditor from '@redgoose/json-editor'
import '@redgoose/json-editor/css'
const jsonEditor = new JsonEditor(document.getElementById('target'), {
live: true,
theme: 'system',
edit: 'all',
node: {},
openDepth: 2,
})
์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ ๋์ ์ฌ์ฉํ๋ ์ต์ ๊ฐ์ ๋๋ค.
live
/ (true,false)
์ด ๊ฐ์ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๊ฐ ์ ๋ฐ์ดํธ ๋ ๋๋ง๋คupdate
๋ฉ์๋๊ฐ ํธ์ถ๋๋ฉด์ ์ ๋ฐ์ดํธ ์ด๋ฒคํธ๋ฅผ ํธ์ถํฉ๋๋ค.theme
/ (system,light,dark)
๋คํฌ๋ชจ๋๋ฅผ ์ฌ์ฉํ๋์ง์ ๋ํ ๊ฐ์ ๋๋ค.edit
/ (all,value,none)
์ปจํธ๋กคํ ์ ์๋ ๋ฒ์๋ฅผ ์ ํฉ๋๋ค.node
/ ({},[])
ํด๋์ค๋ฅผ ์ด๊ธฐํํ ๋ ์ฌ์ฉํ๋ ๋ ธ๋ ๋ฐ์ดํฐ ๊ฐ์ ๋๋ค.openDepth
/ 0
x๋ฒ์งธ ๋์ค์ ๋ ธ๋๊ฐ ์ด๋ฆฌ๋์ง์ ๋ํ์ฌ ์ ํฉ๋๋ค.
์ธ์คํด์ค์์ ์ฌ์ฉํ ์ ์๋ ๋ฉ์๋๋ค์ด๋ฉฐ ํ์ํ ๋์ ์ ์ ํ ์ฌ์ฉํ ์ ์์ต๋๋ค. (์๋๋ฉด ํด๋์ค ํ๋กํ ํ์
์ผ๋ก ๋ฏธ๋ฆฌ ํ์ฅํด๋ ์ ์์ต๋๋ค.)
์ฌ์ฉํ ์ ์๋ ๊ณต๊ฐ ๋ฉ์๋๋ค์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
ps. ๋จผ์ ์์ค์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์ํฉ๋๋ค.
const jsonEditor = new JsonEditor() const node = document.querySelector('.node') // node
object
, array
๋
ธ๋์์ ์์ ๋
ธ๋๋ฅผ ์ถ๊ฐํฉ๋๋ค.
jsonEditor.addNode(node, data, options, useUpdate, useUpdateCount)
node
: ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ ๋ ธ๋ ์๋ฆฌ๋จผํธdata
: ์ถ๊ฐํ ๋ฐ์ดํฐoptions
: ์ถ๊ฐ์ต์ useUpdate
: ๋ ธ๋๋ฅผ ์ถ๊ฐํ๊ณ ์ ๋ฐ์ดํธ ๋ฉ์๋๋ฅผ ์คํํฉ๋๋ค.useUpdateCount
: ๋ถ๋ชจ๋ ธ๋ ๋ฐ์ดํฐ ๊ฐฏ์๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
jsonEditor.addNode(
node,
{ key: '', type: 'string', value: 'metal' },
options,
true,
true
)
๋ ธ๋๋ฅผ ์ญ์ ํฉ๋๋ค.
jsonEditor.removeNode(node, useUpdate)
node
: ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ ๋ ธ๋ ์๋ฆฌ๋จผํธuseUpdate
: ๋ ธ๋๋ฅผ ์ญ์ ํ๊ณ ์ ๋ฐ์ดํธ ๋ฉ์๋๋ฅผ ์คํํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
jsonEditor.removeNode(node, true)
๋ ธ๋์ ํ์ ์ ๋ณ๊ฒฝํฉ๋๋ค.
jsonEditor.changeType(node, type, useUpdate)
node
: ํ์ ์ ๋ณ๊ฒฝํ ๋ ธ๋ ์๋ฆฌ๋จผํธtype
: ํ์ ์ ์ด๋ฆ (object,array,string,number,boolean,null)useUpdate
: ๋ ธ๋ ํ์ ์ ๋ณ๊ฒฝํ๊ณ ์ ๋ฐ์ดํธ ๋ฉ์๋๋ฅผ ์คํํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
jsonEditor.changeType(node, 'boolean', true)
๋
ธ๋์ key
๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค.
jsonEditor.changeKey(node, keyword)
node
: ํ์ ์ ๋ณ๊ฒฝํ ๋ ธ๋ ์๋ฆฌ๋จผํธkeyword
: ํค์๋
๋
ธ๋์ value
๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค.
jsonEditor.changeValue(node, value)
node
: ํ์ ์ ๋ณ๊ฒฝํ ๋ ธ๋ ์๋ฆฌ๋จผํธvalue
: ๊ฐ
๋ ธ๋๋ฅผ ๋ณต์ ํฉ๋๋ค.
jsonEditor.duplicate(node, useUpdate)
node
: ๋ณต์ ํ ๋ ธ๋ ์๋ฆฌ๋จผํธuseUpdate
: ์คํํ๊ณ ์ ๋ฐ์ดํธ ๋ฉ์๋๋ฅผ ์คํํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
jsonEditor.duplicate(node, true)
๋ ธ๋๋ฅผ ์ ๊ฑฐ๋ ํผ์นฉ๋๋ค.
jsonEditor.fold(node, true)
๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
jsonEditor.import(node, data, useUpdate, useUpdateCount)
node
: ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ ๋ ธ๋ ์๋ฆฌ๋จผํธdata
: ๊ฐ์ ธ์ฌ ๋ฐ์ดํฐuseUpdate
: ๋ ธ๋๋ฅผ ์ถ๊ฐํ๊ณ ์ ๋ฐ์ดํธ ๋ฉ์๋๋ฅผ ์คํํฉ๋๋ค.useUpdateCount
: ๋ถ๋ชจ๋ ธ๋ ๋ฐ์ดํฐ ๊ฐฏ์๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
jsonEditor.import(node, { foo: 'bar' }, true, true)
๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ ๊ต์ฒดํฉ๋๋ค.
jsonEditor.replace(data, options, useUpdate)
data
: ์๋ก ๊ต์ฒดํ ๋ฐ์ดํฐoptions
: ์ต์ openDepth
: ๋ฐ์ดํฐ๊ฐ ๊ต์ฒด๋ ๋ ๋ ธ๋๊ฐ ์ด๋ฆฌ๋ x๋ฒ์งธ ๋์ค
useUpdate
: ๋ ธ๋๋ฅผ ์์ ํ๊ณ ์ ๋ฐ์ดํธ ๋ฉ์๋๋ฅผ ์คํํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
jsonEditor.replace({ foo: 'bar' }, {
openDepth: 2,
}, true)
์๋ํฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
jsonEditor.export(node, json, space)
node
: ๊ฐ์ ธ์ฌ ๋ฐ์ดํฐ์ ๋ ธ๋ ์๋ฆฌ๋จผํธjson
: json ํ์์ ๋ฐ์ดํฐ ๋ณํ์ฌ๋ถspace
: json ๊ณต๋ฐฑ
๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
const space = 2 // null,2,'\t'
jsonEditor.export(node, true, space)
๋ ธ๋์ ๋ด์ฉ์ ๋น์๋๋ค.
jsonEditor.clear()
๋ง๋ค์ด์ง ์ธ์คํด์ค๋ฅผ ํ๊ดดํฉ๋๋ค.
jsonEditor.destroy()
์๋ํฐ์์ ์ผ์ด๋ ์ผ๋ค์ ์ธ๋ถ์์ ์ด๋ฒคํธ๋ฆฌ์ค๋๋ก ๋ฐ์์ฌ ์ ์์ต๋๋ค.
ps. ๋จผ์ ์์ค์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์ํฉ๋๋ค.
const jsonEditor = new JsonEditor() const wrap = jsonEditor.el.wrap.get(0) // wrap element
์๋ํฐ์ ๋ด์ฉ์ด ์์ ๋๋ค๋ฉด ์คํ๋๋ ์ด๋ฒคํธ์ ๋๋ค.
wrap.addEventListener('update', ({ detail }) => {
console.log('updated data', src)
})
detail
: ๋ฐ์ดํฐ ๊ฐ์ฒด
์ปจํ ์คํธ ๋ฉ๋ด๊ฐ ์ด๋ฆด๋๋ง๋ค ์คํ๋๋ ์ด๋ฒคํธ์ ๋๋ค. ๋ฉ๋ด๋ฅผ ์ปค์คํฐ๋ง์ด์ฆ ํ ์ ์์ผ๋ฉฐ ์ ๊ณต๋ ํ๋ผ๋ฉํฐ ๊ฐ์ ์ด์ฉํ์ฌ ์ํฉ์ ๋ง๊ฒ ๋ฉ๋ด๋ฅผ ์กฐ์ํ ์ ์์ต๋๋ค.
wrap.addEventListener('context', ({ detail: { body, node, type, isRoot, $ } }) => {
if (!isRoot) return
const $ul = $(body).children()
const $items = $(`
<li><button type="button" data-key="#1">custom #1</button></li>
<li><button type="button" data-key="#2">custom #2</button></li>
`)
$items.find('button').on('click', (e) => {
console.log('click item-key:', $(e.currentTarget).data('key'))
jsonEditor.context.close()
})
$ul.append($items)
})
body
: ์ด๋ฆฐ ์ปจํ ์คํธ ๋ฉ๋ด ์์ญ. ์ด ์๋ฆฌ๋จผํธ์๋ค ํญ๋ชฉ์ ์กฐ์ํ๋ฉด ๋ฉ๋๋ค.node
: ์ ํ๋ ๋ ธ๋ ์๋ฆฌ๋จผํธtype
: ์ ํ๋ ๋ ธ๋์ ํ์isRoot
: ํ์ฌ ์ ํ๋ ๋ ธ๋๊ฐ ๋ฃจํธ์ธ์ง ๊ตฌ๋ถํ๋ ๊ฐ$
: ์ปดํฌ๋ํธ ๋ด๋ถ์์ ์ฌ์ฉํ๋ Cash๋ฅผ ์ด์ฉํ์ฌ ์์ฝ๊ฒ dom์ ๋ค๋ฃฐ ์ ์์ต๋๋ค.
๋ค์ ๊ฒฝ๋ก๋ฅผ ์ฐธ๊ณ ํ์ฌ ๋ชจ๋๋ค์ import ๊ธฐ๋ฅ์ ์ด์ฉํ๋๋ฐ ์ฐธ๊ณ ํ ์ ์์ต๋๋ค.
@redgoose/json-editor
: ์ฝ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ@redgoose/json-editor/css
: ์คํ์ผ์ํธ@redgoose/json-editor/lib/umd
: ์ฝ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ UMD
์๋ํฐ์ ๋์์ธ์ ์์ ํ ์ ์๋ ์์๋ค์ ๋ณ์ํ ์์ผฐ์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์ธ๋ถ ์์ญ์์ ์๋ํฐ ์คํ์ผ์ ์ปค์คํฐ๋ง์ด์ฆ ํ ์ ์์ต๋๋ค.
.editor {
--json-editor-color-base: red;
--json-editor-color-focus: blue;
}
@media (prefers-color-scheme: dark) {
.editor {
--json-editor-color-base: green;
--json-editor-color-focus: yellow;
}
}
main.scss ํ์ผ์ ์ฝ๋๋ฅผ ์ฐธ๊ณ ํ์ฌ ์ง์ ์คํ์ผ์ ํธ์งํ ์ ์์ต๋๋ค.
ํด๋์ค ๋ฉ์๋๋ฅผ ๊ต์ฒดํ์ฌ ์๋ํฐ ํ ์คํธ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
JsonEditor.prototype.updateLanguage = function()
{
this.lang = Object.assign(this.lang, {
nodeChangeSort: '๋
ธ๋ ์์๋ณ๊ฒฝ',
nodeContextMenu: '๋
ธ๋๋ฉ๋ด',
nodeFold: '์ ๊ธฐ/ํผ์น๊ธฐ',
contextChangeType: 'ํ์
๋ณ๊ฒฝ',
contextInsertNode: '๋
ธ๋์ถ๊ฐ',
contextTypeObject: '๊ฐ์ฒด',
contextTypeArray: '๋ฐฐ์ด',
contextTypeString: '๋ฌธ์',
contextTypeNumber: '๋ฒํธ',
contextTypeBoolean: '๋ถ์ธ',
contextTypeNull: '๋',
contextDuplicate: '๋
ธ๋๋ณต์ ',
contextRemove: '๋
ธ๋์ญ์ ',
})
}
JSON Editor
์๋ํฐ๋ฅผ web component
, react
, vue
, svelte
๊ฐ์ ํ๊ฒฝ์์ ์ฌ์ฉํ ์ ์๋๋ก ์ปดํฌ๋ํธ๋ฅผ ๋ํํ ์ ์์ต๋๋ค.
๋ค์ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ์ฌ ๊ฐ๋ฐํ ์ ์์ต๋๋ค.