/* eslint-disable max-len */ import { Controller } from '@hotwired/stimulus' import { castBoolean } from '../../helpers/cast_boolean' export default class extends Controller { static targets = ['input', 'controller', 'rows'] fieldValue = [] options = {} get keyInputDisabled() { return !this.options.editable || this.options.disable_editing_keys } get valueInputDisabled() { return !this.options.editable } connect() { this.setOptions() try { const objectValue = JSON.parse(this.inputTarget.value) Object.keys(objectValue).forEach((key) => this.fieldValue.push([key, objectValue[key]])) } catch (error) { this.fieldValue = [] } this.updateKeyValueComponent() } addRow() { if (this.options.disable_adding_rows || !this.options.editable) return this.fieldValue.push(['', '']) this.updateKeyValueComponent() this.focusLastRow() } deleteRow(event) { if (this.options.disable_deleting_rows || !this.options.editable) return const { index } = event.params this.fieldValue.splice(index, 1) this.updateTextareaInput() this.updateKeyValueComponent() } focusLastRow() { return this.rowsTarget.querySelector('.flex.key-value-row:last-child .key-value-input-key').focus() } valueFieldUpdated(event) { const { value } = event.target const { index } = event.target.dataset this.fieldValue[index][1] = value this.updateTextareaInput() } keyFieldUpdated(event) { const { value } = event.target const { index } = event.target.dataset this.fieldValue[index][0] = value this.updateTextareaInput() } updateTextareaInput() { if (!this.hasInputTarget) return let result = {} if (this.fieldValue && this.fieldValue.length > 0) { result = Object.assign(...this.fieldValue.map(([key, val]) => ({ [key]: val }))) } this.inputTarget.innerText = JSON.stringify(result) } updateKeyValueComponent() { let result = '' let index = 0 this.fieldValue.forEach((row) => { const [key, value] = row result += this.interpolatedRow(key, value, index) index++ }) this.rowsTarget.innerHTML = result window.initTippy() } interpolatedRow(key, value, index) { let result = `
${this.inputField('key', index, key, value)} ${this.inputField('value', index, key, value)}` if (this.options.editable) { result += `` } result += '
' return result } inputField(id = 'key', index, key, value) { return `` } setOptions() { let fieldOptions try { fieldOptions = JSON.parse(this.controllerTarget.dataset.options) } catch (error) { fieldOptions = {} } this.options = { ...fieldOptions, inputClasses: this.controllerTarget.dataset.inputClasses, editable: castBoolean(this.controllerTarget.dataset.editable), } } }