1
+ /*! Easy Checkbox Required (c) Aaron Gustafson (@AaronGustafson). MIT License. http://github.com/easy-designs/easy-checkbox-required.js */
2
+
3
+ /* Easy Checkbox Required API
4
+ *
5
+ * One pain point in HTML5 validation is checkbox groups as you cannot simply
6
+ * use the "required" attribute as it would require the inclusion of each
7
+ * checkbox that is part of the group. This script fixes that by using a data
8
+ * attribute -- `data-checkbox-required` -- to indicate the requirement.
9
+ *
10
+ * Adding the `data-checkbox-required` attribute to one or more checkboxes
11
+ * in a group would require at least one checkbox be chosen, but you can
12
+ * specify lower and upper bounds by giving a value to the attribute. For
13
+ * example:
14
+ *
15
+ * <input type="checkbox" name="test[]" value="1"
16
+ * data-checkbox-required="3" />
17
+ *
18
+ * Would require at least 3 checkboxes in the group be checked
19
+ *
20
+ * <input type="checkbox" name="test[]" value="1"
21
+ * data-checkbox-required="3-5" />
22
+ *
23
+ * Would require at least 3, but no more than 5 checkboxes in the group be
24
+ * checked.
25
+ *
26
+ * <input type="checkbox" name="test[]" value="1"
27
+ * data-checkbox-required="0-5" />
28
+ *
29
+ * Would require any number (including 0), up to 5 checkboxes in the group
30
+ * be checked.
31
+ *
32
+ **/
33
+ ; ( function ( $ , UNDEFINED ) {
34
+
35
+ // jQuery Requirement
36
+ if ( $ == UNDEFINED ) { return ; }
37
+
38
+ var script_name = 'checkbox-required' ,
39
+ selector = '[data-' + script_name + ']' ,
40
+ error_key = script_name + '-error' ,
41
+ container = 'form > ol > li, fieldset > ol > li' ,
42
+ ERROR = 'validation-error' ,
43
+ html5_validation = ( function ( props ) {
44
+
45
+ var input = document . createElement ( 'input' ) ;
46
+ if ( typeof ( input . setCustomValidity ) != 'function' )
47
+ {
48
+ return false ;
49
+ }
50
+ return true ;
51
+ } ( ) ) ,
52
+ set_error = function ( ) { } ,
53
+ remove_error = function ( ) { } ;
54
+
55
+ if ( html5_validation )
56
+ {
57
+ set_error = function ( field , message )
58
+ {
59
+ field . setCustomValidity ( message ) ;
60
+ } ;
61
+ remove_error = function ( field )
62
+ {
63
+ field . setCustomValidity ( '' ) ;
64
+ } ;
65
+ }
66
+ // < HTML5 Errors
67
+ else
68
+ {
69
+ set_error = function ( field , message )
70
+ {
71
+ $ ( field ) . data ( error_key , message ) ;
72
+ } ;
73
+ remove_error = function ( field )
74
+ {
75
+ $ ( field ) . removeData ( error_key ) ;
76
+ } ;
77
+ }
78
+
79
+ function check_validity ( e )
80
+ {
81
+ var $form = $ ( this ) . closest ( 'form' ) ,
82
+ single_template = $form . data ( script_name + '-message-template-single' ) || 'Please choose an option' ,
83
+ min_template = $form . data ( script_name + '-message-template-min' ) || 'Please choose at least {min} options' ,
84
+ range_template = $form . data ( script_name + '-message-template-range' ) || 'Please choose {min}-{max} options' ,
85
+ max_template = $form . data ( script_name + '-message-template-max' ) || 'Please choose at most {max} options' ,
86
+ validated = [ ] ,
87
+ error = false ; // optimism
88
+
89
+ $form . find ( selector ) . each ( function ( ) {
90
+
91
+ var $field = $ ( this ) ,
92
+ name = $field . attr ( 'name' ) ,
93
+ required ,
94
+ checked ,
95
+ message ;
96
+
97
+ remove_error ( this ) ;
98
+
99
+ // only once per name
100
+ if ( $ . inArray ( name , validated ) != - 1 )
101
+ {
102
+ return ;
103
+ }
104
+ validated . push ( name ) ;
105
+
106
+ // get the count
107
+ required = $field . data ( script_name ) . toString ( ) . split ( '-' ) ;
108
+ checked = $field . closest ( 'form' ) . find ( '[type=checkbox][name="' + name + '"]:checked' ) . length ;
109
+
110
+ // empty defaults to one
111
+ if ( required == '' )
112
+ {
113
+ required = [ 1 ] ;
114
+ }
115
+
116
+ // minimum
117
+ if ( checked < required [ 0 ] )
118
+ {
119
+ error = true ;
120
+ }
121
+
122
+ // maximum
123
+ if ( error === false &&
124
+ required [ 1 ] != UNDEFINED &&
125
+ checked > required [ 1 ] )
126
+ {
127
+ error = true ;
128
+ }
129
+
130
+ if ( error )
131
+ {
132
+ if ( required [ 1 ] == UNDEFINED )
133
+ {
134
+ message = required [ 0 ] == 1 ? single_template : min_template ;
135
+ }
136
+ else
137
+ {
138
+ message = required [ 0 ] == 0 ? max_template : range_template ;
139
+ }
140
+
141
+ message = message
142
+ . replace ( '{min}' , required [ 0 ] )
143
+ . replace ( '{max}' , required [ 1 ] ) ;
144
+
145
+ set_error ( this , message ) ;
146
+
147
+ return false ;
148
+ }
149
+
150
+ } ) ;
151
+
152
+ }
153
+
154
+ function validate_form ( e )
155
+ {
156
+
157
+ var $form = $ ( this ) ,
158
+ has_validation_error = false ,
159
+ validated = [ ] ;
160
+
161
+ $form . find ( selector ) . each ( function ( ) {
162
+
163
+ var field = this ,
164
+ $field = $ ( field ) ,
165
+ name = $field . attr ( 'name' ) ;
166
+
167
+ // only once per name
168
+ if ( $ . inArray ( name , validated ) != - 1 )
169
+ {
170
+ return ;
171
+ }
172
+ validated . push ( name ) ;
173
+
174
+ if ( $field . data ( error_key ) != UNDEFINED )
175
+ {
176
+ has_validation_error = true ;
177
+ $field . closest ( container )
178
+ . addClass ( ERROR ) ;
179
+ }
180
+ else
181
+ {
182
+ $field . closest ( container )
183
+ . removeClass ( ERROR ) ;
184
+ }
185
+
186
+ } ) ;
187
+
188
+ // return false if there’s an error (to stop form submission)
189
+ return ! has_validation_error ;
190
+ }
191
+
192
+ // loop through the fields
193
+ $ ( selector ) . each ( function ( ) {
194
+
195
+ // find the form
196
+ var $form = $ ( this ) . closest ( 'form' ) ;
197
+
198
+ // only assign one event handler per form
199
+ if ( $form . data ( script_name ) )
200
+ {
201
+ return ;
202
+ }
203
+
204
+ $form
205
+ // native validation requires assigning validity
206
+ . on ( 'script::load' , check_validity )
207
+ . on ( 'change' , selector , check_validity )
208
+
209
+ // note that this form is already being watched
210
+ . data ( script_name , true )
211
+
212
+ // init the validation
213
+ . triggerHandler ( 'script::load' ) ;
214
+
215
+ // non-HTML5 validation requires tweaks on submit
216
+ if ( ! html5_validation )
217
+ {
218
+ $form . on ( 'submit' , validate_form ) ;
219
+ }
220
+
221
+ } ) ;
222
+
223
+ } ( jQuery ) ) ;
0 commit comments