JSON Editor

by wio_dude

HTML

<div>
  <label for="json-result">Result</label>
  <br/>
  <textarea id="json-result" cols="80" rows="15">null</textarea>
</div>
<div id="json-editor"></div>

JavaScript

const jsonEditor = document.getElementById('json-editor')
const jsonResult = document.getElementById('json-result')


class EditListener {
	constructor() {
  	this.handlers = []
  }
  
	onEdit(handler) {
  	this.handlers.push(handler)
  }
  
  dispatchEdit(value) {
  	for (const handler of this.handlers) {
    	handler(value)
    }
  }
  
}

class NullEditor {
	getValue() {
  	return null
  }
  
  onEdit() {}
  
  getDOM() {
  	return null
  }
}

class BooleanEditor extends EditListener {
	constructor(value = true) {
  	super()
    const dom = document.createElement('select')
    const booleanValues = {
    	true: true,
      false: false
    }
    for (const booleanValue of Object.keys(booleanValues)) {
    	const option = document.createElement('option')
      option.value = booleanValue
      option.innerHTML = booleanValue
      if (value === booleanValues[booleanValue]) {
      	option.selected = true
      }
      dom.appendChild(option)
    }
    dom.addEventListener('input', (evt) => {
    	this.setValue(booleanValues[this.dom.value])
    })
    this.value = value
    this.dom = dom
  }
  
  setValue(value) {
  	this.value = value
    this.dispatchEdit(value)
  }
  
  getValue() {
  	return this.value
  }
  
  getDOM() {
  	return this.dom
  }
}

class StringEditor extends EditListener {
	constructor(value = '') {
  	super()
    const dom = document.createElement('input')
    dom.type = 'text'
    dom.addEventListener('input', (evt) => {
    	this.setValue(this.dom.value)
    })
    dom.value = value
  	this.value = value
    this.dom = dom
  }
  
  setValue(value) {
  	this.value = value
    this.dispatchEdit(value)
  }
  
  getValue() {
  	return this.value
  }
  
  getDOM() {
  	return this.dom
  }
}

class NumberEditor extends EditListener {
	constructor(value = 0) {
  	super()
    const dom = document.createElement('input')
    dom.type = 'text'
    dom.addEventListener('input', (evt) => {
    	this.setValue(Number.parseFloat(this.dom.value))
    })
...