Skip to content

Commit 68ccc1a

Browse files
authored
Merge pull request #10 from formly-js/ssr
SSR & Boolean values
2 parents 150421e + fd09946 commit 68ccc1a

16 files changed

+521
-123
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
*~
22
\#*\#
3+
\.\#*
34
/.emacs.desktop
45
/.emacs.desktop.lock
56

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"babel-preset-es2015": "6.9.0",
3232
"babel-preset-es2015-loose-rollup": "^7.0.0",
3333
"babel-preset-stage-0": "6.5.0",
34+
"babel-runtime": "^6.23.0",
3435
"chai": "3.5.0",
3536
"conventional-changelog-cli": "1.2.0",
3637
"conventional-github-releaser": "1.1.3",
@@ -74,8 +75,8 @@
7475
"sinon-chai": "2.8.0",
7576
"style-loader": "0.13.1",
7677
"uglify-js": "^2.6.4",
77-
"vue": "~2.0.0",
78-
"vue-formly": "^2.3.9",
78+
"vue": "^2.2.6",
79+
"vue-formly": "^2.5.0",
7980
"vue-hot-reload-api": "1.3.2",
8081
"vue-html-loader": "1.2.3",
8182
"vue-loader": "8.5.3",

src/components/errorDisplay.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export default {
2+
render(h){
3+
if ( this.message ) return h('span', {
4+
'class': 'help-block form-text text-danger'
5+
}, this.message);
6+
},
7+
props: ['field', 'form'],
8+
computed: {
9+
message(){
10+
let message = false;
11+
if ( !( this.field in this.form.$errors ) || !( this.field in this.form ) || this.form[ this.field ].$active || !this.form[this.field].$dirty ) return message;
12+
let errors = this.form.$errors[ this.field ];
13+
Object.keys( errors ).some( errorKey => {
14+
if ( typeof errors[ errorKey ] != 'boolean' ){
15+
message = errors[ errorKey ];
16+
return true;
17+
}
18+
});
19+
return message;
20+
}
21+
}
22+
}

