clientside_validation.module 24.8 KB
Newer Older
Peter Droogmans's avatar
Peter Droogmans committed
1
<?php
Jelle's avatar
Jelle committed
2
// $Id$
Peter Droogmans's avatar
Peter Droogmans committed
3
4
/**
 * @file
5
 * Add client side validation to forms.
Peter Droogmans's avatar
Peter Droogmans committed
6
 */
7
8
9
define('CLIENTSIDE_VALIDATION_VALIDATE_ALL', 1);
define('CLIENTSIDE_VALIDATION_VALIDATE_SPECIFIC', 0);
define('CLIENTSIDE_VALIDATION_VALIDATE_ALL_EXCEPT', 2);
Peter Droogmans's avatar
Peter Droogmans committed
10
11
12
13
/**
 * Implements hook_menu().
 */
function clientside_validation_menu() {
14
15
16
17
18
19
20
21
22
23
  $items['admin/config/validation'] = array(
    'title' => 'Validation',
    'description' => 'Validation settings.',
    'position' => 'right',
    'weight' => -10,
    'page callback' => 'drupal_get_form',
    'page arguments' => array('clientside_validation_admin_settings'),
    'access arguments' => array('access administration pages'),
  );
  $items['admin/config/validation/clientside_validation'] = array(
Peter Droogmans's avatar
Peter Droogmans committed
24
25
26
27
28
    'title' => 'Clientside Validation',
    'description' => 'Administer clientside validation.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('clientside_validation_admin_settings'),
    'access arguments' => array('administer site configuration'),
Jelle Sebreghts's avatar
Jelle Sebreghts committed
29
  );
30
  $items['clientside_validation/ajax'] = array(
Jelle Sebreghts's avatar
Jelle Sebreghts committed
31
32
33
34
    'title' => 'Clientside validation ajax callback',
    'page callback' => '_clientside_validation_ajax_call',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
Peter Droogmans's avatar
Peter Droogmans committed
35
36
37
38
  );
  return $items;
}

Jelle Sebreghts's avatar
Jelle Sebreghts committed
39
function _clientside_validation_ajax_call() {
Jelle Sebreghts's avatar
Jelle Sebreghts committed
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  $param = $_POST['param'];
  $value = $_POST['value'];
  $result = array();
  foreach ($param['expressions'] as $key => $regex) {
    if (!(bool) preg_match($regex, (string) $value)) {
      $result =  array('result' => FALSE, 'message' => $param['messages'][$key]);
      break;
    }
  }
  if (empty($result)) {
    $result = array('result' => TRUE);
  }
  drupal_json_output($result);
}


