1 2class Form { 3 constructor (elPath, sch, render=false) { 4 this.el = $(elPath); 5 this.fieldsWrapper = null; 6 this.actionBox = null; 7 this.submitBtn = null; 8 9 this.sch = sch; 10 this.fields = [] 11 12 if (render) this.render(); 13 else { 14 this.el.find('body'); 15 this.fieldsWrapper = this.el.find('.form__fields-wrapper'); 16 this.actionBox = this.el.find('.form__action-box'); 17 this.submitBtn = this.el.find('.form__submit-btn'); 18 19 this.loadFields(); 20 // this.fieldsWrapper.append(this.sch.fields.map(this.renderNode.bind(this))); 21 22 this.submitBtn.click(this.onSubmit.bind(this)); 23 } 24 25 } 26 27 freeze () { 28 this.fields.forEach(ff => ff.disable()); 29 } 30 31 loadFields () { 32 this.fields = this.sch.fields.map(this.loadField.bind(this)); 33 this.fields = this.fields.flat(); 34 } 35 36 loadField (fieldOpt) { 37 38 if (Array.isArray(fieldOpt)) { 39 40 return fieldOpt.map(this.loadField.bind(this)); 41 42 } 43 else { 44 45 let fieldEl = this.fieldsWrapper.find('.' + fieldOpt.name); 46 fieldOpt.el = fieldEl; 47 48 return new FormField(fieldOpt, false); 49 } 50 51 52 } 53 54 clearAllMessages () { 55 this.fields.forEach(ff => ff.clearMessages()); 56 } 57 58 renderNode (fieldOpt) { 59 if (Array.isArray(fieldOpt)) { 60 61 let fieldWrapper = $('<div class="form__fields-row"><div>'); 62 fieldWrapper.append(fieldOpt.map(this.renderNode.bind(this))); 63 64 return fieldWrapper; 65 66 } else { 67 68 let field = new FormField(fieldOpt, true); 69 this.fields.push(field); 70 71 return field.el; 72 73 } 74 } 75 76 render () { 77 78 this.formEl = $(` 79 <form> 80 <div class="form__fields-wrapper"></div> 81 <div class="form__action-box"> 82 <button class="form__submit-btn">${this.sch.submitBtnText}</button> 83 </div> 84 </form> 85 `); 86 this.fieldsWrapper = this.formEl.find('.form__fields-wrapper'); 87 this.actionBox = this.formEl.find('.form__action-box'); 88 this.submitBtn = this.formEl.find('.form__submit-btn'); 89 90 this.fieldsWrapper.append(this.sch.fields.map(this.renderNode.bind(this))); 91 this.el.append(this.formEl); 92 93 this.submitBtn.click(this.onSubmit.bind(this)); 94 95 } 96 97 onSubmit (event) { 98 event.preventDefault(); 99 100 this.clearAllMessages(); 101 102 if (this.validate()) { 103 this.sch.onSubmit(this.getValues(), this); 104 } 105 } 106 107 getField (fieldSlug) { 108 return this.fields.find(ff => ff.slug == fieldSlug); 109 } 110 111 getValues () { 112 return this.fields.reduce((acc, ff) => { 113 acc[ff.slug] = ff.getValue(); 114 return acc; 115 }, {}) 116 } 117 118 setValue (fieldSlug, value) { 119 this.getField(fieldSlug).setValue(value); 120 } 121 122 validate () { 123 124 let payload; 125 let fieldsValidation = this.fields.map(ff => { 126 payload = ff.validate(); 127 128 if (!payload.valid) { 129 ff.addMessage(payload.message, payload.type); 130 } 131 132 return payload; 133 }); 134 135 let valid = fieldsValidation.every(v => v.valid); 136 137 return valid; 138 } 139 140 switchAction (actionSlug) { 141 let action = this.sch.actions[actionSlug]; 142 143 action.onStart(this); 144 145 this.sch.onSubmit = action.onSubmit; 146 } 147 148 149} 150 151Form.addValidators = fieldOpt => { 152 if (Array.isArray(fieldOpt)) { 153 return fieldOpt.map(Form.addValidators); 154 } 155 else { 156 switch (fieldOpt.validators) { 157 case 'text': fieldOpt.validators = __validators.text(); break; 158 case 'email': fieldOpt.validators = __validators.email(); break; 159 default: fieldOpt.validator = []; 160 } 161 } 162 163 return fieldOpt; 164};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.