src/components/errorDisplay.vue

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/fields/baseField.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import errorDisplay from '../components/errorDisplay.vue';
1+
import errorDisplay from '../components/errorDisplay';
22
export default
33
{
44
props: [
@@ -16,6 +16,9 @@ export default
1616
this.$set(this.form, this.field.key, state);
1717
},
1818
methods: {
19+
booleanValue(value){
20+
return ( value === 'true' || value === 'false' ) ? value === 'true' : value;
21+
},
1922
runFunction: function(action, e){
2023
if ( typeof this.to[action] == 'function' ) this.to[action].call(this, e);
2124
},

src/fields/fieldInput.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import baseField from './baseField';
2+
export default {
3+
render(h){
4+
const children = [];
5+
const self = this;
6+
7+
// add the label if it needs it
8+
if ( this.to.label ) children.push(
9+
h('label', {
10+
attrs: {
11+
'for': this.to.id
12+
}
13+
}, this.to.label )
14+
);
15+
16+
// add the input
17+
children.push(
18+
h('input', {
19+
attrs: {
20+
id: this.to.id,
21+
type: this.to.inputType || 'text',
22+
...this.to.atts
23+
},
24+
'class': {
25+
'form-control': true,
26+
...this.to.classes
27+
},
28+
domProps: {
29+
value: this.model[ this.field.key ]
30+
},
31+
on: {
32+
input(event){
33+
self.model[ self.field.key ] = event.target.value;
34+
self.$emit('input', event.target.value);
35+
},
36+
blur: this.onBlur,
37+
focus: this.onFocus,
38+
click: this.onClick,
39+
change: this.onChange,
40+
keyup: this.onKeyup,
41+
keydown: this.onKeydown
42+
}
43+
})
44+
);
45+
46+
// add the error element
47+
children.push(
48+
h('error-display', {
49+
props: {
50+
form: this.form,
51+
field: this.field.key
52+
}
53+
})
54+
);
55+
return h('div', {
56+
'class': [
57+
'form-group formly-input',
58+
this.to.inputType,
59+
this.to.wrapperClasses,
60+
{
61+
'formly-has-value': this.model[ this.field.key ],
62+
'formly-has-focus': this.form[ this.field.key ].$active,
63+
'has-error has-danger': this.hasError
64+
}
65+
]
66+
}, children);
67+
},
68+
mixins: [baseField],
69+
methods: {
70+
onChange: function(e){
71+
72+
this.$set(this.form[this.field.key], '$dirty', true);
73+
this.runFunction('onChange', e);
74+
if ( this.to.inputType == 'file' ){
75+
this.$set(this.model, this.field.key, this.$el.querySelector('input').files);
76+
}
77+
78+
}
79+
}
80+
}

src/fields/fieldInput.vue

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/fields/fieldList.js

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import baseField from './baseField';
2+
export default {
3+
computed: {
4+
inputType(){
5+
return this.to.inputType || 'checkbox';
6+
}
7+
},
8+
created(){
9+
// set the default value to array
10+
if ( this.inputType === 'checkbox' && ( this.model[ this.field.key ].constructor !== Array || !this.model[ this.field.key ].constructor) ) this.$set( this.model, this.field.key, [] );
11+
},
12+
mixins: [baseField],
13+
render(h){
14+
const children = [];
15+
const self = this;
16+
const isArray = this.inputType === 'checkbox';
17+
18+
// add the label if it needs it
19+
if ( this.to.label ) children.push(
20+
h('label', this.to.label )
21+
);
22+
23+
// create each option
24+
if ( 'options' in this.field ){
25+
this.field.options.forEach( option => {
26+
const optionLabel = option.hasOwnProperty('label') ? option.label : option;
27+
const optionVal = option.hasOwnProperty('value') ? option.value : option;
28+
const optionChecked = isArray ? this.model[ this.field.key ].indexOf( optionVal ) > -1 : this.model[ this.field.key ] === optionVal;
29+
30+
children.push(
31+
// wrap each option in a label
32+
h('label', {
33+
'class': this.to.labelClasses
34+
}, [
35+
// create an input
36+
h('input', {
37+
attrs: {
38+
type: this.inputType,
39+
...this.to.atts
40+
},
41+
'class': {
42+
...this.to.classes
43+
},
44+
domProps: {
45+
value: optionVal,
46+
checked: optionChecked
47+
},
48+
on: {
49+
click: this.onClick,
50+
blur: this.onBlur,
51+
focus: this.onFocus,
52+
keyup: this.onKeyup,
53+
keydown: this.onKeydown,
54+
change(event){
55+
const isChecked = event.target.checked;
56+
const val = self.booleanValue( event.target.value );
57+
// we need to add/remove differently depending on the type of input we're using
58+
if ( isArray ){
59+
if ( isChecked ){
60+
// if it's a checkbox, and hence an array, push it
61+
self.model[ self.field.key ].push( val );
62+
} else {
63+
// otherwise remove it
64+
const valueIdx = self.model[ self.field.key ].indexOf( val );
65+
if ( valueIdx > -1 ) self.model[ self.field.key ].splice( valueIdx, 1 );
66+
}
67+
} else {
68+
self.model[ self.field.key ] = isChecked ? val : null;
69+
}
70+
self.$emit('change', val);
71+
if ( typeof self.onChange === 'function' ) self.onChange(event);
72+
}
73+
}
74+
}),
75+
// display the label
76+
optionLabel
77+
])
78+
);
79+
});
80+
}
81+
82+
// add the error element
83+
children.push(
84+
h('error-display', {
85+
props: {
86+
form: this.form,
87+
field: this.field.key
88+
}
89+
})
90+
);
91+
92+
// create the wrapper element
93+
return h('div', {
94+
'class': [
95+
'form-group formly-list',
96+
this.to.wrapperClasses,
97+
{
98+
'has-error has-danger': this.hasError
99+
}
100+
]
101+
}, children);
102+
}
103+
}

src/fields/fieldList.vue

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)