├── .gitignore
├── tests
├── bootstrap.php
└── ExtensionTest.php
├── LICENSE
├── composer.json
├── phpunit.xml.dist
├── src
└── ConditionalFieldsExtension.php
├── README.md
└── web
└── conditional-fields.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .idea/*
3 | .DS_*
4 | config.yml
5 | composer.lock
6 | vendor/
7 | tests/tmp/
8 |
9 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 |
12 | */
13 | class ExtensionTest extends BoltUnitTest
14 | {
15 |
16 | /**
17 | * Ensure that the ExtensionName extension loads correctly.
18 | */
19 | public function testExtensionBasics()
20 | {
21 |
22 | $app = $this->getApp(false);
23 | $extension = new ConditionalFieldsExtension($app);
24 |
25 | $name = $extension->getName();
26 | $this->assertSame($name, 'ExtensionName');
27 | $this->assertInstanceOf('\Bolt\Extension\ExtensionInterface', $extension);
28 | }
29 |
30 | public function testExtensionComposerJson()
31 | {
32 |
33 | $composerJson = json_decode(file_get_contents(dirname(__DIR__) . '/composer.json'), true);
34 |
35 | // Check that the 'bolt-class' key correctly matches an existing class
36 | $this->assertArrayHasKey('bolt-class', $composerJson['extra']);
37 | $this->assertTrue(class_exists($composerJson['extra']['bolt-class']));
38 |
39 | // Check that the 'bolt-assets' key points to the correct directory
40 | $this->assertArrayHasKey('bolt-assets', $composerJson['extra']);
41 | $this->assertSame('web', $composerJson['extra']['bolt-assets']);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 | tests
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | vendor/bolt/bolt/app/config/config.yml.dist
25 |
26 |
27 | vendor/bolt/bolt/app/config/contenttypes.yml.dist
28 |
29 |
30 | vendor/bolt/bolt/app/config/menu.yml.dist
31 |
32 |
33 | vendor/bolt/bolt/app/config/permissions.yml.dist
34 |
35 |
36 | vendor/bolt/bolt/app/config/routing.yml.dist
37 |
38 |
39 | vendor/bolt/bolt/app/config/taxonomy.yml.dist
40 |
41 |
42 |
43 |
44 |
45 | theme/base-2014
46 |
47 |
48 |
49 |
50 |
51 |
52 | vendor/bolt/bolt/tests/phpunit/unit/resources/db/bolt.db
53 |
54 |
55 |
56 | true
57 |
58 | true
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/src/ConditionalFieldsExtension.php:
--------------------------------------------------------------------------------
1 |
16 | */
17 | class ConditionalFieldsExtension extends SimpleExtension
18 | {
19 |
20 | /**
21 | * Pretty extension name
22 | *
23 | * @return string
24 | */
25 | public function getDisplayName()
26 | {
27 |
28 | return 'Conditional Fields';
29 | }
30 |
31 | /**
32 | * {@inheritdoc}
33 | */
34 | protected function registerAssets()
35 | {
36 |
37 | /**
38 | * @var Application $app
39 | */
40 | $app = $this->getContainer();
41 | $content_types = $app['config']->get('contenttypes');
42 | $taxonomies = $app['config']->get('taxonomy');
43 |
44 | // Template Fields
45 | $theme = $app['config']->get('theme');
46 | $template_fields = '';
47 |
48 | if (!empty($theme['templatefields'])) {
49 | $template_fields = $theme['templatefields'];
50 | }
51 |
52 | // Load the conditional fields javascript file
53 | $asset = new JavaScript();
54 |
55 | $asset->setFileName('conditional-fields.js')
56 | ->setZone(Zone::BACKEND)
57 | ->setLate(true);
58 |
59 | // Content Types
60 | $content_types_json = $this->sanitiseJsonString($content_types);
61 | $content_types_snippet = (new Snippet())->setCallback('')
62 | ->setZone(Zone::BACKEND)
63 | ->setLocation(Target::BEFORE_HEAD_JS);
64 |
65 | // Taxonomies
66 | $taxonomies_json = $this->sanitiseJsonString($taxonomies);
67 | $taxonomies_snippet = (new Snippet())->setCallback('')
68 | ->setZone(Zone::BACKEND)
69 | ->setLocation(Target::BEFORE_HEAD_JS);
70 |
71 | // Template Fields
72 | $template_fields_json = $this->sanitiseJsonString($template_fields);
73 | $template_fields_snippet = (new Snippet())->setCallback('')
74 | ->setZone(Zone::BACKEND)
75 | ->setLocation(Target::BEFORE_HEAD_JS);
76 |
77 | return [
78 | $taxonomies_snippet,
79 | $content_types_snippet,
80 | $template_fields_snippet,
81 | $asset
82 | ];
83 | }
84 |
85 | private function sanitiseJsonString($encode_me)
86 | {
87 |
88 | // Convert array to JSON
89 | $json = str_replace('\\\\', '\\', json_encode($encode_me, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE));
90 |
91 | // Remove string line breaks that are parsed in to actual line breaks by JSON.parse()
92 | $json = str_replace("\\n", "", $json);
93 |
94 | return $json;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Conditional fields
2 | ======================
3 |
4 | This extension allows you to add a `condition:` array to fields and repeater sub-fields and taxonomies.
5 |
6 | If no fields are visible on a group (tab) then the group's tab will be hidden. The tab will be shown again if a field inside it is shown.
7 |
8 | ## Config
9 |
10 | The various config options are displayed below:
11 |
12 | ```yml
13 | field:
14 | label: "abc"
15 | type: text
16 |
17 | # The condition array
18 | condition:
19 | # The trigger field (check the fields id in the HTML)
20 | field: fieldname | taxonomy-taxonomyname
21 | # The operator to test the condition with
22 | operator: = | !=
23 | # If the condition is met, show or hide this field
24 | show: true | false
25 | # The values to match the condition against
26 | value: [ '' ] | [ a,b,c] | { "a":'A', "b":'c' }
27 | ```
28 |
29 | `value: [ '' ]` = field value is empty
30 |
31 |
32 | ## Adding conditions
33 |
34 | In your `contenttypes.yml`, add a `condition:` array and indent accordingly:
35 |
36 |
37 | ### Fields
38 |
39 | To make a field conditional, add a `condition:` array to the field, this works for all field including entire repeaters.
40 |
41 | ```yml
42 | map:
43 | label: "Map"
44 | type: geolocation
45 | condition:
46 | field: template
47 | operator: '='
48 | show: true
49 | value: [ "page-contact.twig" ]
50 | ```
51 |
52 | The above example is based on a template field, this is also possible via `templatefields` in your `theme.yml`, however setting this up as a conditional field allows for more control over grouping.
53 |
54 |
55 | #### Repeaters
56 |
57 | It is also possible to add conditional fields to the fields *within* a repeater, e.g. the below:
58 |
59 | Please note, these fields can __only__ be conditional on fields *within* each repeater group. So for example, you can't currently have a conditional repeater sub field dependant on the page's template.
60 |
61 | ```yml
62 | featured_content:
63 | group: "Featured content"
64 | label: "Featured Items"
65 | type: repeater
66 | fields:
67 | type_of_content:
68 | label: "Type of content"
69 | type: select
70 | values: { 'page': "Page", 'news': "News" }
71 | item_page:
72 | label: "Page"
73 | type: select
74 | values: page/title
75 | condition:
76 | field: type_of_content
77 | operator: '='
78 | show: true
79 | value: [ 'page' ]
80 | item_news:
81 | label: "News"
82 | type: select
83 | values: news/title
84 | condition:
85 | field: type_of_content
86 | operator: '='
87 | show: true
88 | value: [ 'news' ]
89 | size:
90 | label: "Card size"
91 | type: select
92 | values: [ 'small', 'medium', 'large' ]
93 |
94 | ```
95 |
96 | ### Taxonomies
97 |
98 | To add conditional taxonomies you can add a `condition:` to your `taxonomy.yml` file.
99 |
100 | ```yml
101 | tags:
102 | slug: tags
103 | singular_slug: tag
104 | behaves_like: tags
105 | postfix: "Add some freeform tags. Start a new tag by typing a comma."
106 | allow_spaces: true
107 | condition:
108 | news:
109 | field: taxonomy-newstype
110 | operator: '!='
111 | show: true
112 | value: [ press-release ]
113 | contenttype2:
114 | field: taxonomy-taxonomyname
115 | operator: '='
116 | show: false
117 | value: [ abc ]
118 | contenttype3:
119 | field: template
120 | operator: '='
121 | show: true
122 | value: [ '' ]
123 | searchweight: 25
124 | ```
125 |
126 | ## Trigger Fields
127 |
128 | These field types are allowed to be set as the trigger field, this is the field that is going to be "watched". When this field is changed, the conditional fields that depend on it will be checked.
129 | * Select
130 |
131 | *Adding more field types to the `on('change', func...` event should be fairly easy but I haven't had a use case to test with yet.*
132 |
133 |
134 | #### Note:
135 | This extension has been built with a specific project in mind, I have tried to generalise functionality as much as possible but there may still be field types that don't work quite right just yet. Please use with caution, if you notice any bugs please submit an issue or a PR.
136 |
--------------------------------------------------------------------------------
/web/conditional-fields.js:
--------------------------------------------------------------------------------
1 | /* global contentTypes, taxonomies */
2 |
3 | // SBTODO: Multiple conditions
4 | // SBTODO: < and > condition functionality
5 | // SBTODO: Make condition: yaml use the field name instead of the backend html class/id (kind of does this already, but taxonomies and relations get prepended)
6 | // SBTODO: On hide, set value to null / empty so they don't still submit (Should clear: true | false be a setting?)
7 |
8 | (function ($) {
9 | 'use strict';
10 |
11 | // Content Types
12 | var contentType = $('#contenttype').val();
13 | var ctConfig = contentTypes[contentType];
14 |
15 | var allFields = null;
16 | var fieldName = '';
17 |
18 | // Repeaters
19 | var allRepeaterFields = null;
20 | var repeaterToAdd = null;
21 | var regexPattern;
22 |
23 | // Relations
24 | var allRelations = null;
25 | var relationToAdd = null;
26 |
27 | // Taxonomies
28 | var allTaxonomies = taxonomies;
29 | var taxonomyToAdd = null;
30 |
31 | // Templatefields
32 | var $templateSelect = $('.bolt-field-templateselect select');
33 | var templatefieldToAdd = null;
34 |
35 | // Conditional Arrays
36 | var fieldsToWatch = [];
37 | var repeaterFieldsToWatch = [];
38 | var conditionalFields = [];
39 | var repeaterFields = [];
40 |
41 | if (ctConfig !== undefined) {
42 | initContenttypeFields();
43 |
44 | initTemplatefieldFields();
45 |
46 | initRelationFields();
47 |
48 | initTaxonomyFields();
49 |
50 | $(document).on('ready', function () {
51 | watchFieldsForChange();
52 |
53 | var i;
54 | var len = fieldsToWatch.length;
55 | var $fieldToWatch;
56 | var watchName;
57 | var watchVal;
58 |
59 | // Check conditional fields
60 | for (i = 0; i < len; i += 1) {
61 | console.log('# Checking fields that have conditionals on: "#' + fieldsToWatch[i] + '"');
62 |
63 | $fieldToWatch = $('#' + fieldsToWatch[i]);
64 |
65 | if (!$fieldToWatch.length) {
66 | $fieldToWatch = $('[name=' + fieldsToWatch[i] + ']');
67 | }
68 |
69 | watchName = $fieldToWatch.attr('id');
70 | watchVal = $fieldToWatch.val();
71 |
72 | if ($fieldToWatch.is('input[type="checkbox"]')) {
73 | watchName = $fieldToWatch.attr('name');
74 | }
75 |
76 | if ($fieldToWatch.is('input[type="checkbox"]') && !$fieldToWatch.is(':checked')) {
77 | watchVal = '0';
78 | }
79 |
80 | checkConditionalFields(watchName, watchVal);
81 | }
82 |
83 | // Check conditional fields inside repeaters
84 | runRepeaterCheck();
85 |
86 | // On new repeater item, check for conditional fields
87 | $('.repeater-add').on('click', function () {
88 | runRepeaterCheck();
89 | });
90 | });
91 | }
92 |
93 | function checkConditionalFields (id, watchedValue) {
94 | // Check the watched value against fields with conditions
95 | for (var name in conditionalFields) {
96 | if (conditionalFields.hasOwnProperty(name)) {
97 | if (conditionalFields[name]['condition']['field'] !== id) {
98 | continue;
99 | }
100 |
101 | // Find the bolt fieldset container
102 | var $field;
103 |
104 | if (conditionalFields[name].hasOwnProperty('type')) {
105 | switch (conditionalFields[name]['type']) {
106 | case 'repeater':
107 | $field = $('[name="' + name + '[]"]');
108 |
109 | break;
110 | case 'relation':
111 | $field = $('#relation-' + name);
112 |
113 | break;
114 | case 'taxonomy':
115 | $field = $('#taxonomy-' + name);
116 |
117 | break;
118 | case 'filelist':
119 | case 'textarea':
120 | case 'checkbox':
121 | $field = $('[name=' + name + ']');
122 |
123 | break;
124 | case 'image':
125 | case 'file':
126 | $field = $('#field-' + name);
127 |
128 | break;
129 | case 'geolocation':
130 | $field = $('[name*="' + name + '[address]"]');
131 |
132 | break;
133 | case 'video':
134 | $field = $('[name*="' + name + '[url]"]');
135 |
136 | break;
137 | default:
138 | $field = $('#' + name);
139 |
140 | break;
141 | }
142 | }
143 |
144 | if ($field.length === 0) {
145 | console.error('Conditional field could not be hidden: ' + name + '. Type = {' + conditionalFields[name]['type'] + '}');
146 | }
147 |
148 | var $fieldContainer = $field.closest('[data-bolt-fieldset]');
149 |
150 | // Config value whether to show / hide the field on condition matched
151 | var showField = (conditionalFields[name]['condition']['show'] === undefined || conditionalFields[name]['condition']['show']);
152 |
153 | // Check if the value matches
154 | var conditionMatched = false;
155 |
156 | // Check if field's value is null (e.g. this occurs for images)
157 | if (watchedValue === null) {
158 | watchedValue = '';
159 | }
160 |
161 | if (typeof watchedValue === 'object') {
162 | var i = 0;
163 | var len = watchedValue.length;
164 |
165 | for (i = 0; i < len; i += 1) {
166 | if (conditionalFields[name]['condition']['value'].indexOf(watchedValue[i]) > -1) {
167 | conditionMatched = true;
168 |
169 | break;
170 | }
171 | }
172 | } else {
173 | if (conditionalFields[name]['condition']['value'].indexOf(watchedValue) > -1) {
174 | conditionMatched = true;
175 | }
176 | }
177 |
178 | // If the condition is a != condition, invert the conditionMatched result
179 | if (conditionalFields[name]['condition']['operator'] === '!=' && conditionMatched) {
180 | conditionMatched = false;
181 | } else if (conditionalFields[name]['condition']['operator'] === '!=') {
182 | conditionMatched = true;
183 | }
184 |
185 | if ((showField && conditionMatched) || (!showField && !conditionMatched)) {
186 | console.log('--> Show ' + name);
187 |
188 | showFieldset($fieldContainer);
189 | } else {
190 | console.log('--> Hide ' + name);
191 |
192 | hideFieldset($fieldContainer);
193 | }
194 | }
195 | }
196 |
197 | checkTabPanes();
198 | }
199 |
200 | function runRepeaterCheck () {
201 | // Check conditional fields inside repeaters
202 | var $repeaterFieldToWatch;
203 | var i;
204 | var len = repeaterFieldsToWatch.length;
205 |
206 | for (i = 0; i < len; i += 1) {
207 | console.log('# Checking repeater fields that have conditionals on: "name=/' + repeaterFieldsToWatch[i] + '/"');
208 |
209 | $repeaterFieldToWatch = $('select, input, textarea').filter(function () {
210 | if (typeof $(this).attr('name') === 'undefined') {
211 | return false;
212 | }
213 |
214 | return $(this).attr('name').match(new RegExp(repeaterFieldsToWatch[i]))
215 | });
216 |
217 | // If repeater fields have been found, loop through them and check the conditional fields within the repeater-group
218 | if ($repeaterFieldToWatch.length) {
219 | $repeaterFieldToWatch.each(function () {
220 | checkRepeaterFields($(this).attr('id'), $(this).val());
221 | })
222 | }
223 | }
224 | }
225 |
226 | function checkRepeaterFields (id, watchedValue) {
227 | // Check the watched value against fields with conditions
228 | for (var name in repeaterFields) {
229 | if (repeaterFields.hasOwnProperty(name)) {
230 | var repeater = repeaterFields[name]['repeater'];
231 | var watchedFieldRegex = new RegExp(repeater + '\\[\\d+\\]\\[' + repeaterFields[name]['condition']['field'] + '\\]');
232 | var fieldRegex = new RegExp(repeater + '\\[\\d+\\]\\[' + name + '\\]');
233 | var $watched_field = $('#' + id);
234 |
235 | if (!watchedFieldRegex.test($watched_field.attr('name'))) {
236 | continue;
237 | }
238 |
239 | // Find the bolt fieldset container
240 | var $field = $watched_field.closest('.repeater-group').find('select, input, textarea').filter(function () {
241 | if (typeof $(this).attr('name') === 'undefined') {
242 | return false;
243 | }
244 |
245 | return $(this).attr('name').match(fieldRegex);
246 | });
247 |
248 | if ($field.length === 0) {
249 | console.error('Conditional repeater field could not be hidden: ' + name + '. Type = {' + repeaterFields[name]['type'] + '}');
250 | }
251 |
252 | var $fieldContainer = $field.closest('.repeater-field');
253 |
254 | // Config value whether to show / hide the field on condition matched
255 | var showField = (repeaterFields[name]['condition']['show'] === undefined || repeaterFields[name]['condition']['show']);
256 |
257 | // Check if the value matches
258 | var conditionMatched = false;
259 |
260 | if (typeof watchedValue === 'object') {
261 | var i = 0;
262 | var len = watchedValue.length;
263 |
264 | for (i = 0; i < len; i += 1) {
265 | if (repeaterFields[name]['condition']['value'].indexOf(watchedValue[i]) > -1) {
266 | conditionMatched = true;
267 |
268 | break;
269 | }
270 | }
271 | } else {
272 | if (repeaterFields[name]['condition']['value'].indexOf(watchedValue) > -1) {
273 | conditionMatched = true;
274 | }
275 | }
276 |
277 | // If the condition is a != condition, invert the conditionMatched result
278 | if (repeaterFields[name]['condition']['operator'] === '!=' && conditionMatched) {
279 | conditionMatched = false;
280 | } else if (repeaterFields[name]['condition']['operator'] === '!=') {
281 | conditionMatched = true;
282 | }
283 |
284 | if ((showField && conditionMatched) || (!showField && !conditionMatched)) {
285 | console.log('--> Show ' + repeater + ' field: ' + name);
286 |
287 | showFieldset($fieldContainer);
288 | } else {
289 | console.log('--> Hide ' + repeater + ' field: ' + name);
290 |
291 | hideFieldset($fieldContainer);
292 | }
293 | }
294 | }
295 | }
296 |
297 | function initContenttypeFields () {
298 | allFields = ctConfig['fields'];
299 | allRelations = ctConfig['relations'];
300 |
301 | // Check condition config to see what fields need to be checked
302 | for (var name in allFields) {
303 | if (allFields.hasOwnProperty(name) && allFields[name].hasOwnProperty('condition')) {
304 | if (allFields[name]['condition'].hasOwnProperty('field')) {
305 | fieldName = allFields[name]['condition']['field'];
306 |
307 | if (fieldsToWatch.indexOf(fieldName) === -1) {
308 | // Fields to watch the value change of
309 | fieldsToWatch.push(fieldName);
310 | }
311 |
312 | // Add to Conditional fields
313 | conditionalFields[name] = allFields[name];
314 | }
315 | }
316 |
317 | // Check repeater fields and build array of repeaters to watch
318 | if (allFields.hasOwnProperty(name) && allFields[name].hasOwnProperty('type') && allFields[name]['type'] === 'repeater') {
319 | allRepeaterFields = allFields[name]['fields'];
320 |
321 | for (var field in allRepeaterFields) {
322 | if (allRepeaterFields.hasOwnProperty(field) && allRepeaterFields[field].hasOwnProperty('condition')) {
323 | if (allRepeaterFields[field]['condition'].hasOwnProperty('field')) {
324 | fieldName = allRepeaterFields[field]['condition']['field'];
325 |
326 | if (repeaterFieldsToWatch.indexOf(name + '\\[\\d+\\]\\[' + fieldName + '\\]') === -1) {
327 | // Fields to watch the value change of
328 | repeaterFieldsToWatch.push(name + '\\[\\d+\\]\\[' + fieldName + '\\]');
329 | }
330 |
331 | repeaterToAdd = allRepeaterFields[field];
332 |
333 | // Flag this entry as a repeater sub field
334 | repeaterToAdd['repeater'] = name;
335 |
336 | // Add this field to the repeaterFields array
337 | repeaterFields[field] = repeaterToAdd;
338 | }
339 | }
340 | }
341 | }
342 | }
343 | }
344 |
345 | function initRelationFields () {
346 | // Check Relations for condition config to see what relationships need to be checked
347 | for (var relName in allRelations) {
348 | if (allRelations.hasOwnProperty(relName) && allRelations[relName].hasOwnProperty('condition')) {
349 | if (allRelations[relName]['condition'].hasOwnProperty('field')) {
350 | fieldName = allRelations[relName]['condition']['field'];
351 |
352 | if (fieldsToWatch.indexOf(fieldName) === -1) {
353 | // Fields to watch the value change of
354 | fieldsToWatch.push(fieldName);
355 | }
356 |
357 | relationToAdd = allRelations[relName];
358 |
359 | // Force the field type
360 | relationToAdd['type'] = 'relation';
361 |
362 | // Add to Conditional fields
363 | conditionalFields[relName] = relationToAdd;
364 | }
365 | }
366 | }
367 | }
368 |
369 | function initTemplatefieldFields () {
370 | // Check templatefields for condition config to see what relationships need to be checked
371 | if ($templateSelect.length && $templateSelect.val().length) {
372 | var selectedTemplate = $templateSelect.val();
373 |
374 | if (templateFields.hasOwnProperty(selectedTemplate)) {
375 | var fieldsForTemplate = templateFields[selectedTemplate]['fields'];
376 |
377 | // Check templatefields for condition config to see what templatefields need to be checked
378 | for (var templatefieldName in fieldsForTemplate) {
379 | if (fieldsForTemplate.hasOwnProperty(templatefieldName) && fieldsForTemplate[templatefieldName].hasOwnProperty('condition')) {
380 | templatefieldToAdd = fieldsForTemplate[templatefieldName];
381 |
382 | fieldName = fieldsForTemplate[templatefieldName]['condition']['field'];
383 |
384 | if (fieldsToWatch.indexOf(fieldName) === -1) {
385 | // Fields to watch the value change of
386 | fieldsToWatch.push(fieldName);
387 | }
388 |
389 | // Add to Conditional fields
390 | conditionalFields['templatefields-' + templatefieldName] = fieldsForTemplate[templatefieldName];
391 | }
392 | }
393 | }
394 | }
395 | }
396 |
397 | function initTaxonomyFields () {
398 | // Check taxonomies for condition config to see what taxonomies need to be checked
399 | for (var taxName in allTaxonomies) {
400 | if (allTaxonomies.hasOwnProperty(taxName) && allTaxonomies[taxName].hasOwnProperty('condition')) {
401 | taxonomyToAdd = allTaxonomies[taxName];
402 |
403 | if (taxonomyToAdd['condition'].hasOwnProperty(contentType)) {
404 | fieldName = allTaxonomies[taxName]['condition'][contentType]['field'];
405 |
406 | if (fieldsToWatch.indexOf(fieldName) === -1) {
407 | // Fields to watch the value change of
408 | fieldsToWatch.push(fieldName);
409 | }
410 |
411 | // Force the field type
412 | taxonomyToAdd['type'] = 'taxonomy';
413 |
414 | // Only use the condition for the relevant content type
415 | taxonomyToAdd['condition'] = taxonomyToAdd['condition'][contentType];
416 |
417 | // Add to Conditional fields
418 | conditionalFields[taxName] = taxonomyToAdd;
419 | }
420 | }
421 | }
422 | }
423 |
424 | function showFieldset ($fieldContainer) {
425 |
426 | var $wasRequiredFields = $fieldContainer.find('.was-required');
427 |
428 | if ($wasRequiredFields.length) {
429 | $wasRequiredFields.each(function () {
430 | $(this).attr('required', 'required').removeClass('was-required');
431 | });
432 | }
433 |
434 | $fieldContainer.show();
435 | }
436 |
437 | function hideFieldset ($fieldContainer) {
438 |
439 | var $requiredFields = $fieldContainer.find('[required]');
440 |
441 | if ($requiredFields.length) {
442 | $requiredFields.each(function () {
443 | $(this).removeAttr('required').addClass('was-required');
444 | });
445 | }
446 |
447 | $fieldContainer.hide();
448 | }
449 |
450 | function checkTabPanes () {
451 | var $tabPanes = $('.tab-pane');
452 | var $fields = null;
453 |
454 | $tabPanes.each(function () {
455 | // Find bolt fields
456 | $fields = $(this).find('[data-bolt-fieldset]');
457 |
458 | // Check which of these are display none (can't use hidden because inactive tabs return as hidden)
459 | $fields = $fields.filter(function () {
460 | return $(this).data('bolt-fieldset').length && $(this).css("display") !== "none"
461 | });
462 |
463 | // Show / Hide the tab if it has visible contents
464 | if ($fields.length > 0) {
465 | $('#tabindicator-' + $(this).attr('id')).show();
466 | } else {
467 | $('#tabindicator-' + $(this).attr('id')).hide();
468 | }
469 | });
470 | }
471 |
472 | function watchFieldsForChange () {
473 | // Check for select2 changes
474 | $(document).on('change', 'select,input', function () {
475 | var id = $(this).attr('id');
476 | var name = $(this).attr('name');
477 | var watchedValue = $(this).val();
478 |
479 | if (!id) {
480 | id = name;
481 | }
482 |
483 | // Check if the changed select is inside a repeater
484 | if ($(this).parents('.repeater-field').length) {
485 | checkRepeaterFields(id, watchedValue);
486 | }
487 |
488 | // Check the changed field is one of the fieldsToWatch
489 | if (fieldsToWatch.indexOf(id) > -1) {
490 | checkConditionalFields(id, watchedValue);
491 | }
492 | }).on('click', 'input[type="checkbox"], button', function () {
493 | var $field = $(this);
494 |
495 | if ($field.is('button')) {
496 | $field = $field.prev();
497 | }
498 |
499 | var id = $field.attr('name');
500 | var name = id;
501 | var watchedValue = $field.val();
502 |
503 | if (!$field.is(':checked')) {
504 | watchedValue = '0';
505 | }
506 |
507 | // Check if the changed select is inside a repeater
508 | if ($field.parents('.repeater-field').length) {
509 | checkRepeaterFields(id, watchedValue);
510 | }
511 |
512 | // Check the changed field is one of the fieldsToWatch
513 | if (fieldsToWatch.indexOf(id) > -1) {
514 | checkConditionalFields(id, watchedValue);
515 | }
516 | });
517 | }
518 | })(jQuery);
519 |
--------------------------------------------------------------------------------