PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 3.19.2
GiveWP – Donation Plugin and Fundraising Platform v3.19.2
4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / src / Form / LegacyConsumer / resources / js / conditional-fields.js
give / src / Form / LegacyConsumer / resources / js Last commit date
conditional-fields.js 3 years ago
conditional-fields.js
222 lines
1 document.addEventListener('readystatechange', (event) => {
2 if (event.target.readyState !== 'complete') {
3 return null;
4 }
5
6 const state = {};
7
8 /**
9 * Get list of watched fields.
10 * @since 2.15.0
11 *
12 * @return object
13 */
14 function getWatchedElementNames(donationForm) {
15 const fields = {};
16
17 donationForm.querySelectorAll('[data-field-visibility-conditions]').forEach(function (fieldContainer) {
18 const visibilityConditions = JSON.parse(fieldContainer.getAttribute('data-field-visibility-conditions'));
19 const visibilityCondition = visibilityConditions[0]; // Currently we support only one visibility condition.
20 let fieldContainerSelector = `[data-field-name="${fieldContainer.getAttribute('data-field-name')}"]`;
21 let {field} = visibilityCondition;
22
23 // Get field. It will tell use real name of field.
24 field = document.querySelector(`[name="${field}"], [name="${field}[]"]`);
25
26 if (field) {
27 fields[field.name] = {
28 ...fields[field.name],
29 [fieldContainerSelector]: visibilityConditions,
30 };
31 }
32 });
33
34 return fields;
35 }
36
37 /**
38 * @since 2.15.0
39 *
40 * @param operator
41 * @param firstData
42 * @param secondData
43 *
44 * @return boolean
45 */
46 function compareWithOperator(operator, firstData, secondData) {
47 return {
48 '=': firstData === secondData,
49 '!=': firstData !== secondData,
50 '>': firstData > secondData,
51 '>=': firstData >= secondData,
52 '<': firstData < secondData,
53 '<=': firstData <= secondData,
54 }[operator];
55 }
56
57 /**
58 * Handle fields visibility.
59 * @since 2.15.0
60 */
61 function handleVisibility(donationForm, watchedFieldName, visibilityConditionsForWatchedField) {
62 for (const [fieldContainerSelector, visibilityConditions] of Object.entries(
63 visibilityConditionsForWatchedField
64 )) {
65 const fieldWrapper = donationForm.querySelector(fieldContainerSelector);
66 const fieldName = fieldWrapper.getAttribute('data-field-name');
67 const visibilityCondition = visibilityConditions[0]; // Currently we support only one visibility condition.
68 let visible = false;
69 const {comparisonOperator} = visibilityCondition;
70 let {value} = visibilityCondition;
71
72 const inputs = donationForm.querySelectorAll(`[name="${watchedFieldName}"]`);
73 let hasFieldController = !!inputs.length;
74
75 if (hasFieldController) {
76 inputs.forEach((input) => {
77 const fieldType = input.getAttribute('type');
78 let inputValue = input.value;
79
80 // Make an exception for the amount field and parse the value
81 if (input.name === 'give-amount') {
82 inputValue = Give.fn.unFormatCurrency(
83 input.value,
84 Give.form.fn.getInfo('decimal_separator', donationForm)
85 );
86
87 value = Math.abs(parseFloat(value));
88 }
89
90 const comparisonResult = compareWithOperator(comparisonOperator, inputValue, value);
91
92 if (fieldType === 'checkbox') {
93 if (
94 (comparisonResult && input.checked && comparisonOperator === '=') ||
95 (!input.checked && comparisonOperator === '!=')
96 ) {
97 visible = true;
98 }
99 } else if (fieldType === 'radio') {
100 if (input.checked && comparisonResult) {
101 visible = true;
102 }
103 } else if (comparisonResult) {
104 visible = true;
105 }
106 });
107
108 // Show or Hide field wrapper.
109 if (visible) {
110 const field = fieldWrapper.querySelector(`[name="${fieldName}"][data-required]`);
111 fieldWrapper.classList.remove('give-hidden');
112
113 // Make hidden flagged required field required.
114 if (field) {
115 field.setAttribute('required', '');
116 field.removeAttribute('data-required');
117 }
118 } else {
119 const field = fieldWrapper.querySelector(`[name="${fieldName}"][required]`);
120 fieldWrapper.classList.add('give-hidden');
121
122 // Make hidden required field non-required.
123 if (field) {
124 field.removeAttribute('required');
125 field.setAttribute('data-required', '1');
126 }
127 }
128 }
129 }
130 }
131
132 /**
133 * Setup state for condition visibility settings.
134 * state contains list of watched elements per donation form.
135 *
136 * @since 2.15.0
137 */
138 function addVisibilityConditionsToStateForDonationForm(donationForm) {
139 const uniqueDonationFormId = donationForm.getAttribute('data-id');
140 const watchedFields = getWatchedElementNames(donationForm);
141
142 // Add donation form to state only if visibility conditions exiting for at least form field.
143 if (uniqueDonationFormId && Object.keys(watchedFields).length) {
144 state[uniqueDonationFormId] = watchedFields;
145 }
146 }
147
148 /**
149 * @since 2.15.0
150 * @param donationForm
151 */
152 function applyVisibilityConditionsToDonationForm(donationForm) {
153 const uniqueDonationFormId = donationForm.getAttribute('data-id');
154
155 if (uniqueDonationFormId && uniqueDonationFormId in state) {
156 const formState = state[uniqueDonationFormId];
157
158 for (const [watchedFieldName, visibilityConditions] of Object.entries(formState)) {
159 handleVisibility(
160 document.querySelector(`form[data-id="${uniqueDonationFormId}"]`).closest('.give-form'),
161 watchedFieldName,
162 visibilityConditions
163 );
164 }
165 }
166 }
167
168 /**
169 * @since 2.15.0
170 */
171 function addChangeEventToWatchedElementsForDonationForm(donationFormUniqueId) {
172 const donationForm = document
173 .querySelector(`form.give-form[data-id="${donationFormUniqueId}"`)
174 .closest('form.give-form');
175
176 if (!donationForm || !state.hasOwnProperty(donationFormUniqueId)) {
177 return;
178 }
179
180 for (const [watchedElementName, VisibilityConditions] of Object.entries(state[donationFormUniqueId])) {
181 document.querySelectorAll(`[name = "${watchedElementName}"]`).forEach((field) => {
182 jQuery(field).on(
183 'input change blur',
184 handleVisibility.bind(null, donationForm, watchedElementName, VisibilityConditions)
185 );
186 });
187 }
188 }
189
190 /**
191 * @since 2.15.0
192 */
193 function bootVisibilityConditionsFormAllDonationForm() {
194 document.querySelectorAll('form.give-form').forEach(addVisibilityConditionsToStateForDonationForm);
195
196 // Apply visibility conditions.
197 // Add change event to watched field.
198 for (const [donationFormUniqueId, donationFormState] of Object.entries(state)) {
199 for (const [watchedFieldName, visibilityConditions] of Object.entries(donationFormState)) {
200 handleVisibility(
201 document.querySelector(`form[data-id="${donationFormUniqueId}"]`).closest('.give-form'),
202 watchedFieldName,
203 visibilityConditions
204 );
205 }
206
207 addChangeEventToWatchedElementsForDonationForm(donationFormUniqueId);
208 }
209 }
210
211 bootVisibilityConditionsFormAllDonationForm();
212
213 // Apply visibility conditions to donation form when donor switch gateway.
214 document.addEventListener('give_gateway_loaded', (event) => {
215 const donationForm = document.getElementById(event.detail.formIdAttribute);
216 const uniqueDonationFormId = donationForm.getAttribute('data-id');
217 addVisibilityConditionsToStateForDonationForm(donationForm);
218 applyVisibilityConditionsToDonationForm(donationForm);
219 addChangeEventToWatchedElementsForDonationForm(uniqueDonationFormId);
220 });
221 });
222