Skip to content

Commit 4032ade

Browse files
committed
form genearator MVP
1 parent 303c2c0 commit 4032ade

File tree

3 files changed

+239
-4
lines changed

3 files changed

+239
-4
lines changed

assets/css/style.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,16 @@ h1, h2, h3, h4, h5, h6, input, select {
1111

1212
.segment{
1313
margin-top: 40px !important;
14+
}
15+
16+
.gen-field{
17+
border: 1px dotted #ddd;
18+
padding: 15px 5px ;
19+
margin-bottom: 5px;
20+
}
21+
22+
#code{
23+
padding: 10px;
24+
background: #111;
25+
-ms-overflow-x: scroll;
1426
}

assets/js/engine.js

Lines changed: 144 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,38 @@
1+
function clone(obj) {
2+
if (null == obj || "object" != typeof obj) return obj;
3+
var copy = obj.constructor();
4+
for (var attr in obj) {
5+
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
6+
}
7+
return copy;
8+
}
9+
110
var app = new Vue({
211
el: '#app',
312
data: {
4-
message: 'Hello Vue!',
13+
code: '',
514
theme: 'bootstrap',
615
method: 'get',
7-
fld: [],
16+
old: '',
17+
flds: [],
818
typ: [
919
'row',
1020
'input',
11-
'select'
21+
'select',
22+
'submit'
1223
],
1324
raw: {
1425
type: 'input',
1526
name: '',
27+
label: '',
1628
size: 12,
1729
id: '',
30+
options: ''
1831
}
1932
},
2033
mounted() {
2134
// sematicui
22-
$('.ui.dropdown').dropdown();
35+
this.initSemanticui();
2336

2437
}, computed: {
2538
siz: function () {
@@ -28,6 +41,133 @@ var app = new Vue({
2841
}
2942
return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
3043
}
44+
}, methods: {
45+
46+
makeLabel: function (field, inp) {
47+
48+
var out = '';
49+
if (field.id.trim() == '') {
50+
field.id = field.name;
51+
}
52+
53+
out += `\t\t <div class="col-md-${field.size}">\n`;
54+
55+
out += `\t\t\t <label for="${field.id}"> \n`;
56+
out += `\t\t\t\t {{_('${field.label}')}} \n`;
57+
out += `\t\t\t </label> \n`;
58+
59+
out += inp;
60+
out += `\t\t </div>\n`;
61+
return out;
62+
},
63+
generateForm: function () {
64+
var out = '';
65+
var hasRowBefore = false;
66+
// make method
67+
var method = 'get';
68+
var extMethod = '';
69+
if (this.method != 'get') {
70+
method = 'post';
71+
if (this.method != 'post') {
72+
extMethod = `@method('${this.method.toUpperCase()}')`;
73+
}
74+
}
75+
// make class
76+
var formClass = '';
77+
var generalClass = '';
78+
var rowClass = '';
79+
if (this.theme == 'bootstrap') {
80+
generalClass = 'form-control';
81+
rowClass = 'form-group row';
82+
}
83+
84+
// make form html
85+
out += `<form method="${method}" action=""> \n`;
86+
out += `\t @csrf \n`;
87+
out += `\t ${extMethod} \n`;
88+
for (const i in this.flds) {
89+
var field = this.flds[i];
90+
switch (field.type) {
91+
case "row":
92+
if (hasRowBefore) {
93+
out += `\t </div>\n`;
94+
} else {
95+
hasRowBefore = true;
96+
}
97+
out += `\t <div class="${rowClass}">\n`;
98+
break;
99+
case 'input':
100+
var old = '';
101+
if (this.old.trim() !== '') {
102+
old = ',' + this.old.replace('#name', field.name);
103+
}
104+
if (this.theme == 'bootstrap') {
105+
var genClass = generalClass + ` @error('${field.name}') is-invalid @enderror`;
106+
} else {
107+
var genClass = generalClass;
108+
}
109+
var inp = `\t\t\t <input type="${field.option}" class="${genClass}" placeholder="{{_('${field.label}')}}" value="{{old('${field.name}'${old})}}" /> \n`;
110+
out += this.makeLabel(field, inp);
111+
break;
112+
case 'select':
113+
var old = '';
114+
115+
if (this.theme == 'bootstrap') {
116+
var genClass = generalClass + ` @error('${field.name}') is-invalid @enderror`;
117+
} else {
118+
var genClass = generalClass;
119+
}
120+
var inp = `\t\t\t <select id="${field.id}" class="${genClass}" > \n`;
121+
try {
122+
var ops = field.option.split(':');
123+
var rs = ops[0];
124+
var r = ops[1];
125+
var key = ops[2];
126+
var title = ops[3];
127+
} catch (e) {
128+
alert('invalide options for ' + field.name);
129+
}
130+
131+
if (this.old.trim() !== '') {
132+
old = ',' + this.old.replace('#name', field.name);
133+
old = ` @if (old('${field.name}'${old}) == ${r}->${key} ) selected @endif`;
134+
} else {
135+
old = ` @if (old('${field.name}') == ${r}->${key} ) selected @endif`;
136+
}
137+
inp += `\t\t\t\t @foreach(${rs} as ${r} ) \n`;
138+
inp += `\t\t\t\t\t <option value="{{ ${r}->${key} }}" ${old} > {{${r}->${title}}} </option> \n`;
139+
inp += `\t\t\t\t @endforeach \n`;
140+
141+
out += this.makeLabel(field, inp);
142+
break;
143+
case 'submit':
144+
out += `\t\t <div class="col-md-${field.size}">\n`;
145+
146+
out += `\t\t\t <label> &nbsp; </label> \n`;
147+
var genClass = 'btn btn-primary mt-2';
148+
out += `\t\t\t <input type="submit" class="${genClass}" value="{{_('${field.label}')}}" /> \n`;
149+
out += `\t\t </div>\n`;
150+
break;
151+
}
152+
}
153+
154+
if (hasRowBefore) {
155+
out += `\t </div> \n`;
156+
}
157+
158+
out += `</form>`;
159+
160+
$("#code").text(out);
161+
},
162+
addField: function () {
163+
this.flds.push(clone(this.raw));
164+
this.initSemanticui();
165+
},
166+
initSemanticui: function () {
167+
setTimeout(function () {
168+
$('.ui.dropdown').dropdown();
169+
}, 200);
170+
}
31171
}
32172
});
33173

index.html

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,95 @@ <h4 class="ui dividing header">General setting</h4>
6262
</select>
6363
</div>
6464
</div>
65+
<div class="two fields">
66+
<div class="field">
67+
<label for="old">
68+
Old second parameter
69+
</label>
70+
<input type="text" placeholder="$item->#name??null" v-model="old"/>
71+
</div>
72+
</div>
73+
<h4 class="ui dividing header">Elements</h4>
74+
<div v-for="(fld,i) in flds" class="gen-field">
75+
<div class="fields two">
76+
<div class="field required">
77+
<label :for=`type-${i}`>
78+
Type
79+
</label>
80+
<select v-model="fld.type" :id=`type-${i}` class="ui dropdown">
81+
<option v-for="type in typ" :value="type"> {{type}} </option>
82+
</select>
83+
</div>
84+
<div class="field required" v-if="fld.type != 'row'">
85+
<label :for=`name-${i}`>
86+
Name
87+
</label>
88+
<input v-model="fld.name" :id=`name-${i}`>
89+
</div>
90+
<div class="field required" v-if="fld.type != 'row'">
91+
<label :for=`lbl-${i}`>
92+
Label
93+
</label>
94+
<input v-model="fld.label" :id=`lbl-${i}`>
95+
</div>
96+
</div>
97+
<div class="fields" v-if="fld.type != 'row'">
98+
<div class="five wide field required">
99+
<label :for=`size-${i}`>
100+
Size
101+
</label>
102+
<select v-model="fld.size" :id=`size-${i}` class="ui dropdown search">
103+
<option v-for="size in siz" :value="size"> {{size}} </option>
104+
</select>
105+
</div>
106+
<div class="five wide field">
107+
<label :for=`id-${i}`>
108+
ID
109+
</label>
110+
<input v-model="fld.id" :id=`id-${i}`>
111+
</div>
112+
<div class="seven wide field">
113+
<label :for=`opt-${i}`>
114+
Options
115+
</label>
116+
<input v-model="fld.option" :id=`opt-${i}` placeholder="$records:$record:id:title|type">
117+
</div>
118+
<div class="one wide field">
119+
<label> &nbsp;</label>
120+
<div class="button ui red fluid">
121+
<i class="times icon"></i>
122+
</div>
123+
</div>
124+
125+
</div>
126+
</div>
127+
<br>
128+
<br>
129+
<div class="ui button blue" @click="addField">
130+
Add field
131+
</div>
132+
<div class="ui button green" @click="generateForm">
133+
Generate form
134+
</div>
135+
65136
</div>
66137
</div>
67138

139+
<div class="ui segment inverted">
140+
<h2>
141+
Generated Code
142+
</h2>
143+
<pre id="code">
144+
{{code}}
145+
</pre>
146+
</div>
147+
<br>
148+
<br>
149+
<br>
68150
</div>
69151

70152

153+
71154
<script src="assets/js/engine.js"></script>
72155
</body>
73156
</html>

0 commit comments

Comments
 (0)