semantic-ui-sass 1.12.3.0 → 2.0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/app/assets/javascripts/semantic-ui.js +1 -0
  4. data/app/assets/javascripts/semantic-ui/accordion.js +67 -53
  5. data/app/assets/javascripts/semantic-ui/api.js +395 -189
  6. data/app/assets/javascripts/semantic-ui/checkbox.js +322 -114
  7. data/app/assets/javascripts/semantic-ui/colorize.js +4 -2
  8. data/app/assets/javascripts/semantic-ui/dimmer.js +74 -50
  9. data/app/assets/javascripts/semantic-ui/dropdown.js +2046 -584
  10. data/app/assets/javascripts/semantic-ui/embed.js +662 -0
  11. data/app/assets/javascripts/semantic-ui/form.js +345 -163
  12. data/app/assets/javascripts/semantic-ui/modal.js +119 -90
  13. data/app/assets/javascripts/semantic-ui/nag.js +8 -9
  14. data/app/assets/javascripts/semantic-ui/popup.js +390 -228
  15. data/app/assets/javascripts/semantic-ui/progress.js +112 -103
  16. data/app/assets/javascripts/semantic-ui/rating.js +79 -55
  17. data/app/assets/javascripts/semantic-ui/search.js +305 -123
  18. data/app/assets/javascripts/semantic-ui/shape.js +94 -48
  19. data/app/assets/javascripts/semantic-ui/sidebar.js +84 -151
  20. data/app/assets/javascripts/semantic-ui/site.js +5 -5
  21. data/app/assets/javascripts/semantic-ui/state.js +4 -4
  22. data/app/assets/javascripts/semantic-ui/sticky.js +108 -35
  23. data/app/assets/javascripts/semantic-ui/tab.js +220 -125
  24. data/app/assets/javascripts/semantic-ui/transition.js +205 -171
  25. data/app/assets/javascripts/semantic-ui/visibility.js +220 -100
  26. data/app/assets/javascripts/semantic-ui/visit.js +6 -4
  27. data/app/assets/stylesheets/semantic-ui/collections/_breadcrumb.scss +17 -16
  28. data/app/assets/stylesheets/semantic-ui/collections/_form.scss +223 -121
  29. data/app/assets/stylesheets/semantic-ui/collections/_grid.scss +462 -448
  30. data/app/assets/stylesheets/semantic-ui/collections/_menu.scss +949 -665
  31. data/app/assets/stylesheets/semantic-ui/collections/_message.scss +134 -92
  32. data/app/assets/stylesheets/semantic-ui/collections/_table.scss +270 -208
  33. data/app/assets/stylesheets/semantic-ui/elements/_all.scss +1 -0
  34. data/app/assets/stylesheets/semantic-ui/elements/_button.scss +1357 -521
  35. data/app/assets/stylesheets/semantic-ui/elements/_container.scss +125 -0
  36. data/app/assets/stylesheets/semantic-ui/elements/_divider.scss +51 -31
  37. data/app/assets/stylesheets/semantic-ui/elements/_flag.scss +3 -3
  38. data/app/assets/stylesheets/semantic-ui/elements/_header.scss +270 -144
  39. data/app/assets/stylesheets/semantic-ui/elements/_icon.scss +241 -110
  40. data/app/assets/stylesheets/semantic-ui/elements/_image.scss +30 -16
  41. data/app/assets/stylesheets/semantic-ui/elements/_input.scss +88 -53
  42. data/app/assets/stylesheets/semantic-ui/elements/_label.scss +432 -281
  43. data/app/assets/stylesheets/semantic-ui/elements/_list.scss +172 -128
  44. data/app/assets/stylesheets/semantic-ui/elements/_loader.scss +16 -14
  45. data/app/assets/stylesheets/semantic-ui/elements/_rail.scss +15 -7
  46. data/app/assets/stylesheets/semantic-ui/elements/_reveal.scss +32 -13
  47. data/app/assets/stylesheets/semantic-ui/elements/_segment.scss +329 -212
  48. data/app/assets/stylesheets/semantic-ui/elements/_step.scss +291 -99
  49. data/app/assets/stylesheets/semantic-ui/globals/_reset.scss +2 -2
  50. data/app/assets/stylesheets/semantic-ui/globals/_site.scss +19 -18
  51. data/app/assets/stylesheets/semantic-ui/modules/_accordion.scss +17 -18
  52. data/app/assets/stylesheets/semantic-ui/modules/_all.scss +1 -0
  53. data/app/assets/stylesheets/semantic-ui/modules/_checkbox.scss +265 -161
  54. data/app/assets/stylesheets/semantic-ui/modules/_dimmer.scss +29 -15
  55. data/app/assets/stylesheets/semantic-ui/modules/_dropdown.scss +441 -156
  56. data/app/assets/stylesheets/semantic-ui/modules/_embed.scss +168 -0
  57. data/app/assets/stylesheets/semantic-ui/modules/_modal.scss +163 -85
  58. data/app/assets/stylesheets/semantic-ui/modules/_nag.scss +8 -8
  59. data/app/assets/stylesheets/semantic-ui/modules/_popup.scss +88 -23
  60. data/app/assets/stylesheets/semantic-ui/modules/_progress.scss +185 -129
  61. data/app/assets/stylesheets/semantic-ui/modules/_rating.scss +75 -60
  62. data/app/assets/stylesheets/semantic-ui/modules/_search.scss +99 -52
  63. data/app/assets/stylesheets/semantic-ui/modules/_shape.scss +11 -11
  64. data/app/assets/stylesheets/semantic-ui/modules/_sidebar.scss +16 -12
  65. data/app/assets/stylesheets/semantic-ui/modules/_sticky.scss +4 -4
  66. data/app/assets/stylesheets/semantic-ui/modules/_tab.scss +3 -3
  67. data/app/assets/stylesheets/semantic-ui/modules/_transition.scss +31 -39
  68. data/app/assets/stylesheets/semantic-ui/views/_ad.scss +3 -3
  69. data/app/assets/stylesheets/semantic-ui/views/_all.scss +1 -0
  70. data/app/assets/stylesheets/semantic-ui/views/_card.scss +204 -162
  71. data/app/assets/stylesheets/semantic-ui/views/_comment.scss +6 -6
  72. data/app/assets/stylesheets/semantic-ui/views/_feed.scss +51 -26
  73. data/app/assets/stylesheets/semantic-ui/views/_item.scss +62 -36
  74. data/app/assets/stylesheets/semantic-ui/views/_statistic.scss +265 -90
  75. data/lib/semantic/ui/sass/version.rb +2 -2
  76. data/semantic-ui-sass.gemspec +2 -2
  77. metadata +9 -6
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * # Semantic UI 1.12.3 - Form Validation
2
+ * # Semantic UI - Form Validation
3
3
  * http://github.com/semantic-org/semantic-ui/
