class SerializerField { /** * constructor * * @param {HTMLElement} f Input field (input|select|textarea) * @returns {SerializerField} */ constructor(f){ this.field = f; } /** * serialize * * @returns {(String|Number)} */ serialize(){ let type = this.field.getAttribute("type"); if(type == "number" || type == "range"){ return Number(this.field.value); } else if(type == "date" || type == "datetime-local" || type == "month" || type == "week") { return new Date(this.field.value); } else if(type == "checkbox") { return this.field.checked; } else { return this.field.value; } } } class Serializer { /** * constructor * * @param {HTMLElement} element * @returns {Serializer} */ constructor(element){ let fields = element.querySelectorAll(`:scope > input:not([type="submit"]), :scope > select, :scope > textarea, :scope > group`); this._fields = new Map(); for(let f of fields){ this.addField(f); } } /** * addField * * @param {HTMLElement} f */ addField(f){ let fieldName = f.getAttribute("name"); let isArray = fieldName.match(/^\[(\d*)\]/) let field; if(f.tagName == "GROUP"){ field = new Serializer(f) } else { field = new SerializerField(f); } if(isArray){ fieldName = fieldName.replace(/^\[(\d*)\]/, ''); if(!this._fields.has(fieldName)){ this._fields.set(fieldName, []) } if(isArray[1] != ""){ this._fields.get(fieldName)[isArray[1]] = field } else { this._fields.get(fieldName).push(field) } } else { this._fields.set(fieldName, field) } } /** * serialize * * @returns {Object} */ serialize(){ let json = {}; for(let [k, f] of this._fields){ if(Array.isArray(f)){ if(k != ""){ json[k] = []; } else { json = []; } for(let key in f){ if(f[key]){ if(k == ""){ json[key] = f[key].serialize() continue; } json[k][key] = f[key].serialize() } } } else { if(k == ""){ json = f.serialize() continue; } json[k] = f.serialize() } } return json; } }