-
Notifications
You must be signed in to change notification settings - Fork 0
/
form-element.jsx
217 lines (188 loc) · 6.97 KB
/
form-element.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
var React = require('../../../lib/react-0.11.1');
var FormElement = React.createClass({
getInitialState: function (){
return {
initVal: this.props.config.initVal
}
},
// Iterate through the options
// TODO: sort the option by the 'order' param
processOptions: function (selected){
this.props.config.layout.options.sort(function (a, b) {
if (a.sortOrder > b.sortOrder){
return 1;
}
if (a.sortOrder < b.sortOrder) {
return -1;
}
return 0;
});
var options = this.props.config.layout.options.map(function (opt, i) {
return <option
key={opt.key}
value={opt.key}
disabled={!opt.isEnabled}>
{opt.display}
</option>;
});
// Add 'placeholder' as first select option
options.splice(0, 0, <option key='-1' value=''>
-- Select an Option --
</option>);
return options;
},
getValue: function () {
return this.refs[this.props.config.key].getDOMNode().value;
},
/**
* Alias for validate()
* @see validate
*/
handleBlur: function () {
if(this.validate()) {
this.props.save(this.props.ref, this.getValue());
}
},
/**
* This method is called everytime a form element is altered/chaged.
* If it has a validation Regular Expression then it is tested and if
* it fails that test then error classes are applied to it.
* @return {[boolean]} pass
*/
validate: function (dependency) {
this.setState({initVal: this.getValue()});
var key = this.props.config.key;
var invalidClasses = ' dirty invalid';
var elem = this.refs[key].getDOMNode();
var pass;
// Checkboxes will still have a value if they aren't 'checked' so,
// when validating they need to alter the value depending on whether the
// box is checked or not.
if(elem.type === 'checkbox') {
if(!elem.checked) {
elem.value = '';
} else {
elem.value = 'on';
}
}
// Checking for required class, so we can validate 'required' elements
// in IE8 and IE9
var requiredClass = elem.className.split(' ').indexOf('required');
if(requiredClass > 0) {
elem.required = true;
}
// If the element has a value, and isn't required and isn't being
// validated as a dependency, then consider it a valid input.
//
// If there isn't a value and the element is either required or
// being evaluated as a dependency then consider it an invalid input.
//
// Other ways, evaluate the element and its value based on the supplied
// Regular Expression set as an attribute.
if(elem.value.length === 0 && !elem.required && !dependency) {
pass = true;
} else if(elem.value.length === 0 && (elem.required || dependency)){
pass = false;
} else {
var pattern = new RegExp(this.props.config.validationRegex);
pass = pattern.test(elem.value);
}
// Add remove the invalid classes based on if the
// element passed validation
if(!pass && elem.className.indexOf(invalidClasses) == -1) {
elem.className += invalidClasses;
} else if(pass) {
elem.className = elem.className.replace(invalidClasses, '').trim();
}
// Return result
return pass;
},
/**
* This render function will dynamically generate a form element from the
* current element configuration provided by the Form class
*
* @return {[jsx]} [HTML Form Element]
* @todo Support more HTML form elements
*/
render: function () {
var type = this.props.config.layout.fieldType;
var element;
var styles = 'aio-form-input';
var width = ' aio-col-' + 12 / (100 / this.props.config.layout.fieldStyle);
// Enable 'required' attribute through class, IE8/9
if(this.props.config.required) {
styles += ' required';
}
switch (type) {
case 'phone-us':
case 'text':
case 'input':
element = <div>
<label className='aio-form-label'>{this.props.config.name}
{ this.props.config.required ? <span className='aio-astx'> *</span> : null }
</label>
<input
className={styles}
type={type}
name={this.props.config.key}
ref={this.props.config.key}
value={this.state.initVal}
required={this.props.config.required}
placeholder={this.props.config.name}
pattern={this.props.config.validationRegex}
validate={this.validate}
dependencies={this.props.config.dependencies}
onBlur={this.handleBlur}
onChange={this.validate} />
</div>;
break;
case 'select' :
var options = this.processOptions(this.state.initVal);
element = <div>
<label className='aio-form-label'>{this.props.config.name}
{ this.props.config.required ? <span className='aio-astx'> *</span> : null }
</label>
<select
className={styles}
name={this.props.config.name}
pattern={this.props.config.validationRegex}
required={this.props.config.required}
defaultValue={this.state.initVal}
ref={this.props.config.key}
id={this.props.config.key}
validate={this.validate}
dependencies={this.props.config.dependencies}
onBlur={this.handleBlur}
onChange={this.validate} >
{options}
</select>
</div>;
break;
case 'checkbox' :
element = <div>
<input
type='checkbox'
ref={this.props.config.key}
name={this.props.config.key}
id={this.props.config.key}
validate={this.validate}
defaultValue={this.state.initVal}
dependencies={this.props.config.dependencies} />
<label htmlFor={this.props.config.key}>{this.props.config.name}</label>
</div>;
break;
//This form element type is used for things like the TCPA disclocsure
case 'staticText' :
element = <div>
<span>{this.props.config.name}</span>
<input type='hidden' validate={this.validate} ref={this.props.config.key} value={this.props.config.name} />
</div>;
break;
default :
element = <div>{this.props.config.type}</div>;
};
element = <div className={width}>{element}</div>;
return element;
}
});
module.exports = FormElement;