4
4
  *
5
5
  *
6
- * Copyright 2014 Contributors
6
+ * Copyright 2015 Contributors
7
7
  * Released under the MIT license
8
8
  * http://opensource.org/licenses/MIT
9
9
  *
@@ -13,60 +13,72 @@
13
13
 
14
14
  "use strict";
15
15
 
16
- $.fn.form = function(fields, parameters) {
16
+ $.fn.form = function(parameters) {
17
17
  var
18
- $allModules = $(this),
18
+ $allModules = $(this),
19
+ moduleSelector = $allModules.selector || '',
19
20
 
20
- settings = $.extend(true, {}, $.fn.form.settings, parameters),
21
- validation = $.extend({}, $.fn.form.settings.defaults, fields),
21
+ time = new Date().getTime(),
22
+ performance = [],
22
23
 
23
- namespace = settings.namespace,
24
- metadata = settings.metadata,
25
- selector = settings.selector,
26
- className = settings.className,
27
- error = settings.error,
28
-
29
- eventNamespace = '.' + namespace,
30
- moduleNamespace = 'module-' + namespace,
31
-
32
- moduleSelector = $allModules.selector || '',
33
-
34
- time = new Date().getTime(),
35
- performance = [],
36
-
37
- query = arguments[0],
38
- methodInvoked = (typeof query == 'string'),
39
- queryArguments = [].slice.call(arguments, 1),
24
+ query = arguments[0],
25
+ legacyParameters = arguments[1],
26
+ methodInvoked = (typeof query == 'string'),
27
+ queryArguments = [].slice.call(arguments, 1),
40
28
  returnedValue
41
29
  ;
42
30
  $allModules
43
31
  .each(function() {
44
32
  var
45
33
  $module = $(this),
46
- $field = $(this).find(selector.field),
47
- $group = $(this).find(selector.group),
48
- $message = $(this).find(selector.message),
49
- $prompt = $(this).find(selector.prompt),
50
-
51
- $submit = $(this).find(selector.submit),
52
- $clear = $(this).find(selector.clear),
53
- $reset = $(this).find(selector.reset),
34
+ element = this,
54
35
 
55
36
  formErrors = [],
56
37
  keyHeldDown = false,
57
38
 
58
- element = this,
59
- instance = $module.data(moduleNamespace),
39
+ // set at run-time
40
+ $field,
41
+ $group,
42
+ $message,
43
+ $prompt,
44
+ $submit,
45
+ $clear,
46
+ $reset,
47
+
48
+ settings,
49
+ validation,
50
+
51
+ metadata,
52
+ selector,
53
+ className,
54
+ error,
55
+
56
+ namespace,
57
+ moduleNamespace,
58
+ eventNamespace,
59
+
60
+ instance,
60
61
  module
61
62
  ;
62
63
 
63
64
  module = {
64
65
 
65
66
  initialize: function() {
66
- module.verbose('Initializing form validation', $module, validation, settings);
67
- module.bindEvents();
68
- module.set.defaults();
69
- module.instantiate();
67
+
68
+ // settings grabbed at run time
69
+ module.get.settings();
70
+ if(methodInvoked) {
71
+ if(instance === undefined) {
72
+ module.instantiate();
73
+ }
74
+ module.invoke(query);
75
+ }
76
+ else {
77
+ module.verbose('Initializing form validation', $module, settings);
78
+ module.bindEvents();
79
+ module.set.defaults();
80
+ module.instantiate();
81
+ }
70
82
  },
71
83
 
72
84
  instantiate: function() {
@@ -87,7 +99,14 @@ $.fn.form = function(fields, parameters) {
87
99
 
88
100
  refresh: function() {
89
101
  module.verbose('Refreshing selector cache');
90
- $field = $module.find(selector.field);
102
+ $field = $module.find(selector.field);
103
+ $group = $module.find(selector.group);
104
+ $message = $module.find(selector.message);
105
+ $prompt = $module.find(selector.prompt);
106
+
107
+ $submit = $module.find(selector.submit);
108
+ $clear = $module.find(selector.clear);
109
+ $reset = $module.find(selector.reset);
91
110
  },
92
111
 
93
112
  submit: function() {
@@ -100,7 +119,7 @@ $.fn.form = function(fields, parameters) {
100
119
  attachEvents: function(selector, action) {
101
120
  action = action || 'submit';
102
121
  $(selector)
103
- .on('click', function(event) {
122
+ .on('click' + eventNamespace, function(event) {
104
123
  module[action]();
105
124
  event.preventDefault();
106
125
  })
@@ -108,28 +127,25 @@ $.fn.form = function(fields, parameters) {
108
127
  },
109
128
 
110
129
  bindEvents: function() {
111
- if(settings.keyboardShortcuts) {
112
- $field
113
- .on('keydown' + eventNamespace, module.event.field.keydown)
114
- ;
115
- }
130
+ module.verbose('Attaching form events');
116
131
  $module
117
132
  .on('submit' + eventNamespace, module.validate.form)
133
+ .on('blur' + eventNamespace, selector.field, module.event.field.blur)
134
+ .on('click' + eventNamespace, selector.submit, module.submit)
135
+ .on('click' + eventNamespace, selector.reset, module.reset)
136
+ .on('click' + eventNamespace, selector.clear, module.clear)
118
137
  ;
119
- $field
120
- .on('blur' + eventNamespace, module.event.field.blur)
121
- ;
122
-
123
- // attach events to common elements
124
- module.attachEvents($submit, 'submit');
125
- module.attachEvents($reset, 'reset');
126
- module.attachEvents($clear, 'clear');
127
-
138
+ if(settings.keyboardShortcuts) {
139
+ $module
140
+ .on('keydown' + eventNamespace, selector.field, module.event.field.keydown)
141
+ ;
142
+ }
128
143
  $field
129
144
  .each(function() {
130
145
  var
131
- type = $(this).prop('type'),
132
- inputEvent = module.get.changeEvent(type)
146
+ $input = $(this),
147
+ type = $input.prop('type'),
148
+ inputEvent = module.get.changeEvent(type, $input)
133
149
  ;
134
150
  $(this)
135
151
  .on(inputEvent + eventNamespace, module.event.field.change)
@@ -161,7 +177,7 @@ $.fn.form = function(fields, parameters) {
161
177
  $element.dropdown('clear');
162
178
  }
163
179
  else if(isCheckbox) {
164
- $element.checkbox('uncheck');
180
+ $field.prop('checked', false);
165
181
  }
166
182
  else {
167
183
  module.verbose('Resetting field value', $field, defaultValue);
@@ -179,11 +195,14 @@ $.fn.form = function(fields, parameters) {
179
195
  $element = $field.parent(),
180
196
  $fieldGroup = $field.closest($group),
181
197
  $prompt = $fieldGroup.find(selector.prompt),
182
- defaultValue = $field.data(metadata.defaultValue) || '',
198
+ defaultValue = $field.data(metadata.defaultValue),
183
199
  isCheckbox = $element.is(selector.uiCheckbox),
184
200
  isDropdown = $element.is(selector.uiDropdown),
185
201
  isErrored = $fieldGroup.hasClass(className.error)
186
202
  ;
203
+ if(defaultValue === undefined) {
204
+ return;
205
+ }
187
206
  if(isErrored) {
188
207
  module.verbose('Resetting error on field', $fieldGroup);
189
208
  $fieldGroup.removeClass(className.error);
@@ -195,12 +214,7 @@ $.fn.form = function(fields, parameters) {
195
214
  }
196
215
  else if(isCheckbox) {
197
216
  module.verbose('Resetting checkbox value', $element, defaultValue);
198
- if(defaultValue === true) {
199
- $element.checkbox('check');
200
- }
201
- else {
202
- $element.checkbox('uncheck');
203
- }
217
+ $field.prop('checked', defaultValue);
204
218
  }
205
219
  else {
206
220
  module.verbose('Resetting field value', $field, defaultValue);
@@ -210,6 +224,21 @@ $.fn.form = function(fields, parameters) {
210
224
  ;
211
225
  },
212
226
 
227
+ is: {
228
+ valid: function() {
229
+ var
230
+ allValid = true
231
+ ;
232
+ module.verbose('Checking if form is valid');
233
+ $.each(validation, function(fieldName, field) {
234
+ if( !( module.validate.field(field) ) ) {
235
+ allValid = false;
236
+ }
237
+ });
238
+ return allValid;
239
+ }
240
+ },
241
+
213
242
  removeEvents: function() {
214
243
  $module
215
244
  .off(eventNamespace)
@@ -243,9 +272,6 @@ $.fn.form = function(fields, parameters) {
243
272
  ;
244
273
  }
245
274
  if(!event.ctrlKey && key == keyCode.enter && $field.is(selector.input) && $field.not(selector.checkbox).length > 0 ) {
246
- $submit
247
- .addClass(className.pressed)
248
- ;
249
275
  if(!keyHeldDown) {
250
276
  $field
251
277
  .one('keyup' + eventNamespace, module.event.field.keyup)
@@ -258,19 +284,19 @@ $.fn.form = function(fields, parameters) {
258
284
  },
259
285
  keyup: function() {
260
286
  keyHeldDown = false;
261
- $submit.removeClass(className.pressed);
262
287
  },
263
288
  blur: function() {
264
289
  var
265
- $field = $(this),
266
- $fieldGroup = $field.closest($group)
290
+ $field = $(this),
291
+ $fieldGroup = $field.closest($group),
292
+ validationRules = module.get.validation($field)
267
293
  ;
268
294
  if( $fieldGroup.hasClass(className.error) ) {
269
- module.debug('Revalidating field', $field, module.get.validation($field));
270
- module.validate.field( module.get.validation($field) );
295
+ module.debug('Revalidating field', $field, validationRules);
296
+ module.validate.field( validationRules );
271
297
  }
272
298
  else if(settings.on == 'blur' || settings.on == 'change') {
273
- module.validate.field( module.get.validation($field) );
299
+ module.validate.field( validationRules );
274
300
  }
275
301
  },
276
302
  change: function() {
@@ -291,8 +317,8 @@ $.fn.form = function(fields, parameters) {
291
317
  },
292
318
 
293
319
  get: {
294
- changeEvent: function(type) {
295
- if(type == 'checkbox' || type == 'radio' || type == 'hidden') {
320
+ changeEvent: function(type, $input) {
321
+ if(type == 'checkbox' || type == 'radio' || type == 'hidden' || $input.is('select')) {
296
322
  return 'change';
297
323
  }
298
324
  else {
@@ -307,6 +333,52 @@ $.fn.form = function(fields, parameters) {
307
333
  : 'keyup'
308
334
  ;
309
335
  },
336
+ settings: function() {
337
+ var
338
+ firstProperty
339
+ ;
340
+ if($.isPlainObject(parameters)) {
341
+ var
342
+ keys = Object.keys(parameters),
343
+ isLegacySettings = (keys.length > 0)
344
+ ? (parameters[keys[0]].identifier !== undefined && parameters[keys[0]].rules !== undefined)
345
+ : false
346
+ ;
347
+ if(isLegacySettings) {
348
+ // 1.x (ducktyped)
349
+ settings = $.extend(true, {}, $.fn.form.settings, legacyParameters);
350
+ validation = $.extend({}, $.fn.form.settings.defaults, parameters);
351
+ module.error(settings.error.oldSyntax, element);
352
+ module.verbose('Extending settings from legacy parameters', validation, settings);
353
+ }
354
+ else {
355
+ // 2.x
356
+ settings = $.extend(true, {}, $.fn.form.settings, parameters);
357
+ validation = $.extend({}, $.fn.form.settings.defaults, settings.fields);
358
+ module.verbose('Extending settings', validation, settings);
359
+ }
360
+ }
361
+ else {
362
+ settings = $.fn.form.settings;
363
+ validation = $.fn.form.settings.defaults;
364
+ module.verbose('Using default form validation', validation, settings);
365
+ }
366
+
367
+ // shorthand
368
+ namespace = settings.namespace;
369
+ metadata = settings.metadata;
370
+ selector = settings.selector;
371
+ className = settings.className;
372
+ error = settings.error;
373
+ moduleNamespace = 'module-' + namespace;
374
+ eventNamespace = '.' + namespace;
375
+
376
+ // grab instance
377
+ instance = $module.data(moduleNamespace);
378
+
379
+ // refresh selector cache
380
+ module.refresh();
381
+ },
310
382
  field: function(identifier) {
311
383
  module.verbose('Finding field with identifier', identifier);
312
384
  if( $field.filter('#' + identifier).length > 0 ) {
@@ -336,8 +408,11 @@ $.fn.form = function(fields, parameters) {
336
408
  var
337
409
  rules
338
410
  ;
411
+ if(!validation) {
412
+ return false;
413
+ }
339
414
  $.each(validation, function(fieldName, field) {
340
- if( module.get.field(field.identifier).get(0) == $field.get(0) ) {
415
+ if( module.get.field(field.identifier)[0] == $field[0] ) {
341
416
  rules = field;
342
417
  }
343
418
  });
@@ -380,7 +455,7 @@ $.fn.form = function(fields, parameters) {
380
455
  }
381
456
  if(isCheckbox) {
382
457
  if(isChecked) {
383
- values[name].push(value)
458
+ values[name].push(value);
384
459
  }
385
460
  else {
386
461
  module.debug('Omitted unchecked checkbox', $field);
@@ -420,6 +495,9 @@ $.fn.form = function(fields, parameters) {
420
495
 
421
496
  field: function(identifier) {
422
497
  module.verbose('Checking for existence of a field with identifier', identifier);
498
+ if(typeof identifier !== 'string') {
499
+ module.error(error.identifier, identifier);
500
+ }
423
501
  if( $field.filter('#' + identifier).length > 0 ) {
424
502
  return true;
425
503
  }
@@ -600,7 +678,6 @@ $.fn.form = function(fields, parameters) {
600
678
  }
601
679
  }
602
680
  });
603
- module.validate.form();
604
681
  }
605
682
  },
606
683
 
@@ -608,7 +685,6 @@ $.fn.form = function(fields, parameters) {
608
685
 
609
686
  form: function(event) {
610
687
  var
611
- allValid = true,
612
688
  apiRequest
613
689
  ;
614
690
 
@@ -619,12 +695,7 @@ $.fn.form = function(fields, parameters) {
619
695
 
620
696
  // reset errors
621
697
  formErrors = [];
622
- $.each(validation, function(fieldName, field) {
623
- if( !( module.validate.field(field) ) ) {
624
- allValid = false;
625
- }
626
- });
627
- if(allValid) {
698
+ if( module.is.valid() ) {
628
699
  module.debug('Form has no validation errors, submitting');
629
700
  module.set.success();
630
701
  return settings.onSuccess.call(element, event);
@@ -685,23 +756,36 @@ $.fn.form = function(fields, parameters) {
685
756
  var
686
757
  $field = module.get.field(field.identifier),
687
758
  type = validation.type,
688
- value = $.trim($field.val() + ''),
689
-
690
- bracketRegExp = /\[(.*)\]/i,
691
- bracket = bracketRegExp.exec(type),
759
+ value = $field.val(),
760
+ bracket = type.match(settings.regExp.bracket),
692
761
  isValid = true,
762
+ rule,
693
763
  ancillary,
694
764
  functionType
695
765
  ;
766
+ // cast to string avoiding encoding special values
767
+ value = (value === undefined || value === '' || value === null)
768
+ ? ''
769
+ : $.trim(value + '')
770
+ ;
696
771
  // if bracket notation is used, pass in extra parameters
697
- if(bracket !== undefined && bracket !== null) {
772
+ if(bracket) {
698
773
  ancillary = '' + bracket[1];
699
774
  functionType = type.replace(bracket[0], '');
700
- isValid = settings.rules[functionType].call(element, value, ancillary);
775
+ rule = settings.rules[functionType];
776
+ if( !$.isFunction(rule) ) {
777
+ module.error(error.noRule, functionType);
778
+ return;
779
+ }
780
+ isValid = rule.call($field, value, ancillary);
701
781
  }
702
- // normal notation
703
782
  else {
704
- isValid = settings.rules[type].call($field, value);
783
+ rule = settings.rules[type];
784
+ if( !$.isFunction(rule) ) {
785
+ module.error(error.noRule, type);
786
+ return;
787
+ }
788
+ isValid = rule.call($field, value);
705
789
  }
706
790
  return isValid;
707
791
  }
@@ -775,7 +859,7 @@ $.fn.form = function(fields, parameters) {
775
859
  });
776
860
  }
777
861
  clearTimeout(module.performance.timer);
778
- module.performance.timer = setTimeout(module.performance.display, 100);
862
+ module.performance.timer = setTimeout(module.performance.display, 500);
779
863
  },
780
864
  display: function() {
781
865
  var
@@ -863,19 +947,7 @@ $.fn.form = function(fields, parameters) {
863
947
  return found;
864
948
  }
865
949
  };
866
- if(methodInvoked) {
867
- if(instance === undefined) {
868
- module.initialize();
869
- }
870
- module.invoke(query);
871
- }
872
- else {
873
- if(instance !== undefined) {
874
- instance.invoke('destroy');
875
- }
876
- module.initialize();
877
- }
878
-
950
+ module.initialize();
879
951
  })
880
952
  ;
881
953
 
@@ -891,9 +963,10 @@ $.fn.form.settings = {
891
963
  namespace : 'form',
892
964
 
893
965
  debug : false,
894
- verbose : true,
966
+ verbose : false,
895
967
  performance : true,
896
968
 
969
+ fields : false,
897
970
 
898
971
  keyboardShortcuts : true,
899
972
  on : 'submit',
@@ -915,6 +988,15 @@ $.fn.form.settings = {
915
988
  validate : 'validate'
916
989
  },
917
990
 
991
+ regExp: {
992
+ bracket : /\[(.*)\]/i,
993
+ escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
994
+ email : "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
995
+ integer : /^\-?\d+$/,
996
+ flags : /^\/(.*)\/(.*)?/,
997
+ url : /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/i
998
+ },
999
+
918
1000
  selector : {
919
1001
  checkbox : 'input[type="checkbox"], input[type="radio"]',
920
1002
  clear : '.clear',
@@ -924,8 +1006,8 @@ $.fn.form.settings = {
924
1006
  message : '.error.message',
925
1007
  prompt : '.prompt.label',
926
1008
  radio : 'input[type="radio"]',
927
- reset : '.reset',
928
- submit : '.submit',
1009
+ reset : '.reset:not([type="reset"])',
1010
+ submit : '.submit:not([type="submit"])',
929
1011
  uiCheckbox : '.ui.checkbox',
930
1012
  uiDropdown : '.ui.dropdown'
931
1013
  },
@@ -938,7 +1020,10 @@ $.fn.form.settings = {
938
1020
  },
939
1021
 
940
1022
  error: {
941
- method : 'The method you called is not defined.'
1023
+ oldSyntax : 'Starting in 2.0 forms now only take a single settings object. Validation settings converted to new syntax automatically.',
1024
+ identifier : 'You must specify a string identifier for each field',
1025
+ noRule : 'There is no rule matching the one you specified',
1026
+ method : 'The method you called is not defined.'
942
1027
  },
943
1028
 
944
1029
  templates: {
@@ -966,42 +1051,53 @@ $.fn.form.settings = {
966
1051
 
967
1052
  rules: {
968
1053
 
1054
+ // is not empty or blank string
1055
+ empty: function(value) {
1056
+ return !(value === undefined || '' === value || $.isArray(value) && value.length === 0);
1057
+ },
1058
+
969
1059
  // checkbox checked
970
1060
  checked: function() {
971
1061
  return ($(this).filter(':checked').length > 0);
972
1062
  },
973
1063
 
974
- // value contains text (insensitive)
975
- contains: function(value, text) {
976
- // escape regex characters
977
- text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
978
- return (value.search( new RegExp(text, 'i') ) !== -1);
979
- },
980
-
981
- // value contains text (case sensitive)
982
- containsExactly: function(value, text) {
983
- // escape regex characters
984
- text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
985
- return (value.search( new RegExp(text) ) !== -1);
986
- },
987
-
988
1064
  // is most likely an email
989
1065
  email: function(value){
990
1066
  var
991
- emailRegExp = new RegExp("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", "i")
1067
+ emailRegExp = new RegExp($.fn.form.settings.regExp.email, 'i')
992
1068
  ;
993
1069
  return emailRegExp.test(value);
994
1070
  },
995
1071
 
996
- // is not empty or blank string
997
- empty: function(value) {
998
- return !(value === undefined || '' === value);
1072
+ // value is most likely url
1073
+ url: function(value) {
1074
+ return $.fn.form.settings.regExp.url.test(value);
999
1075
  },
1000
1076
 
1001
- // is valid integer
1077
+ // matches specified regExp
1078
+ regExp: function(value, regExp) {
1079
+ var
1080
+ regExpParts = regExp.match($.fn.form.settings.regExp.flags),
1081
+ flags
1082
+ ;
1083
+ // regular expression specified as /baz/gi (flags)
1084
+ if(regExpParts) {
1085
+ regExp = (regExpParts.length >= 2)
1086
+ ? regExpParts[1]
1087
+ : regExp
1088
+ ;
1089
+ flags = (regExpParts.length >= 3)
1090
+ ? regExpParts[2]
1091
+ : ''
1092
+ ;
1093
+ }
1094
+ return value.match( new RegExp(regExp, flags) );
1095
+ },
1096
+
1097
+ // is valid integer or matches range
1002
1098
  integer: function(value, range) {
1003
1099
  var
1004
- intRegExp = /^\-?\d+$/,
1100
+ intRegExp = $.fn.form.settings.regExp.integer,
1005
1101
  min,
1006
1102
  max,
1007
1103
  parts
@@ -1030,6 +1126,7 @@ $.fn.form.settings = {
1030
1126
  );
1031
1127
  },
1032
1128
 
1129
+
1033
1130
  // is value (case insensitive)
1034
1131
  is: function(value, text) {
1035
1132
  text = (typeof text == 'string')
@@ -1048,29 +1145,93 @@ $.fn.form.settings = {
1048
1145
  return (value == text);
1049
1146
  },
1050
1147
 
1051
- // is at least string length
1148
+ // value is not another value (case insensitive)
1149
+ not: function(value, notValue) {
1150
+ value = (typeof value == 'string')
1151
+ ? value.toLowerCase()
1152
+ : value
1153
+ ;
1154
+ notValue = (typeof notValue == 'string')
1155
+ ? notValue.toLowerCase()
1156
+ : notValue
1157
+ ;
1158
+ return (value != notValue);
1159
+ },
1160
+
1161
+ // value is not another value (case sensitive)
1162
+ notExactly: function(value, notValue) {
1163
+ return (value != notValue);
1164
+ },
1165
+
1166
+ // value contains text (insensitive)
1167
+ contains: function(value, text) {
1168
+ // escape regex characters
1169
+ text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
1170
+ return (value.search( new RegExp(text, 'i') ) !== -1);
1171
+ },
1172
+
1173
+ // value contains text (case sensitive)
1174
+ containsExactly: function(value, text) {
1175
+ // escape regex characters
1176
+ text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
1177
+ return (value.search( new RegExp(text) ) !== -1);
1178
+ },
1179
+
1180
+ // value contains text (insensitive)
1181
+ doesntContain: function(value, text) {
1182
+ // escape regex characters
1183
+ text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
1184
+ return (value.search( new RegExp(text, 'i') ) === -1);
1185
+ },
1186
+
1187
+ // value contains text (case sensitive)
1188
+ doesntContainExactly: function(value, text) {
1189
+ // escape regex characters
1190
+ text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
1191
+ return (value.search( new RegExp(text) ) === -1);
1192
+ },
1193
+
1194
+ // is exactly length
1052
1195
  length: function(value, requiredLength) {
1196
+ return (value !== undefined)
1197
+ ? (value.length == requiredLength)
1198
+ : false
1199
+ ;
1200
+ },
1201
+
1202
+ // is at least string length
1203
+ minLength: function(value, requiredLength) {
1053
1204
  return (value !== undefined)
1054
1205
  ? (value.length >= requiredLength)
1055
1206
  : false
1056
1207
  ;
1057
1208
  },
1058
1209
 
1210
+ // is less than length
1211
+ maxLength: function(value, maxLength) {
1212
+ return (value !== undefined)
1213
+ ? (value.length <= maxLength)
1214
+ : false
1215
+ ;
1216
+ },
1217
+
1059
1218
  // matches another field
1060
- match: function(value, fieldIdentifier) {
1061
- // use either id or name of field
1219
+ match: function(value, identifier) {
1062
1220
  var
1063
1221
  $form = $(this),
1064
1222
  matchingValue
1065
1223
  ;
1066
- if($form.find('#' + fieldIdentifier).length > 0) {
1067
- matchingValue = $form.find('#' + fieldIdentifier).val();
1224
+ if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
1225
+ matchingValue = $('[data-validate="'+ identifier +'"]').val();
1068
1226
  }
1069
- else if($form.find('[name="' + fieldIdentifier +'"]').length > 0) {
1070
- matchingValue = $form.find('[name="' + fieldIdentifier + '"]').val();
1227
+ else if($('#' + identifier).length > 0) {
1228
+ matchingValue = $('#' + identifier).val();
1071
1229
  }
1072
- else if( $form.find('[data-validate="'+ fieldIdentifier +'"]').length > 0 ) {
1073
- matchingValue = $form.find('[data-validate="'+ fieldIdentifier +'"]').val();
1230
+ else if($('[name="' + identifier +'"]').length > 0) {
1231
+ matchingValue = $('[name="' + identifier + '"]').val();
1232
+ }
1233
+ else if( $('[name="' + identifier +'[]"]').length > 0 ) {
1234
+ matchingValue = $('[name="' + identifier +'[]"]');
1074
1235
  }
1075
1236
  return (matchingValue !== undefined)
1076
1237
  ? ( value.toString() == matchingValue.toString() )
@@ -1078,38 +1239,59 @@ $.fn.form.settings = {
1078
1239
  ;
1079
1240
  },
1080
1241
 
1081
- // string length is less than max length
1082
- maxLength: function(value, maxLength) {
1083
- return (value !== undefined)
1084
- ? (value.length <= maxLength)
1242
+ // different than another field
1243
+ different: function(value, identifier) {
1244
+ // use either id or name of field
1245
+ var
1246
+ $form = $(this),
1247
+ matchingValue
1248
+ ;
1249
+ if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
1250
+ matchingValue = $('[data-validate="'+ identifier +'"]').val();
1251
+ }
1252
+ else if($('#' + identifier).length > 0) {
1253
+ matchingValue = $('#' + identifier).val();
1254
+ }
1255
+ else if($('[name="' + identifier +'"]').length > 0) {
1256
+ matchingValue = $('[name="' + identifier + '"]').val();
1257
+ }
1258
+ else if( $('[name="' + identifier +'[]"]').length > 0 ) {
1259
+ matchingValue = $('[name="' + identifier +'[]"]');
1260
+ }
1261
+ return (matchingValue !== undefined)
1262
+ ? ( value.toString() !== matchingValue.toString() )
1085
1263
  : false
1086
1264
  ;
1087
1265
  },
1088
1266
 
1089
- // value is not value (case insensitive)
1090
- not: function(value, notValue) {
1091
- value = (typeof value == 'string')
1092
- ? value.toLowerCase()
1093
- : value
1094
- ;
1095
- notValue = (typeof notValue == 'string')
1096
- ? notValue.toLowerCase()
1097
- : notValue
1098
- ;
1099
- return (value != notValue);
1267
+ exactCount: function(value, exactCount) {
1268
+ if(exactCount == 0) {
1269
+ return (value === '');
1270
+ }
1271
+ if(exactCount == 1) {
1272
+ return (value !== '' && value.search(',') === -1);
1273
+ }
1274
+ return (value.split(',').length == exactCount);
1100
1275
  },
1101
1276
 
1102
- // value is not value (case sensitive)
1103
- notExactly: function(value, notValue) {
1104
- return (value != notValue);
1277
+ minCount: function(value, minCount) {
1278
+ if(minCount == 0) {
1279
+ return true;
1280
+ }
1281
+ if(minCount == 1) {
1282
+ return (value !== '');
1283
+ }
1284
+ return (value.split(',').length >= minCount);
1105
1285
  },
1106
1286
 
1107
- // value is most likely url
1108
- url: function(value) {
1109
- var
1110
- urlRegExp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
1111
- ;
1112
- return urlRegExp.test(value);
1287
+ maxCount: function(value, maxCount) {
1288
+ if(maxCount == 0) {
1289
+ return false;
1290
+ }
1291
+ if(maxCount == 1) {
1292
+ return (value.search(',') === -1);
1293
+ }
1294
+ return (value.split(',').length <= maxCount);
1113
1295
  }
1114
1296
  }
1115
1297