Skip to content

Commit b02d866

Browse files
Merge pull request #493 from lionel-bijaoui/lb_custom_label_help_&_hint
Custom label, help, hint and errors block
2 parents 02055ec + 301ab94 commit b02d866

18 files changed

+679
-78
lines changed

build/webpack.dev.config.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,13 @@ module.exports = {
4444
contentBase: [path.resolve("dev/projects")]
4545
},
4646
entry: {
47-
full: path.resolve("dev", "projects", "full", "main.js"),
4847
basic: path.resolve("dev", "projects", "basic", "main.js"),
49-
mselect: path.resolve("dev", "projects", "multiselect", "main.js"),
48+
checklist: path.resolve("dev", "projects", "checklist", "main.js"),
49+
custom: path.resolve("dev", "projects", "custom", "main.js"),
50+
full: path.resolve("dev", "projects", "full", "main.js"),
5051
grouping: path.resolve("dev", "projects", "grouping", "main.js"),
52+
mselect: path.resolve("dev", "projects", "multiselect", "main.js"),
5153
multi: path.resolve("dev", "projects", "multi", "main.js"),
52-
checklist: path.resolve("dev", "projects", "checklist", "main.js"),
5354
picker: path.resolve("dev", "projects", "picker", "main.js")
5455
},
5556

dev/projects/basic/app.vue

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
</template>
1616

