5c975ee46a1503d53c51940ed74776b05d863569
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Resources / Public / JavaScript / FormEngineValidation.js
1 /*
2 * This file is part of the TYPO3 CMS project.
3 *
4 * It is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, either version 2
6 * of the License, or any later version.
7 *
8 * For the full copyright and license information, please read the
9 * LICENSE.txt file that was distributed with this source code.
10 *
11 * The TYPO3 project - inspiring people to share!
12 */
13
14 /**
15 * contains all JS functions related to TYPO3 TCEforms/FormEngineValidation
16 */
17 define('TYPO3/CMS/Backend/FormEngineValidation', ['jquery', 'TYPO3/CMS/Backend/FormEngine'], function ($, FormEngine) {
18
19 /**
20 * the main FormEngineValidation object
21 *
22 * @type {{rulesSelector: string, dateTimeSelector: string, groupFieldHiddenElement: string, relatedFieldSelector: string}}
23 */
24 var FormEngineValidation = {
25 rulesSelector: '[data-formengine-validation-rules]',
26 dateTimeSelector: '.t3js-datetimepicker',
27 groupFieldHiddenElement: '.t3js-formengine-field-group input[type=hidden]',
28 relatedFieldSelector: '[data-relatedfieldname]'
29 };
30
31 /**
32 * initialize validation for the first time
33 */
34 FormEngineValidation.initialize = function() {
35 $(document).find('.has-error').removeClass('has-error');
36
37 // bind to field changes
38 $(document).on('change', FormEngineValidation.rulesSelector, function() {
39 // we need to wait, because the update of the select field needs some time
40 window.setTimeout(function() {
41 FormEngineValidation.validate();
42 }, 500);
43 });
44
45 // bind to datepicker changes
46 $(document).on('dp.change', FormEngineValidation.dateTimeSelector, function(event) {
47 FormEngineValidation.validate();
48 });
49
50 if (typeof RTEarea !== 'undefined') {
51 console.log(RTEarea);
52 }
53 };
54
55 /**
56 * validate the complete form
57 */
58 FormEngineValidation.validate = function() {
59 $(document).find('.t3js-formengine-validation-marker, .t3js-tabmenu-item')
60 .removeClass('has-error')
61 .removeClass('has-validation-error');
62
63 $(FormEngineValidation.rulesSelector).each(function() {
64 var $field = $(this);
65 var $rules = $field.data('formengine-validation-rules');
66 var markParent = false;
67 var selected = 0;
68 $rules.each(function(rule) {
69 switch (rule.type) {
70 case 'required':
71 if ($field.val() === '') {
72 markParent = true;
73 $field.closest('.t3js-formengine-validation-marker').addClass('has-error');
74 }
75 break;
76 case 'range':
77 if (rule.minItems || rule.maxItems) {
78 $relatedField = $(document).find('[name="' + $field.data('relatedfieldname') + '"]');
79 if ($relatedField.length) {
80 selected = FormEngineValidation.trimExplode(',', $relatedField.val()).length;
81 if (selected < rule.minItems || selected > rule.maxItems) {
82 markParent = true;
83 $field.closest('.t3js-formengine-validation-marker').addClass('has-error');
84 }
85 } else {
86 selected = $field.val();
87 if (selected < rule.minItems || selected > rule.maxItems) {
88 markParent = true;
89 $field.closest('.t3js-formengine-validation-marker').addClass('has-error');
90 }
91
92 }
93 }
94 break;
95 case 'select':
96 if (rule.minItems || rule.maxItems) {
97 $relatedField = $(document).find('[name="' + $field.data('relatedfieldname') + '"]');
98 if ($relatedField.length) {
99 selected = FormEngineValidation.trimExplode(',', $relatedField.val()).length;
100 if (selected < rule.minItems || selected > rule.maxItems) {
101 markParent = true;
102 $field.closest('.t3js-formengine-validation-marker').addClass('has-error');
103 }
104 } else {
105 selected = $field.find('option:selected').length;
106 if (selected < rule.minItems || selected > rule.maxItems) {
107 markParent = true;
108 $field.closest('.t3js-formengine-validation-marker').addClass('has-error');
109 }
110
111 }
112 }
113 break;
114 case 'group':
115 if (rule.minItems || rule.maxItems) {
116 selected = $field.find('option').length;
117 if (selected < rule.minItems || selected > rule.maxItems) {
118 markParent = true;
119 $field.closest('.t3js-formengine-validation-marker').addClass('has-error');
120 }
121 }
122 break;
123 case 'inline':
124 if (rule.minItems || rule.maxItems) {
125 selected = FormEngineValidation.trimExplode(',', $field.val()).length;
126 if (selected < rule.minItems || selected > rule.maxItems) {
127 markParent = true;
128 $field.closest('.t3js-formengine-validation-marker').addClass('has-error');
129 }
130 }
131 break;
132 default:
133 FormEngineValidation.log('unknown validation type: ' + rule.type);
134 }
135 });
136 if (markParent) {
137 // check tabs
138 FormEngineValidation.markParentTab($field);
139 }
140 });
141 };
142
143 /**
144 * helper function to get clean trimmed array from comma list
145 *
146 * @param delimiter
147 * @param string
148 * @returns {Array}
149 */
150 FormEngineValidation.trimExplode = function(delimiter, string) {
151 var result = [];
152 var items = string.split(delimiter);
153 for (var i=0; i<items.length; i++) {
154 var item = items[i].trim();
155 if (item.length > 0) {
156 result.push(item);
157 }
158 }
159 return result;
160 };
161
162 /**
163 * find tab by field and mark it as has-validation-error
164 *
165 * @param $element
166 */
167 FormEngineValidation.markParentTab = function($element) {
168 var $panes = $element.parents('.tab-pane');
169 $panes.each(function() {
170 var $pane = $(this);
171 var id = $pane.attr('id');
172 $(document)
173 .find('a[href="#' + id + '"]')
174 .closest('.t3js-tabmenu-item')
175 .addClass('has-validation-error');
176 });
177 };
178
179 /**
180 * helper function for console.log message
181 *
182 * @param msg
183 */
184 FormEngineValidation.log = function(msg) {
185 if (typeof console !== 'undefined') {
186 console.log(msg);
187 }
188 };
189
190 /**
191 * initialize function
192 */
193 FormEngineValidation.initialize();
194 // Start first validation after one second, because all fields are initial empty (typo3form.fieldSet)
195 window.setTimeout(function() {
196 FormEngineValidation.validate();
197 }, 1000);
198
199 FormEngine.Validation = FormEngineValidation;
200 });