1+ <template >
2+ <div class =" container" >
3+ <h1 >Basic</h1 >
4+ <div class =" row" >
5+ <div class =" col-sm-12" >
6+ <vue-form-generator :schema =" schema" :model =" model" :options =" formOptions" ref =" form" :is-new-model =" isNewModel" @model-updated =" modelUpdated" @validated =" onValidated" ></vue-form-generator >
7+ </div >
8+ </div >
9+ <div class =" row" >
10+ <div class =" col-sm-12" >
11+ <pre v-if =" model" v-html =" prettyModel" ></pre >
12+ </div >
13+ </div >
14+ </div >
15+ </template >
16+
17+ <script >
18+ import Vue from " vue" ;
19+ import VueFormGenerator from " ../../src" ;
20+
21+ import { filters } from " ./utils" ;
22+
23+ import {each , isFunction , cloneDeep , merge } from ' lodash' ;
24+
25+ Vue .use (VueFormGenerator);
26+
27+ export default {
28+ components: {
29+ },
30+
31+ filters: filters,
32+
33+ data () {
34+ return {
35+ isNewModel: false ,
36+
37+ selected: [],
38+
39+ model: {
40+ first_name: " David" ,
41+ last_name: " Higgins" ,
42+ status: true ,
43+ },
44+
45+ // rows: users,
46+
47+ schema: {
48+ fields: [
49+ {
50+ " type" : " input" ,
51+ " inputType" : " text" ,
52+ " label" : " First Name" ,
53+ " model" : " first_name"
54+ },
55+ {
56+ " type" : " checkbox" ,
57+ " label" : " Active" ,
58+ " model" : " status" ,
59+ },
60+ {
61+ " type" : " input" ,
62+ " inputType" : " color" ,
63+ " label" : " Color" ,
64+ " model" : " color"
65+ },
66+ {
67+ " type" : " submit" ,
68+ " buttonText" : " Change Previous Type" ,
69+ " onSubmit " : () => {
70+ // this.schema.fields[2].type = "input";
71+ if (this .schema .fields [2 ].inputType == " color" ) {
72+ this .schema .fields [2 ].inputType = " text" ;
73+ } else {
74+ this .schema .fields [2 ].inputType = " color" ;
75+ }
76+ }
77+ }
78+ ]
79+ },
80+
81+ formOptions: {
82+ validateAfterLoad: true ,
83+ validateAfterChanged: true ,
84+ validateBeforeSave: true
85+ }
86+ }
87+ },
88+
89+ computed: {
90+ validationErrors () {
91+ if (this .$refs .form && this .$refs .form .errors )
92+ return this .$refs .form .errors ;
93+
94+ return [];
95+ },
96+ prettyModel (){
97+ return filters .prettyJSON (this .model );
98+ }
99+ },
100+
101+ methods: {
102+ showWarning () {
103+ if (this .$refs .form && this .$refs .form .errors ) {
104+ return this .$refs .form .errors .length > 0
105+ }
106+ },
107+
108+ onSelectRow (event , row , add ) {
109+ this .isNewModel = false ;
110+ if ( (add || (event && event .ctrlKey ))) {
111+ if (this .selected .indexOf (row) != - 1 ){
112+ var index = this .selected .indexOf (row);
113+ this .selected .splice (index, 1 );
114+ } else {
115+ this .selected .push (row);
116+ }
117+ } else {
118+ this .clearSelection ();
119+ this .selected .push (row);
120+ }
121+ this .generateModel ();
122+ },
123+
124+ clearSelection () {
125+ this .selected .splice (0 );
126+ this .generateModel ();
127+ },
128+
129+ onValidated (res , errors ) {
130+ console .log (" VFG validated:" , res, errors);
131+ },
132+
133+ generateModel () {
134+ if (this .selected .length == 1 ) {
135+ this .model = cloneDeep (this .selected [0 ]);
136+ } else if (this .selected .length > 1 ) {
137+ this .model = VueFormGenerator .schema .mergeMultiObjectFields (Schema, this .selected );
138+ } else {
139+ this .model = null ;
140+ }
141+ },
142+
143+ newModel () {
144+ console .log (" Create new model..." );
145+ this .selected .splice (0 );
146+ let newRow = VueFormGenerator .schema .createDefaultObject (Schema, { id: this .getNextID () })
147+ this .isNewModel = true ;
148+ this .model = newRow;
149+
150+ let el = document .querySelector (" div.form input:nth-child(1):not([readonly]):not(:disabled)" );
151+ if (el)
152+ el .focus ()
153+
154+ },
155+
156+ saveModel () {
157+ console .log (" Save model..." );
158+ if (this .formOptions .validateBeforeSave === false || this .validate ()) {
159+ this .mergeModelValues ();
160+
161+ if (this .isNewModel ) {
162+ this .rows .push (this .model );
163+ this .onSelectRow (null , this .model , false );
164+ }
165+
166+ } else {
167+ console .warn (" Error saving model..." );
168+ // Validation error
169+ }
170+ },
171+
172+ mergeModelValues () {
173+ let model = this .model ;
174+ if (model && this .selected .length > 0 ) {
175+ each (this .selected , (row ) => {
176+ merge (row, model);
177+ });
178+ }
179+ },
180+
181+ deleteModel () {
182+ if (this .selected .length > 0 ) {
183+ each (this .selected , (row ) => {
184+ let index = this .rows .indexOf (row);
185+ this .rows .splice (index, 1 )
186+ })
187+ this .clearSelection ();
188+ }
189+ },
190+
191+ getNextID () {
192+ let id = 0 ;
193+
194+ each (this .rows , (row ) => {
195+ if (row .id > id)
196+ id = row .id ;
197+ });
198+
199+ return ++ id;
200+ },
201+
202+ validate () {
203+ // console.log("validate", this.$refs.form, this.$refs.form.validate());
204+ return this .$refs .form .validate ();
205+ },
206+
207+ modelUpdated (newVal , schema ) {
208+ console .log (" main model has updated" , newVal, schema);
209+ },
210+
211+
212+ getLocation (model ) {
213+ if (navigator .geolocation ) {
214+ navigator .geolocation .getCurrentPosition ((pos ) => {
215+ if (! model .address )
216+ model .address = {};
217+ if (! model .address .geo )
218+ model .address .geo = {};
219+ model .address .geo .latitude = pos .coords .latitude .toFixed (5 );
220+ model .address .geo .longitude = pos .coords .longitude .toFixed (5 );
221+ });
222+ } else {
223+ alert (" Geolocation is not supported by this browser." );
224+ }
225+ }
226+
227+
228+ },
229+
230+ mounted () {
231+ this .$nextTick (function () {
232+ window .app = this ;
233+
234+ // Localize validate errors
235+ // VueFormGenerator.validators.resources.fieldIsRequired = "Ezt a mezőt kötelező kitölteni!";
236+ // VueFormGenerator.validators.resources.textTooSmall = "A szöveg túl rövid! Jelenleg: {0}, minimum: {1}";
237+ })
238+ }
239+ }
240+
241+ // window.Vue = require('vue');
242+ </script >
243+
244+ <style lang="sass">
245+ @import url(http://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700|Open+Sans+Condensed:300&subset=latin,latin-ext) ;
246+
247+ html {
248+ font-family : " Open Sans" ;
249+ font-size : 14px ;
250+ }
251+
252+ * {
253+ -moz-box-sizing : border-box ;
254+ -webkit-box-sizing : border-box ;
255+ box-sizing : border-box ;
256+ }
257+
258+ pre {
259+ overflow : auto ;
260+
261+ .string { color: #885800; }
262+ .number { color: blue; }
263+ .boolean { color: magenta; }
264+ .null { color: red; }
265+ .key { color: green; }
266+ }
267+
268+ .control-buttons {
269+ button {
270+ margin : 0.2em 0.3em ;
271+ padding : 6px 20px ;
272+ position : relative ;
273+
274+ i {
275+ margin-right : 0.3em ;
276+ }
277+ }
278+
279+ i .fa.fa-warning {
280+ position : absolute ;
281+ top : 0px ;
282+ right : 0px ;
283+ color : Orange ;
284+ }
285+ }
286+
287+ .errors {
288+ .alert {
289+ padding : 4px ;
290+ width : 80% ;
291+ margin : 5px auto ;
292+ }
293+ }
294+
295+ fieldset .vue-form-generator {
296+
297+ .form-group.half-width {
298+ width : 50% ;
299+ }
300+
301+ .half-width + .half-width {
302+ & :not (.first ) {
303+ padding-left : 0.5rem ;
304+ }
305+ }
306+
307+ }
308+ </style >
0 commit comments