UNPKG

adhara

Version:

foundation for any kind of website: microframework

199 lines (174 loc) 5.55 kB
class AdharaMutableView extends AdharaView{ /** * @constructor * @param {Object} [settings] * @param {String} [settings.name] - field name * @param {String} [settings.key=undefined] - Instance key * @param {String} settings.c - CSS Selector from parent view to place content of this class * @param {String} [settings.fields=[]] - CSS Selector from parent view to place content of this class * */ constructor(settings = {}) { settings.key = settings.key || settings.name; super(settings); this.parentContainer = this.parentContainer || `[data-field="${settings.name}"]`; this._name = settings.name; this._fields = settings.fields; this.mutator = null; this._registerEvents(["Saved", "Cancelled"]); } onInit(){ this._mutable_data = {}; this.fieldMap = {}; this.rendered_fields = []; } get name(){ return this._name || ""; } get fullName(){ return ((this.mutator&&this.mutator.name)?(this.mutator.name+"."):"")+this.name; } get safeName(){ return this.name.replace('.', '-'); } get key(){ return this.name; } /** * @example * get fields(){ * return [ * InputField("question", {}, {}), * TextArea("answer", {}, {}) * ]; * } * returns {Array<FormField>} * */ get fields(){ return this._fields || []; } isFormField(f){ return (f instanceof FormField || f instanceof AdharaMutableView); } get mutableFields(){ return this.fields.filter(this.isFormField); } set mutableData(_){ this._mutable_data = _; } get mutableData(){ return this._mutable_data; } /** * @returns {*} Field data * */ getFieldValue(field_name){ let d = getValueFromJSON(this.mutableData, this.fieldMap[field_name].name); if(d===undefined){ d = this.fieldMap[field_name].value; } return d; } get ignoreNulls(){ return false; } /** * @returns {*} Field data * */ setFieldValue(field_name, value){ let field = this.formElement[field_name]; if(field.type==="checkbox"){ field.checked = true; }else{ field.value = value; } } getFormData(){ let hasFiles = false; for(let rendered_field of this.rendered_fields){ if(rendered_field instanceof InputField && rendered_field.config.input_type === InputField.FILE){ hasFiles = true; } } if(hasFiles){ let formData = new FormData(); for(let [key, value] of Object.entries(data)){ formData.append(key, value); } return formData; } } get hasFileFields(){ for(let rendered_field of this.rendered_fields){ if(rendered_field instanceof InputField && rendered_field.config.input_type === InputField.FILE){ return true; } } return false; } getMutatedData(){ let hasFiles = this.hasFileFields; let data = hasFiles?new FormData():{}; for(let field of this.rendered_fields){ let serialized_value = (field instanceof AdharaMutableView)?field.getMutatedData():field.serialize(); if((!this.ignoreNulls || serialized_value!==null)){ if(hasFiles){ if(field.config.input_type === InputField.FILE && field.fieldAttributes.multiple==="true"){ if(serialized_value){ for(let file of serialized_value){ data.append(field.name, file); } } }else{ data.append(field.name, serialized_value); } }else{ setValueToJson(data, field.name, serialized_value); } } } return data; } getField(field_name){ return this.fieldMap[field_name]; } /** * @getter * @param {*} data to be submitted destination * @returns {Promise} response on submission. * */ async submitData(data){ throw new Error("Must override `submitData`"); } /** * @param {FormField} field * */ enhanceFieldForSubViewRendering(field){ this.fieldMap[field.name] = field; field.mutator = this; let _v = this.getFieldValue(field.name); if(field instanceof AdharaMutableView){ if(_v && _v instanceof Array && _v.length){ field.mutableData = _v; } }else{ field.value = _v; } return field; } get subViews(){ let fields = this.mutableFields.map((_) => this.enhanceFieldForSubViewRendering(_)); this.rendered_fields = fields.slice(); return fields; } onMutableDataChanged(){ // Can override if required... } onFieldValueChanged(field_name, value, old_value){ // can override as required } _onFieldValueChanged(field_name, value, old_value, {event, data}={}){ setValueToJson(this._mutable_data, this.fieldMap[field_name].name, value); this.onFieldValueChanged(field_name, value, old_value); this.onMutableDataChanged(); } }