1717
<script>
18+
/* eslint no-console: 0 */
1819
import mixinUtils from "../../mixins/utils.js";
1920
2021
export default {

dev/projects/checklist/app.vue

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
</template>
1616

1717
<script>
18+
/* eslint no-console: 0 */
1819
import { validators } from "../../../src";
1920
import mixinUtils from "../../mixins/utils.js";
2021

dev/projects/custom/app.vue

+248
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
<template>
2+
<div class="container">
3+
<h1>Custom label, help, hint and errors (with grouping)</h1>
4+
<div class="row">
5+
<div class="col-sm-12">
6+
<vue-form-generator :schema="schema" :model="model" :options="formOptions" tag="section">
7+
8+
<template slot="label" slot-scope="{ field, getValueFromOption }">
9+
<h3><i :class="`fa fa-${getIcon(field, getValueFromOption)}`"></i> {{ field.label }}</h3>
10+
</template>
11+
12+
<template slot="help" slot-scope="{ field }">
13+
<span v-if='field.help' class="help">
14+
<span @click.prevent="testClick(field.help, $event)">Need help</span>
15+
<i class="fa fa-question"></i>
16+
<vue-markdown class="helpText" :source="field.help"></vue-markdown>
17+
</span>
18+
</template>
19+
20+
<template slot="hint" slot-scope="{ field, getValueFromOption }">
21+
<div class="hint hint--info">
22+
<i class="fa fa-info-circle"></i>
23+
<span v-html="getValueFromOption(field, 'hint', undefined)"></span>
24+
</div>
25+
</template>
26+
27+
<template slot="errors" slot-scope="{ errors, field, getValueFromOption }">
28+
<span>Custom errors</span>
29+
<table class="errors help-block">
30+
<tbody>
31+
<thead>
32+
<tr>
33+
<th scope="col" id="">Index</th>
34+
<th scope="col" id="">Error</th>
35+
</tr>
36+
</thead>
37+
<tbody>
38+
<tr v-for="(error, index) in errors" :key="index">
39+
<td>{{index}}</td>
40+
<td v-html="error"></td>
41+
</tr>
42+
</tbody>
43+
</tbody>
44+
</table>
45+
</template>
46+
47+
</vue-form-generator>
48+
</div>
49+
</div>
50+
<div class="row">
51+
<div class="col-sm-12">
52+
<pre v-if="model" v-html="prettyModel"></pre>
53+
</div>
54+
</div>
55+
</div>
56+
</template>
57+
58+
<script>
59+
/* eslint no-console: 0 */
60+
import mixinUtils from "../../mixins/utils.js";
61+
import VueMarkdown from "vue-markdown";
62+
63+
export default {
64+
mixins: [mixinUtils],
65+
components: {
66+
VueMarkdown
67+
},
68+
data() {
69+
return {
70+
model: {
71+
name: "Brian Blessed",
72+
73+
others: {
74+
more: "",
75+
things: 2
76+
},
77+
single: "blah",
78+
color: ""
79+
},
80+
81+
schema: {
82+
fields: [
83+
{
84+
type: "group",
85+
legend: "Contact Details",
86+
tag: "div",
87+
fields: [
88+
{
89+
type: "input",
90+
model: "name",
91+
label: "Name",
92+
fieldOptions: {
93+
inputType: "text"
94+
},
95+
required: true,
96+
validator: ["required"]
97+
},
98+
{
99+
type: "group",
100+
legend: "Subgroup",
101+
styleClasses: "subgroup",
102+
tag: "fieldset",
103+
fields: [
104+
{
105+
type: "input",
106+
model: "color",
107+
label: "Some color",
108+
fieldOptions: {
109+
inputType: "color"
110+
},
111+
required: true,
112+
validator: ["required"]
113+
}
114+
]
115+
},
116+
{
117+
type: "input",
118+
model: "email",
119+
label: "Email",
120+
hint: "We will not share your email with third-party",
121+
fieldOptions: {
122+
inputType: "email"
123+
}
124+
}
125+
]
126+
},
127+
{
128+
type: "input",
129+
model: "single",
130+
label: "Single field (without group)",
131+
fieldOptions: {
132+
inputType: "text"
133+
},
134+
required: true,
135+
validator: ["string"]
136+
},
137+
{
138+
type: "group",
139+
legend: "Other Details",
140+
fields: [
141+
{
142+
type: "input",
143+
model: "others.more",
144+
label: "More",
145+
help: `
146+
Welcome to this *custom help*
147+
148+
some code example
149+
150+
151+
You need a modern browser to fill this field in the best condition.
152+
* test1
153+
* test2
154+
155+
https://google.com/
156+
157+
# Markdown !
158+
`,
159+
fieldOptions: {
160+
inputType: "date"
161+
}
162+
},
163+
{
164+
type: "input",
165+
model: "others.things",
166+
label: "Things",
167+
fieldOptions: {
168+
inputType: "number"
169+
}
170+
}
171+
]
172+
}
173+
]
174+
},
175+
176+
formOptions: {
177+
validateAfterLoad: true,
178+
validateAfterChanged: true,
179+
fieldIdPrefix: "frm1-"
180+
}
181+
};
182+
},
183+
184+
methods: {
185+
testClick(helpText, event) {
186+
console.log(helpText, event);
187+
},
188+
getIcon(field, getValueFromOption) {
189+
let fieldType = getValueFromOption(field, "type");
190+
let fieldOptions = getValueFromOption(field, "fieldOptions");
191+
let icons = {
192+
email: "at",
193+
number: "calculator",
194+
date: "calendar-alt",
195+
color: "palette"
196+
};
197+
if (fieldType === "input" && typeof icons[fieldOptions.inputType] !== "undefined") {
198+
return icons[fieldOptions.inputType];
199+
} else {
200+
return "file-alt";
201+
}
202+
}
203+
},
204+
205+
created() {
206+
window.app = this;
207+
}
208+
};
209+
</script>
210+
211+
<style lang="scss">
212+
@import "../../style.scss";
213+
.field-group {
214+
border: 2px solid #bbb;
215+
padding: 8px;
216+
border-radius: 4px;
217+
}
218+
.subgroup {
219+
border-color: goldenrod;
220+
legend {
221+
color: #00268d;
222+
}
223+
}
224+
.hint {
225+
&--info {
226+
color: #339af0;
227+
}
228+
}
229+
230+
table {
231+
border-collapse: collapse;
232+
border-spacing: 0;
233+
}
234+
thead th {
235+
background-color: #efdddd;
236+
border: solid 1px #eedddd;
237+
color: #6b3333;
238+
padding: 10px;
239+
text-align: left;
240+
text-shadow: 1px 1px 1px #fff;
241+
}
242+
tbody td {
243+
border: solid 1px #eedddd;
244+
color: #333;
245+
padding: 10px;
246+
text-shadow: 1px 1px 1px #fff;
247+
}
248+
</style>

dev/projects/custom/index.html

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!doctype html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<title>vue-form-generator multiple forms demo</title>
7+
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU"
8+
crossorigin="anonymous">
9+
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css">
10+
</head>
11+
12+
<body>
13+
<div class="container-fluid"></div>
14+
<div id="app"></div>
15+
<script src="/custom.js"></script>
16+
</body>
17+
18+
</html>

dev/projects/custom/main.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import Vue from "vue";
2+
import VueFormGenerator from "../../../src";
3+
Vue.use(VueFormGenerator);
4+
5+
import App from "./app.vue";
6+
7+
new Vue({
8+
...App
9+
}).$mount("#app");

dev/projects/full/app.vue

+16-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
<strong>{{ item.error }}</strong>
2323
</div>
2424
</div>
25-
<vue-form-generator :schema="schema" :model="model" :options="formOptions" :multiple="selected.length > 1" ref="form" :is-new-model="isNewModel" @model-updated="modelUpdated" @validated="onValidated"></vue-form-generator>
25+
<vue-form-generator :schema="schema" :model="model" :options="formOptions" :multiple="selected.length > 1" ref="form" :is-new-model="isNewModel" @model-updated="modelUpdated" @validated="onValidated">
26+
27+
</vue-form-generator>
2628
</div>
2729
<div class="col-md-6">
2830
<pre v-if="model" v-html="prettyModel"></pre>
@@ -32,6 +34,7 @@
3234
</template>
3335

3436
<script>
37+
/* eslint no-console: 0 */
3538
import Vue from "vue";
3639
import VueFormGenerator from "../../../src";
3740
import DataTable from "./dataTable.vue";
@@ -82,7 +85,9 @@ export default {
8285
8386
computed: {
8487
validationErrors() {
85-
if (this.$refs.form && this.$refs.form.errors) return this.$refs.form.errors;
88+
if (this.$refs.form && this.$refs.form.errors) {
89+
return this.$refs.form.errors;
90+
}
8691
8792
return [];
8893
}
@@ -185,7 +190,9 @@ export default {
185190
let id = 0;
186191
187192
each(this.rows, (row) => {
188-
if (row.id > id) id = row.id;
193+
if (row.id > id) {
194+
id = row.id;
195+
}
189196
});
190197
191198
return ++id;
@@ -204,8 +211,12 @@ export default {
204211
getLocation(model) {
205212
if (navigator.geolocation) {
206213
navigator.geolocation.getCurrentPosition((pos) => {
207-
if (!model.address) model.address = {};
208-
if (!model.address.geo) model.address.geo = {};
214+
if (!model.address) {
215+
model.address = {};
216+
}
217+
if (!model.address.geo) {
218+
model.address.geo = {};
219+
}
209220
model.address.geo.latitude = pos.coords.latitude.toFixed(5);
210221
model.address.geo.longitude = pos.coords.longitude.toFixed(5);
211222
});

dev/projects/full/data.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import fecha from "fecha";
33

44
let fakerator = new Fakerator();
55

6-
let roles = [{ id: "admin", name: "Administrator" }, { id: "moderator", name: "Moderator" }, { id: "user", name: "Registered User" }, { id: "visitor", name: "Visitor" }];
6+
let roles = [
7+
{ id: "admin", name: "Administrator" },
8+
{ id: "moderator", name: "Moderator" },
9+
{ id: "user", name: "Registered User" },
10+
{ id: "visitor", name: "Visitor" }
11+
];
712

813
let skills = ["HTML5", "Javascript", "CSS3", "CoffeeScript", "AngularJS", "ReactJS", "VueJS"];
914

@@ -34,7 +39,9 @@ let users = (function() {
3439
user.favoriteColor = "#" + fakerator.internet.color();
3540
user.color = "#" + fakerator.internet.color();
3641

37-
if (user.type === "business") user.company = fakerator.entity.company();
42+
if (user.type === "business") {
43+
user.company = fakerator.entity.company();
44+
}
3845

3946
user.income = [fakerator.random.number(50000), fakerator.random.number(50000, 100000)];
4047

0 commit comments

Comments
 (0)