Peter Droogmans's avatar
Peter Droogmans committed
56
57
58
59
60
function clientside_validation_admin_settings() {
  $form['clientside_validation'] = array(
    '#type' => 'fieldset',
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
61
62
    '#title' => t('Error message settings'),
    '#description' => t('Change error message related settings.'),
Peter Droogmans's avatar
Peter Droogmans committed
63
  );
64

Peter Droogmans's avatar
Peter Droogmans committed
65
66
67
68
69
70
  $form['clientside_validation']['clientside_validation_prefix'] = array(
    '#title' => t('Field name prefix'),
    '#description' => t('The prefix of the field name in the error messages.'),
    '#type' => 'textfield',
    '#default_value' => variable_get('clientside_validation_prefix', ''),
  );
71

Peter Droogmans's avatar
Peter Droogmans committed
72
73
74
75
76
77
  $form['clientside_validation']['clientside_validation_suffix'] = array(
    '#title' => t('Field name suffix'),
    '#description' => t('The suffix of the field name in the error messages.'),
    '#type' => 'textfield',
    '#default_value' => variable_get('clientside_validation_suffix', ''),
  );
78

Peter Droogmans's avatar
Peter Droogmans committed
79
80
81
  $form['clientside_validation']['example_image'] = array(
    '#type' => 'item',
    '#title' => t('Example'),
82
    '#markup' => '<img id="clientside_validation_example_image" src="' . base_path() . drupal_get_path('module', 'clientside_validation') . '/errormsg.png" alt="' . t('Error message example') . '" />',
Peter Droogmans's avatar
Peter Droogmans committed
83
84
85
    '#description' => t('Filling in double quotes in both the above fields will give this result.'),
  );

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  $form['clientside_validation']['clientside_validation_scrollto_errormessage'] = array(
    '#title' => t('Scroll to error message'),
    '#description' => t('If checked, the page will automatically scroll to the error messages when validation fails.'),
    '#type' => 'checkbox',
    '#default_value' => variable_get('clientside_validation_scrollto_errormessage', 1),
  );

  $form['clientside_validation']['clientside_validation_scroll_speed'] = array(
    '#title' => t('Scroll speed'),
    '#description' => t('The scroll speed in milliseconds'),
    '#type' => 'textfield',
    '#default_value' => variable_get('clientside_validation_scroll_speed', 1000),
    '#states' => array(
      'visible' => array(
        'input[name="clientside_validation_scrollto_errormessage"]' => array('checked' => TRUE),
      ),
    ),
  );

  if (module_exists('fapi_validation') && module_exists('clientside_validation_fapi')) {
    $form['clientside_validation']['clientside_validation_scroll_speed'] += array('#rules' => array('numeric'));
  }

Peter Droogmans's avatar
Peter Droogmans committed
109
110
111
112
113
114
115
  $form['clientside_validation_min'] = array(
    '#type' => 'fieldset',
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
    '#title' => t('Use minified version of jquery.validate.js'),
    '#description' => t('You can use the minified version of the library.'),
  );
116

Peter Droogmans's avatar
Peter Droogmans committed
117
118
119
120
121
122
123
124
125
  $form['clientside_validation_min']['clientside_validation_use_minified'] = array(
    '#type' => 'radios',
    '#options' => array(
      '0' => t('No'), 
      '1' => t('Yes')
    ),
    '#default_value' => variable_get('clientside_validation_use_minified', 0), 
    '#title' => t('Use minified version?'),
  );
126

127
  $form['clientside_validation_include_hidden'] = array(
128
129
130
    '#type' => 'fieldset',
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
131
    '#title' => t('Behaviour for hidden fields'),
132
  );
133

134
  $form['clientside_validation_include_hidden']['clientside_validation_include_hidden'] = array(
135
136
    '#type' => 'textarea',
    '#default_value' => variable_get('clientside_validation_include_hidden', ''),
137
138
139
    '#title' => t("Don't ignore hidden fields on the following forms"),
    '#description' => t('You can specify form IDs (one per line) of forms that should have hidden elements validated.'),
  );
140

141
142
  $form['clientside_validation_include_hidden']['clientside_validation_validate_tabs'] = array(
    '#type' => 'checkbox',
143
    '#default_value' => variable_get('clientside_validation_validate_tabs', 1),
144
145
146
147
    '#title' => t('Validate all vertical tabs'),
    '#description' => t('If you check this, all tabs will be validated on submit
                      (including the hidden ones). Warning: if there are other hidden
                      fields (e.g. conditional fields), those will be validated too.'),
148
  );
149
150
151
152
153
154
155
156
157
  
  $form['clientside_validation_validate_forms'] = array(
    '#type' => 'fieldset',
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
    '#title' => t('Forms to validate'),
  );

  $form['clientside_validation_validate_forms']['clientside_validation_validate_all'] = array(
158
159
160
161
162
163
164
165
    '#type' => 'radios',
    '#default_value' => variable_get('clientside_validation_validate_all', CLIENTSIDE_VALIDATION_VALIDATE_ALL),
    '#title' => t('Select the forms to validate'),
    '#options' => array(
      CLIENTSIDE_VALIDATION_VALIDATE_ALL => t('Validate all forms'),
      CLIENTSIDE_VALIDATION_VALIDATE_SPECIFIC => t('Only validate forms listed below'),
      CLIENTSIDE_VALIDATION_VALIDATE_ALL_EXCEPT => t('Validate all forms except those listed below')
    )
166
167
168
169
170
  );

  $form['clientside_validation_validate_forms']['clientside_validation_validate_specific'] = array(
    '#type' => 'textarea',
    '#default_value' => variable_get('clientside_validation_validate_specific', ''),
171
172
    '#title' => t("Enter form IDs below"),
    '#description' => t('You can specify form IDs (one per line) of forms that should or should not be validated.'),
173
174
    '#states' => array(
      'invisible' => array(
175
       'input[name="clientside_validation_validate_all"]' => array('value' => (string)CLIENTSIDE_VALIDATION_VALIDATE_ALL),
176
177
178
      ),
    ),
  );
179

Peter Droogmans's avatar
Peter Droogmans committed
180
181
182
  return system_settings_form($form);
}

Peter Droogmans's avatar
Peter Droogmans committed
183
/**
184
 * Implementation of hook_form_alter().
Peter Droogmans's avatar
Peter Droogmans committed
185
 */
186
function clientside_validation_form_alter(&$form, &$form_state, $form_id) {
187
188
  $validate_specific_setting = variable_get('clientside_validation_validate_specific', '');
  $validate_specific = preg_split('/(\r\n?|\n)/', $validate_specific_setting, -1, PREG_SPLIT_NO_EMPTY);
189
190
191
192
193
194
  if (variable_get('clientside_validation_validate_all', CLIENTSIDE_VALIDATION_VALIDATE_ALL) == CLIENTSIDE_VALIDATION_VALIDATE_SPECIFIC
    && !in_array($form_id, $validate_specific)) {
    return;
  }
  elseif (variable_get('clientside_validation_validate_all', CLIENTSIDE_VALIDATION_VALIDATE_ALL) == CLIENTSIDE_VALIDATION_VALIDATE_ALL_EXCEPT
    && in_array($form_id, $validate_specific)) {
195
196
    return;
  }
197
198
  if (strpos($form_id, 'webform_client_form') !== FALSE) {
    if (isset($form['actions']['previous'])) {
199
      $form['actions']['previous']['#attributes']['class'][] = 'cancel';
200
    }
201
    $form['#after_build'][] = 'clientside_validation_webform_after_build';
202
  }
203
  else {
204
205
206
    if (isset($form['actions']['delete'])) {
      $form['actions']['delete']['#attributes']['class'][] = 'cancel';
    }
207
208
209
210
211
212
213
214
215
216
    switch ($form['#id']) {
      case 'node-form':
      case 'webform-component-edit-form':
        $form['#after_build'][] = 'clientside_validation_form_after_build';
        break;
      default:
        $form['#after_build'][] = 'clientside_validation_form_after_build';
        break;
    }
  }
217
218
219
220
221
222
223
224

  // Add a setting for this form if the hidden elements should still be validated
  $include_hidden_setting = variable_get('clientside_validation_include_hidden', '');
  $include_hidden = preg_split('/(\r\n?|\n)/', $include_hidden_setting, -1, PREG_SPLIT_NO_EMPTY);
  if (in_array($form_id, $include_hidden)) {
    $setting['clientsideValidation']['forms'][$form['#id']]['includeHidden'] = TRUE;
    drupal_add_js($setting, 'setting');
  }
225
226
227
228
229
230
231
232
}

/**
 * Webform.
 */
function clientside_validation_webform_after_build(&$form, &$form_state) {
  $js_rules = array();
  drupal_alter("clientside_validation_webform", $form, $form_state, $js_rules);
Peter Droogmans's avatar
Peter Droogmans committed
233
  if (!empty($js_rules)) {
Jelle's avatar
Jelle committed
234
    $settings['clientsideValidation']['general'] = array(
Peter Droogmans's avatar
Peter Droogmans committed
235
236
      "errorClass" => "error",
      "wrapper" => "li",
Jelle Sebreghts's avatar
Jelle Sebreghts committed
237
      "validateTabs" =>  variable_get('clientside_validation_validate_tabs', 1),
238
239
      "scrollTo" => variable_get('clientside_validation_scrollto_errormessage', 1),
      "scrollSpeed" => (int)variable_get('clientside_validation_scroll_speed', 1000),
Peter Droogmans's avatar
Peter Droogmans committed
240
241
242
243
244
    );
    $settings['clientsideValidation']['forms'][$form['#id']]['settings'] = array(
      "errorContainer" => "#formerrors-" . $form['#id'],
      "errorLabelContainer" => "#formerrors-" . $form['#id'] . " ul",
    );
Jelle's avatar
Jelle committed
245
    foreach ($js_rules as $key => $rule) {
Peter Droogmans's avatar
Peter Droogmans committed
246
247
248
249
250
251
252
253
254
255
256
257
258
259
      if (isset($rule['checkboxgroupminmax'])) {
        $settings['clientsideValidation']['forms'][$form['#id']]['checkboxrules'][$key] = array(
            'checkboxgroupminmax' => $rule['checkboxgroupminmax'],
            'messages' => array('checkboxgroupminmax' => $rule['messages']['checkboxgroupminmax'])
        );
        unset($rule['checkboxgroupminmax']);
        unset($rule['messages']['checkboxgroupminmax']);
        if (empty($rule['messages'])) {
          unset($rule['messages']);
        }
      }
      if (!empty($rule)) {
        $settings['clientsideValidation']['forms'][$form['#id']]['rules'][$key] = $rule;
      }
Peter Droogmans's avatar
Peter Droogmans committed
260
    }
Peter Droogmans's avatar
Peter Droogmans committed
261
262
263
264
265
266
267
    
    if (variable_get('clientside_validation_use_minified', 0) == 0) {
      drupal_add_js(drupal_get_path('module', 'clientside_validation') . '/jquery-validate/jquery.validate.js');
    }
    else {
      drupal_add_js(drupal_get_path('module', 'clientside_validation') . '/jquery-validate/jquery.validate.min.js');
    }
Peter Droogmans's avatar
Peter Droogmans committed
268
    drupal_add_js(drupal_get_path('module', 'clientside_validation') . '/clientside_validation.js');
Peter Droogmans's avatar
Peter Droogmans committed
269
270
271
272
273
274
    drupal_add_js($settings, 'setting');
  }
  return $form;
}

/**
275
 * Regular form.
Peter Droogmans's avatar
Peter Droogmans committed
276
277
278
 */
function clientside_validation_form_after_build(&$form, &$form_state) {
  static $js_rules = array();
279
280
281
282
283
  static $form_ids = array();
  if (isset($form_ids[$form['#id']])) {
    return $form;
  }

284
  drupal_alter("clientside_validation_form", $form, $form_state, $js_rules);
Peter Droogmans's avatar
Peter Droogmans committed
285
  if (!empty($js_rules)) {
Jelle's avatar
Jelle committed
286
    $settings['clientsideValidation']['general'] = array(
Peter Droogmans's avatar
Peter Droogmans committed
287
288
      "errorClass" => "error",
      "wrapper" => "li",
289
      "validateTabs" =>  variable_get('clientside_validation_validate_tabs', 1),
290
291
      "scrollTo" => variable_get('clientside_validation_scrollto_errormessage', 1),
      "scrollSpeed" => (int)variable_get('clientside_validation_scroll_speed', 1000),
Peter Droogmans's avatar
Peter Droogmans committed
292
293
294
295
296
    );
    $settings['clientsideValidation']['forms'][$form['#id']]['settings'] = array(
      "errorContainer" => "#formerrors-" . $form['#id'],
      "errorLabelContainer" => "#formerrors-" . $form['#id'] . " ul",
    );
Jelle's avatar
Jelle committed
297
    foreach ($js_rules as $key => $rule) {
Jelle Sebreghts's avatar
Jelle Sebreghts committed
298
299
300
301
302
303
304
305
306
307
308
309
310
311
      if (isset($rule['checkboxgroupminmax'])) {
        $settings['clientsideValidation']['forms'][$form['#id']]['checkboxrules'][$key] = array(
            'checkboxgroupminmax' => $rule['checkboxgroupminmax'],
            'messages' => array('checkboxgroupminmax' => $rule['messages']['checkboxgroupminmax'])
        );
        unset($rule['checkboxgroupminmax']);
        unset($rule['messages']['checkboxgroupminmax']);
        if (empty($rule['messages'])) {
          unset($rule['messages']);
        }
      }
      if (!empty($rule)) {
        $settings['clientsideValidation']['forms'][$form['#id']]['rules'][$key] = $rule;
      }
Peter Droogmans's avatar
Peter Droogmans committed
312
    }
Peter Droogmans's avatar
Peter Droogmans committed
313
314
315
316
317
318
    if (variable_get('clientside_validation_use_minified', 0) == 0) {
      drupal_add_js(drupal_get_path('module', 'clientside_validation') . '/jquery-validate/jquery.validate.js');
    }
    else {
      drupal_add_js(drupal_get_path('module', 'clientside_validation') . '/jquery-validate/jquery.validate.min.js');
    }
Peter Droogmans's avatar
Peter Droogmans committed
319
    drupal_add_js(drupal_get_path('module', 'clientside_validation') . '/clientside_validation.js');
Peter Droogmans's avatar
Peter Droogmans committed
320
    drupal_add_js($settings, 'setting');
321
    $form_ids[$form['#id']] = TRUE;
Peter Droogmans's avatar
Peter Droogmans committed
322
323
  }

324
  return $form;
Peter Droogmans's avatar
Peter Droogmans committed
325
326
}

327
328
329
/**
 * Set validation rule for required fields.
 */
Jelle's avatar
Jelle committed
330
function _clientside_validation_set_required($name, $title, $required, &$js_rules, $message = '') {
Jelle Sebreghts's avatar
Jelle Sebreghts committed
331
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
Peter Droogmans's avatar
Peter Droogmans committed
332
333
  if ($required) {
    $js_rules[$name]['required'] = TRUE;
334
    $js_rules[$name]['messages']['required'] = (empty($message)) ? t('!name field is required.', array('!name' => $title)) : $message;
Peter Droogmans's avatar
Peter Droogmans committed
335
336
337
  }
}

338
339
340
/**
 * Set validation rule for number fields.
 */
Jelle's avatar
Jelle committed
341
function _clientside_validation_set_number($name, $title, $decimalpoint, &$js_rules) {
Jelle Sebreghts's avatar
Jelle Sebreghts committed
342
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
Peter Droogmans's avatar
Peter Droogmans committed
343
344
345
346
  $js_rules[$name]['digits_negative'] = TRUE;
  $js_rules[$name]['messages']['digits_negative'] = t('!name field accepts only numbers.', array('!name' => $title));
}

347
348
349
/**
 * Set validation rule for decimal fields.
 */
350
function _clientside_validation_set_number_decimal($name, $title, $decimalpoint, &$js_rules) {
Jelle Sebreghts's avatar
Jelle Sebreghts committed
351
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
Peter Droogmans's avatar
Peter Droogmans committed
352
353
354
355
356
357
358
359
360
361
  if ($decimalpoint == '.') {
    $js_rules[$name]['number'] = TRUE;
    $js_rules[$name]['messages']['number'] = t('!name field accepts only numbers (use a \'.\' as decimal point).', array('!name' => $title));
  }
  else {
    $js_rules[$name]['numberDE'] = TRUE;
    $js_rules[$name]['messages']['numberDE'] = t('!name field accepts only numbers (use a \',\' as decimal point).', array('!name' => $title));
  }
}

362
363
364
/**
 * Set validation rule for fields with a minimum and/or a maximum value.
 */
Jelle's avatar
Jelle committed
365
function _clientside_validation_set_minmax($name, $title, $min, $max, &$js_rules, $message = '') {
Jelle Sebreghts's avatar
Jelle Sebreghts committed
366
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
Peter Droogmans's avatar
Peter Droogmans committed
367
368
  if (isset($min) && $min != '' && isset($max) && $max != '') {
    $js_rules[$name]['range'] = array($min, $max);
369
    $js_rules[$name]['messages']['range'] = (empty($message)) ? t('!name field has to be between !min and !max.', array('!name' => $title, '!min' => $min, '!max' => $max)) : $message;
Peter Droogmans's avatar
Peter Droogmans committed
370
  }
Jelle's avatar
Jelle committed
371
  elseif (isset($min) && $min != '') {
Peter Droogmans's avatar
Peter Droogmans committed
372
    $js_rules[$name]['min'] = $min;
373
    $js_rules[$name]['messages']['min'] = (empty($message)) ? t('!name field has to be greater than !min.', array('!name' => $title, '!min' => $min)) : $message;
Peter Droogmans's avatar
Peter Droogmans committed
374
  }
Jelle's avatar
Jelle committed
375
  elseif (isset($max) && $max != '') {
Peter Droogmans's avatar
Peter Droogmans committed
376
    $js_rules[$name]['max'] = $max;
377
    $js_rules[$name]['messages']['max'] = (empty($message)) ? t('!name field has to be smaller than !max.', array('!name' => $title, '!max' => $max)) : $message;
Peter Droogmans's avatar
Peter Droogmans committed
378
379
380
  }
}

381
382
383
/**
 * Set validation rule for fields with a minimum and/or maximum length.
 */
Jelle's avatar
Jelle committed
384
function _clientside_validation_set_minmaxlength($name, $title, $min, $max, &$js_rules, $message = '') {
Jelle Sebreghts's avatar
Jelle Sebreghts committed
385
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
Jelle Sebreghts's avatar
Jelle Sebreghts committed
386
  if ($max == 1) {
387
388
    $max = '';
  }
Peter Droogmans's avatar
Peter Droogmans committed
389
390
  if (isset($min) && $min != '' && isset($max) && $max != '') {
    $js_rules[$name]['rangelength'] = array($min, $max);
391
    $js_rules[$name]['messages']['rangelength'] = (empty($message)) ? t('!name field has to have between !min and !max values.', array('!name' => $title, '!min' => $min, '!max' => $max)) : $message;
Peter Droogmans's avatar
Peter Droogmans committed
392
  }
Jelle's avatar
Jelle committed
393
  elseif (isset($min) && $min != '') {
Peter Droogmans's avatar
Peter Droogmans committed
394
    $js_rules[$name]['minlength'] = $min;
395
    $js_rules[$name]['messages']['minlength'] = (empty($message)) ? t('!name field has to have minimal !min values.', array('!name' => $title, '!min' => $min)) : $message;
Peter Droogmans's avatar
Peter Droogmans committed
396
  }
Jelle's avatar
Jelle committed
397
  elseif (isset($max) && $max != '') {
Peter Droogmans's avatar
Peter Droogmans committed
398
    $js_rules[$name]['maxlength'] = $max;
399
    $js_rules[$name]['messages']['maxlength'] = (empty($message)) ? t('!name field has to have maximum !max values.', array('!name' => $title, '!max' => $max)) : $message;
Peter Droogmans's avatar
Peter Droogmans committed
400
401
402
  }
}

403
404
405
/**
 * Set validation rule for required fields that must equal a value from an other field.
 */
Jelle's avatar
Jelle committed
406
function _clientside_validation_set_equal($name, $title, $value, &$js_rules) {
Jelle Sebreghts's avatar
Jelle Sebreghts committed
407
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
408
409
410
411
412
413
414
  $js_rules[$name]['equalTo'] = ':input[name=\'submitted[' . $value['form_key'] . ']\']';
  $js_rules[$name]['messages']['equalTo'] = t('!name field has to be equal to !firstone.', array('!name' => $title, '!firstone' => $value['name']));
}

/**
 * Set validation rule for fields that can not be equal to a value from an other field.
 */
Jelle's avatar
Jelle committed
415
function _clientside_validation_set_not_equal($name, $title, $value, &$js_rules, $message = '') {
416
  $js_rules[$name]['notEqualTo'] = ':input[name=\'submitted[' . $value['form_key'] . ']\']';
Jelle Sebreghts's avatar
Jelle Sebreghts committed
417
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
418
419
420
421
422
423
424
  $message = empty($message) ? t('!name field has to different from !firstone.', array('!name' => $title, '!firstone' => $value['name'])) : $message;
  $js_rules[$name]['messages']['notEqualTo'] = $message;
}

/**
 * Set validation rule for fields that must be equal to a specific value.
 */
Jelle's avatar
Jelle committed
425
function _clientside_validation_set_specific_value($name, $title, $value, &$js_rules, $message = '') {
426
  $js_rules[$name]['oneOf'] = $value;
Jelle Sebreghts's avatar
Jelle Sebreghts committed
427
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
428
429
430
431
  $message = empty($message) ? t('!name field has to different from !firstone.', array('!name' => $title, '!firstone' => $value['name'])) : $message;
  $js_rules[$name]['messages']['oneOf'] = $message;
}

432
433
434
435
436
437
438
439
440
441
/**
 * Set validation rule for fields that consist of one or more of specific values (e.g. string with only a, b and c in it).
 */
function _clientside_validation_set_specific_values($name, $title, $values, &$js_rules, $message = '') {
  $js_rules[$name]['specificVals'] = $values;
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
  $message = empty($message) ? t('!name field must consist of following elements only: !elements.', array('!name' => $title, '!elements' => implode(', ', $values))) : $message;
  $js_rules[$name]['messages']['specificVals'] = $message;
}

442
443
444
/**
 * Set validation rule for ean number fields.
 */
Jelle's avatar
Jelle committed
445
function _clientside_validation_set_ean($name, $title, &$js_rules, $message = '') {
Jelle Sebreghts's avatar
Jelle Sebreghts committed
446
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
447
448
  $message = empty($message) ? t('!name field is not a valid EAN number.', array('!name' => $title)) : $message;
  $js_rules[$name]['validEAN'] = TRUE;
Peter Droogmans's avatar
Peter Droogmans committed
449
  $js_rules[$name]['messages']['validEAN'] = $message;
Peter Droogmans's avatar
Peter Droogmans committed
450
451
}

452
453
454
/**
 * Set validation rule for fields with regex validation from webform_validation
 */
455
function _clientside_validation_set_regex($name, $title, &$js_rules, $expression, $message = '', $modifiers = "") {
456
457
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
  $message = empty($message) ? t('!name field is not a valid EAN number.', array('!name' => $title)) : $message;
458
  $js_rules[$name]['regexMatch'] = array($expression);
Jelle Sebreghts's avatar
Jelle Sebreghts committed
459
  if (!empty($modifiers)) {
460
461
    $js_rules[$name]['regexMatch'][] = $modifiers;
  }
462
463
464
  $js_rules[$name]['messages']['regexMatch'] = $message;
}

Jelle Sebreghts's avatar
Jelle Sebreghts committed
465
466
467
468
469
470
471
472
473
474
/**
 * Set validation rule for fields with regex validation from webform_validation
 */
function _clientside_validation_set_regex_pcre($name, $title, &$js_rules, $expression, $message = '') {
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
  $message = empty($message) ? t('!name field is not a valid EAN number.', array('!name' => $title)) : $message;
  $js_rules[$name]['regexMatchPCRE']['expressions'][] = $expression;
    $js_rules[$name]['regexMatchPCRE']['messages'][] = $message;
}

475
476
477
/**
 * Set validation rule for file fields that must have a certain extension.
 */
Jelle's avatar
Jelle committed
478
function _clientside_validation_set_extensions($name, $extensions, &$js_rules) {
479
480
481
482
483
484
485
486
  $extension_list = preg_replace('#,(?![^,]+,)#', ' or', implode(', ', $extensions));
  $js_rules[$name]['accept'] = implode('|', $extensions);
  $js_rules[$name]['messages']['accept'] = t("Only files with a %exts extension are allowed.", array('%exts' => $extension_list));
}

/**
 * Set validation rule for checkboxes.
 */
487
function _clientside_validation_set_checkboxgroup_minmax($name, $title, $id, &$js_rules, $message = '', $min = 1, $max = 99) {
Jelle Sebreghts's avatar
Jelle Sebreghts committed
488
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
489
  $message = empty($message) ? t('!name field is required.', array('!name' => $title)) : $message;
490
  $js_rules[$name]['checkboxgroupminmax'] = array($min, $max, $id);
491
  $js_rules[$name]['messages']['checkboxgroupminmax'] = $message;
492
493
494
495
496
}

/**
 * Set validation rule for email fields.
 */
Jelle's avatar
Jelle committed
497
function _clientside_validation_set_email($name, $title, &$js_rules) {
Jelle Sebreghts's avatar
Jelle Sebreghts committed
498
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
499
500
501
502
  $js_rules[$name]['email'] = TRUE;
  $js_rules[$name]['messages']['email'] = t('The value in !name is not a valid email address.', array('!name' => $title));
}

503
504
505
/**
 * Set validation rule for url fields.
 */
Jelle Sebreghts's avatar
Jelle Sebreghts committed
506
function _clientside_validation_set_url($name, $title, &$js_rules) {
507
508
509
510
511
512
  $title = variable_get('clientside_validation_prefix', '') . $title . variable_get('clientside_validation_suffix', '');
  $js_rules[$name]['url'] = TRUE;
  $js_rules[$name]['messages']['url'] = t('The value in !name is not a valid url.', array('!name' => $title));
}

/**
Jelle Sebreghts's avatar
Jelle Sebreghts committed
513
 * Set fapi validation.
514
 */
Jelle Sebreghts's avatar
Jelle Sebreghts committed
515
function _clientside_validation_set_fapi_validation($name, $title, $callback, $params, &$js_rules, $message = '') {
516
  $expressions = array(
Jelle Sebreghts's avatar
Jelle Sebreghts committed
517
518
519
520
521
522
    'fapi_validation_rule_alpha' => '/^[\pL]++$/uD',
    'fapi_validation_rule_alpha_numeric' => '/^[\pL\pN]++$/uD',
    'fapi_validation_rule_ipv4' => '/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
      . '(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/',
    'fapi_validation_rule_alpha_dash' => '/^[-\pL\pN_]+$/uD',
    'fapi_validation_rule_digit' => '/^\d+$/',
523
524
525
526
527
528
529
530
  );
  switch ($callback) {
    case 'fapi_validation_rule_alpha':
    case 'fapi_validation_rule_alpha_numeric':
    case 'fapi_validation_rule_ipv4':
    case 'fapi_validation_rule_alpha_dash':
    case 'fapi_validation_rule_digit':
    case 'fapi_validation_rule_regexp':
Jelle Sebreghts's avatar
Jelle Sebreghts committed
531
      if ($callback == 'fapi_validation_rule_regexp') {
Jelle Sebreghts's avatar
Jelle Sebreghts committed
532
        $expressions['fapi_validation_rule_regexp'] = $params[1][0];
533
534
      }
      $message = t($message, array('%field' => $title));
Jelle Sebreghts's avatar
Jelle Sebreghts committed
535
      _clientside_validation_set_regex_pcre($name, $title, $js_rules, $expressions[$callback], $message);
536
537
538
539
540
541
542
543
544

      break;
    case 'fapi_validation_rule_numeric':
      _clientside_validation_set_number($name, $title, '.', $js_rules);
      break;
    case 'fapi_validation_rule_email':
      _clientside_validation_set_email($name, $title, $js_rules);
      break;
    case 'fapi_validation_rule_length':
Jelle Sebreghts's avatar
Jelle Sebreghts committed
545
      if (count($params[1]) == 1) {
546
547
        _clientside_validation_set_minmaxlength($name, $title, '', $params[1][0], $js_rules);
      }
Jelle Sebreghts's avatar
Jelle Sebreghts committed
548
      elseif (count($params[1]) == 2) {
549
550
551
552
553
554
555
556
557
558
        _clientside_validation_set_minmaxlength($name, $title, $params[1][0], $params[1][1], $js_rules);
      }
      break;
    case 'fapi_validation_rule_url':
      _clientside_validation_set_url($name, $title, $js_rules);
      break;
    case 'fapi_validation_rule_chars':
      _clientside_validation_set_specific_values($name, $title, $params[1], $js_rules);
      break;
    case 'fapi_validation_rule_decimal':
Jelle Sebreghts's avatar
Jelle Sebreghts committed
559
      $message = t($message, array('%field' => $title));
Jelle Sebreghts's avatar
Jelle Sebreghts committed
560
561
      if (count($params[1]) == 2) {
        $expression = '/^[0-9]{' . $params[1][0] . '}\.[0-9]{' . $params[1][1] . '}$/';
Jelle Sebreghts's avatar
Jelle Sebreghts committed
562
563
564
565
566
      }
      else {
        $expression = '/\d+\.\d+/';
      }
      _clientside_validation_set_regex_pcre($name, $title, $js_rules, $expression, $message);
567
568
569
570
571
572
      break;
    default:
      break;
  }
}

573
574
575
function clientside_validation_drupal_json_encode($var) {
  return str_replace(array('<', '>', '&'), array('\u003c', '\u003e', '\u0026'), json_encode($var));
}