Skip to content

Commit 7ffa1d2

Browse files
committed
Merge branch 'v3' into develop
* v3: build disabled "color" test for fieldInput.spec to enable build skipping optional fields, proposing these be moved into separate packages for each field to allow for more extensive testing, examples and documentation on each updated core field tests to use modified nextTick with exception handling, removed "checkbox" test from fieldInput, updated to latest npm packages, added new "basic" dev samples, fixed problems in fieldCheckbox.spec tests related to the updates ... # Conflicts: # dist/vfg-core.js # dist/vfg.js
2 parents dab3785 + 244abb9 commit 7ffa1d2

32 files changed

+2287
-720
lines changed

bower.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-form-generator",
3-
"version": "2.1.1",
3+
"version": "3.0.0-dev",
44
"homepage": "https://github.com/icebob/vue-form-generator",
55
"authors": [
66
"Icebob"

dev/basic/app.vue

+308
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
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>

dev/basic/index.html

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>vue-form-generator development</title>
6+
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css">
7+
8+
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.js"></script>
9+
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.min.js"></script>
10+
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>
11+
<!-- jQuery dependent -->
12+
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.js"></script>
13+
</head>
14+
<body>
15+
<div class="container-fluid"></div>
16+
<div id="app"></div>
17+
<script src="/basic.js"></script>
18+
</body>
19+
</html>

dev/basic/main.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* global Vue */
2+
3+
// var App = require('./app.vue');
4+
// $(function() {
5+
// App.$mount('#app');
6+
// });
7+
8+
import Vue from 'vue';
9+
import App from './app.vue';
10+
11+
new Vue({
12+
...App
13+
}).$mount('#app');

dev/basic/utils.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module.exports = {
2+
3+
filters: {
4+
prettyJSON: function(json) {
5+
if (json) {
6+
json = JSON.stringify(json, null, 4);
7+
json = json.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
8+
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
9+
var cls = "number";
10+
if (/^"/.test(match)) {
11+
if (/:$/.test(match)) {
12+
cls = "key";
13+
} else {
14+
cls = "string";
15+
}
16+
} else if (/true|false/.test(match)) {
17+
cls = "boolean";
18+
} else if (/null/.test(match)) {
19+
cls = "null";
20+
}
21+
return "<span class='" + cls + "'>" + match + "</span>";
22+
});
23+
}
24+
}
25+
26+
}
27+
};

dist/vfg-core.css

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/vfg-core.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)