22div.vue-form-generator ( v-if ='schema != null' )
33fieldset( v-if ="schema.fields" , :is ='tag' )
44template( v-for ='field in fields' )
5- .form-group ( v-if ='fieldVisible(field)' , :class ='getFieldRowClasses(field)' )
6- label( v-if ="fieldTypeHasLabel(field)" , :for ="getFieldID(field)" , :class ="field.labelClasses" )
7- | {{ field.label }}
8- span.help ( v-if ='field.help' )
9- i.icon
10- .helpText ( v-html ='field.help' )
11- .field-wrap
12- component( :is ='getFieldType(field)' , :disabled ='fieldDisabled(field)' , :model ='model' , :schema ='field' , :formOptions ='options' , @model-updated ='modelUpdated' , @validated ="onFieldValidated" )
13- .buttons ( v-if ='buttonVisibility(field)' )
14- button( v-for ='btn in field.buttons' , @click ='buttonClickHandler(btn, field, $event)' , :class ='btn.classes' ) {{ btn.label }}
15- .hint ( v-if ='field.hint' ) {{ fieldHint(field) }}
16- .errors.help-block ( v-if ='fieldErrors(field).length > 0' )
17- span( v-for ='(error, index) in fieldErrors(field)' , v-html ='error' , track-by ='index' )
5+ form-group( v-if ='fieldVisible(field)' , :field ="field" , :errors ="errors" , :model ="model" , :options ="options" , @validated ="onFieldValidated" )
186
197template( v-for ='group in groups' )
208fieldset( :is ='tag' , :class ='getFieldRowClasses(group)' )
219legend( v-if ='group.legend' ) {{ group.legend }}
2210template( v-for ='field in group.fields' )
23- .form-group ( v-if ='fieldVisible(field)' , :class ='getFieldRowClasses(field)' )
24- label( v-if ="fieldTypeHasLabel(field)" , :for ="getFieldID(field)" , :class ="field.labelClasses" )
25- | {{ field.label }}
26- span.help ( v-if ='field.help' )
27- i.icon
28- .helpText ( v-html ='field.help' )
29- .field-wrap
30- component( :is ='getFieldType(field)' , :disabled ='fieldDisabled(field)' , :model ='model' , :schema ='field' , :formOptions ='options' ,@model-updated ='modelUpdated' , @validated ="onFieldValidated" )
31- .buttons ( v-if ='buttonVisibility(field)' )
32- button( v-for ='btn in field.buttons' , @click ='buttonClickHandler(btn, field, $event)' , :class ='btn.classes' ) {{ btn.label }}
33- .hint ( v-if ='field.hint' ) {{ field.hint }}
34- .errors.help-block ( v-if ='fieldErrors(field).length > 0' )
35- span( v-for ='(error, index) in fieldErrors(field)' , v-html ='error' , track-by ='index' )
11+ form-group( v-if ='fieldVisible(field)' , :field ="field" , :errors ="errors" , :model ="model" , :options ="options" , @validated ="onFieldValidated" )
3612</template >
3713
3814<script >
39- // import Vue from "vue";
40- import { get as objGet , forEach , isFunction , isNil , isArray , isString } from " lodash" ;
41- import { slugifyFormID } from " ./utils/schema" ;
42-
43- // Load all fields from '../fields' folder
44- let fieldComponents = {};
45-
46- let coreFields = require .context (" ./fields/core" , false , / ^ \.\/ field([\w -_ ] + )\. vue$ / );
47-
48- forEach (coreFields .keys (), key => {
49- let compName = key .replace (/ ^ \.\/ / , " " ).replace (/ \. vue/ , " " );
50- fieldComponents[compName] = coreFields (key).default ;
51- });
52-
53- if (process .env .FULL_BUNDLE ) {
54- // eslint-disable-line
55- let Fields = require .context (" ./fields/optional" , false , / ^ \.\/ field([\w -_ ] + )\. vue$ / );
56-
57- forEach (Fields .keys (), key => {
58- let compName = key .replace (/ ^ \.\/ / , " " ).replace (/ \. vue/ , " " );
59- fieldComponents[compName] = Fields (key).default ;
60- });
61- }
15+ import { get as objGet , forEach , isFunction , isNil , isArray } from " lodash" ;
16+ import formMixin from " ./formMixin.js" ;
17+ import formGroup from " ./formGroup.vue" ;
6218
6319export default {
64- components: fieldComponents,
65-
20+ name: " formGenerator" ,
21+ components: { formGroup },
22+ mixins: [formMixin],
6623props: {
6724schema: Object ,
6825
@@ -163,75 +120,6 @@ export default {
163120},
164121
165122methods: {
166- // Get style classes of field
167- getFieldRowClasses (field ) {
168- const hasErrors = this .fieldErrors (field).length > 0 ;
169- let baseClasses = {
170- [objGet (this .options , " validationErrorClass" , " error" )]: hasErrors,
171- [objGet (this .options , " validationSuccessClass" , " valid" )]: ! hasErrors,
172- disabled: this .fieldDisabled (field),
173- readonly: this .fieldReadonly (field),
174- featured: this .fieldFeatured (field),
175- required: this .fieldRequired (field)
176- };
177-
178- if (isArray (field .styleClasses )) {
179- forEach (field .styleClasses , c => (baseClasses[c] = true ));
180- } else if (isString (field .styleClasses )) {
181- baseClasses[field .styleClasses ] = true ;
182- }
183-
184- if (! isNil (field .type )) {
185- baseClasses[" field-" + field .type ] = true ;
186- }
187-
188- return baseClasses;
189- },
190-
191- // Get type of field 'field-xxx'. It'll be the name of HTML element
192- getFieldType (fieldSchema ) {
193- return " field-" + fieldSchema .type ;
194- },
195-
196- // Should field type have a label?
197- fieldTypeHasLabel (field ) {
198- if (isNil (field .label )) return false ;
199-
200- let relevantType = " " ;
201- if (field .type === " input" ) {
202- relevantType = field .inputType ;
203- } else {
204- relevantType = field .type ;
205- }
206-
207- switch (relevantType) {
208- case " button" :
209- case " submit" :
210- case " reset" :
211- return false ;
212- default :
213- return true ;
214- }
215- },
216-
217- // Get disabled attr of field
218- fieldDisabled (field ) {
219- if (isFunction (field .disabled )) return field .disabled .call (this , this .model , field, this );
220-
221- if (isNil (field .disabled )) return false ;
222-
223- return field .disabled ;
224- },
225-
226- // Get required prop of field
227- fieldRequired (field ) {
228- if (isFunction (field .required )) return field .required .call (this , this .model , field, this );
229-
230- if (isNil (field .required )) return false ;
231-
232- return field .required ;
233- },
234-
235123// Get visible prop of field
236124fieldVisible (field ) {
237125if (isFunction (field .visible )) return field .visible .call (this , this .model , field, this );
@@ -241,35 +129,6 @@ export default {
241129return field .visible ;
242130},
243131
244- // Get readonly prop of field
245- fieldReadonly (field ) {
246- if (isFunction (field .readonly )) return field .readonly .call (this , this .model , field, this );
247-
248- if (isNil (field .readonly )) return false ;
249-
250- return field .readonly ;
251- },
252-
253- // Get featured prop of field
254- fieldFeatured (field ) {
255- if (isFunction (field .featured )) return field .featured .call (this , this .model , field, this );
256-
257- if (isNil (field .featured )) return false ;
258-
259- return field .featured ;
260- },
261-
262- // Get current hint.
263- fieldHint (field ) {
264- if (isFunction (field .hint )) return field .hint .call (this , this .model , field, this );
265-
266- return field .hint ;
267- },
268-
269- buttonClickHandler (btn , field , event ) {
270- return btn .onclick .call (this , this .model , field, event , this );
271- },
272-
273132// Child field executed validation
274133onFieldValidated (res , errors , field ) {
275134// Remove old errors for this field
@@ -301,7 +160,7 @@ export default {
301160
302161forEach (this .$children , child => {
303162if (isFunction (child .validate )) {
304- fields .push (child); // keep track of validated children
163+ fields .push (child . $refs . child ); // keep track of validated children
305164results .push (child .validate (true ));
306165}
307166});
@@ -338,32 +197,12 @@ export default {
338197forEach (this .$children , child => {
339198child .clearValidationErrors ();
340199});
341- },
342-
343- modelUpdated (newVal , schema ) {
344- this .$emit (" model-updated" , newVal, schema);
345- },
346-
347- buttonVisibility (field ) {
348- return field .buttons && field .buttons .length > 0 ;
349- },
350-
351- fieldErrors (field ) {
352- let res = this .errors .filter (e => e .field === field);
353- return res .map (item => item .error );
354- },
355-
356- getFieldID (schema ) {
357- const idPrefix = this .options && this .options .fieldIdPrefix ? this .options .fieldIdPrefix : " " ;
358- return slugifyFormID (schema, idPrefix);
359200}
360201}
361202};
362203 </script >
363204
364205<style lang="scss">
365- $errorColor : #f00 ;
366-
367206.vue-form-generator {
368207* {
369208box-sizing : border-box ;
@@ -499,64 +338,5 @@ $errorColor: #f00;
499338font-style : italic ;
500339font-size : 0.8em ;
501340} // .hint
502-
503- .form-group {
504- display : inline-block ;
505- vertical-align : top ;
506- width : 100% ;
507- // margin: 0.5rem 0.26rem;
508- margin-bottom : 1rem ;
509-
510- label {
511- font-weight : 400 ;
512- }
513-
514- & .featured {
515- > label {
516- font-weight : bold ;
517- }
518- }
519-
520- & .required {
521- > label :after {
522- content : " *" ;
523- font-weight : normal ;
524- color : Red ;
525- // position: absolute;
526- padding-left : 0.2em ;
527- font-size : 1em ;
528- }
529- }
530-
531- & .disabled {
532- > label {
533- color : #666 ;
534- font-style : italic ;
535- }
536- }
537-
538- & .error {
539- input :not ([type = " checkbox" ]),
540- textarea ,
541- select {
542- border : 1px solid $errorColor ;
543- background-color : rgba ($errorColor , 0.15 );
544- }
545-
546- .errors {
547- color : $errorColor ;
548- font-size : 0.8em ;
549- span {
550- display : block ;
551- background-image : url (" data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAiklEQVR4Xt2TMQoCQQxF3xdhu72MpZU3GU/meBFLOztPYrVWsQmEWSaMsIXgK8P8RyYkMjO2sAN+K9gTIAmDAlzoUzE7p4IFytvDCQWJKSStYB2efcAvqZFM0BcstMx5naSDYFzfLhh/4SmRM+6Agw/xIX0tKEDFufeDNRUc4XqLRz3qabVIf3BMHwl6Ktexn3nmAAAAAElFTkSuQmCC" );
552- background-repeat : no-repeat ;
553- padding-left : 17px ;
554- padding-top : 0px ;
555- margin-top : 0.2em ;
556- font-weight : 600 ;
557- }
558- } // .errors
559- } // .error
560- } // .form-group
561341} // fieldset
562342 </style >
0 commit comments