Commit | Line | Data |
---|---|---|
53f2643c | 1 | // https://civicrm.org/licensing |
53f2643c | 2 | jQuery(function($) { |
53f2643c | 3 | $('body') |
3cb1ef9e | 4 | // Enable administrators to edit option lists in a dialog |
53f2643c | 5 | .on('click', 'a.crm-option-edit-link', CRM.popup) |
4b472ff2 CW |
6 | .on('crmPopupFormSuccess', 'a.crm-option-edit-link', function() { |
7 | $(this).trigger('crmOptionsEdited'); | |
3ef93345 MD |
8 | var optionEditPath = $(this).data('option-edit-path'); |
9 | var $selects = $('select[data-option-edit-path="' + optionEditPath + '"]'); | |
10 | var $inputs = $('input[data-option-edit-path="' + optionEditPath + '"]'); | |
11 | var $radios = $inputs.filter('[type=radio]'); | |
12 | var $checkboxes = $inputs.filter('[type=checkbox]'); | |
13 | ||
14 | if ($selects.length > 0) { | |
15 | rebuildOptions($selects, CRM.utils.setOptions); | |
53f2643c | 16 | } |
3ef93345 MD |
17 | else if ($radios.length > 0) { |
18 | rebuildOptions($radios, rebuildRadioOptions); | |
19 | } | |
20 | else if ($checkboxes.length > 0) { | |
21 | rebuildOptions($checkboxes, rebuildCheckboxOptions); | |
22 | } | |
23 | }); | |
24 | ||
25 | /** | |
26 | * Fetches options using metadata from the existing ones and calls the | |
27 | * function to rebuild them | |
28 | * @param $existing {object} The existing options, used as metadata store | |
29 | * @param rebuilder {function} Function to be called to rebuild the options | |
30 | */ | |
31 | function rebuildOptions($existing, rebuilder) { | |
32 | if ($existing.data('api-entity') && $existing.data('api-field')) { | |
b3ee84c9 | 33 | var params = { |
3ef93345 MD |
34 | sequential: 1, |
35 | field: $existing.data('api-field') | |
b3ee84c9 MD |
36 | }; |
37 | $.extend(params, $existing.data('option-edit-context')); | |
38 | ||
39 | CRM.api3($existing.data('api-entity'), 'getoptions', params) | |
3ef93345 MD |
40 | .done(function(data) { |
41 | rebuilder($existing, data.values); | |
42 | }); | |
43 | } | |
44 | } | |
45 | ||
46 | /** | |
47 | * Rebuild checkbox input options, overwriting the existing options | |
48 | * | |
49 | * @param $existing {object} the existing checkbox options | |
50 | * @param newOptions {array} in format returned by api.getoptions | |
51 | */ | |
52 | function rebuildCheckboxOptions($existing, newOptions) { | |
53 | var $parent = $existing.first().parent(), | |
54 | $firstExisting = $existing.first(), | |
55 | optionName = $firstExisting.attr('name'), | |
56 | optionAttributes = | |
57 | 'data-option-edit-path =' + $firstExisting.data('option-edit-path') + | |
58 | ' data-api-entity = ' + $firstExisting.data('api-entity') + | |
59 | ' data-api-field = ' + $firstExisting.data('api-field'); | |
60 | ||
61 | var prefix = optionName.substr(0, optionName.lastIndexOf("[")); | |
62 | ||
63 | var checkedBoxes = []; | |
64 | $parent.find('input:checked').each(function() { | |
65 | checkedBoxes.push($(this).attr('id')); | |
66 | }); | |
67 | ||
68 | // remove existing checkboxes | |
69 | $parent.find('input[type=checkbox]').remove(); | |
70 | ||
71 | // find existing labels for the checkboxes | |
72 | var $checkboxLabels = $parent.find('label').filter(function() { | |
73 | var forAttr = $(this).attr('for') || ''; | |
74 | ||
75 | return forAttr.indexOf(prefix) !== -1; | |
76 | }); | |
77 | ||
78 | // find what is used to separate the elements; spaces or linebreaks | |
79 | var $elementAfterLabel = $checkboxLabels.first().next(); | |
80 | var separator = $elementAfterLabel.is('br') ? '<br/>' : ' '; | |
81 | ||
82 | // remove existing labels | |
83 | $checkboxLabels.remove(); | |
84 | ||
85 | // remove linebreaks in container | |
86 | $parent.find('br').remove(); | |
87 | ||
88 | // remove separator whitespace in container | |
89 | $parent.html(function (i, html) { | |
90 | return html.replace(/ /g, ''); | |
91 | }); | |
92 | ||
93 | var renderedOptions = ''; | |
94 | // replace missing br at start of element | |
95 | if (separator === '<br/>') { | |
96 | $parent.prepend(separator); | |
97 | renderedOptions = separator; | |
98 | } | |
99 | ||
100 | newOptions.forEach(function(option) { | |
101 | var optionId = prefix + '_' + option.key, | |
102 | checked = ''; | |
103 | ||
104 | if ($.inArray(optionId, checkedBoxes) !== -1) { | |
105 | checked = ' checked="checked"'; | |
106 | } | |
107 | ||
108 | renderedOptions += '<input type="checkbox" ' + | |
109 | ' value="1"' + | |
110 | ' id="' + optionId + '"' + | |
111 | ' name="' + prefix + '[' + option.key +']' + '"' + | |
112 | checked + | |
113 | ' class="crm-form-checkbox"' + | |
114 | optionAttributes + | |
115 | '><label for="' + optionId + '">' + option.value + '</label>' + | |
116 | separator; | |
117 | }); | |
118 | ||
119 | // remove final separator | |
120 | renderedOptions = renderedOptions.substring(0, renderedOptions.lastIndexOf(separator)); | |
121 | ||
122 | var $editLink = $parent.find('.crm-option-edit-link'); | |
123 | ||
124 | // try to insert before the edit link to maintain structure | |
125 | if ($editLink.length > 0) { | |
126 | $(renderedOptions).insertBefore($editLink); | |
127 | } | |
128 | else { | |
129 | $parent.append(renderedOptions); | |
130 | } | |
131 | } | |
132 | ||
133 | /** | |
134 | * Rebuild radio input options, overwriting the existing options | |
135 | * | |
136 | * @param $existing {object} the existing input options | |
137 | * @param newOptions {array} in format returned by api.getoptions | |
138 | */ | |
139 | function rebuildRadioOptions($existing, newOptions) { | |
140 | var $parent = $existing.first().parent(), | |
141 | $firstExisting = $existing.first(), | |
142 | optionName = $firstExisting.attr('name'), | |
143 | renderedOptions = '', | |
144 | checkedValue = parseInt($parent.find('input:checked').attr('value')), | |
145 | optionAttributes = | |
146 | 'data-option-edit-path =' + $firstExisting.attr('data-option-edit-path') + | |
147 | ' data-api-entity = ' + $firstExisting.attr('data-api-entity') + | |
148 | ' data-api-field = ' + $firstExisting.attr('data-api-field'); | |
149 | ||
150 | // remove existing radio inputs and labels | |
151 | $parent.find('input, label').remove(); | |
152 | ||
153 | newOptions.forEach(function(option) { | |
154 | var optionId = 'CIVICRM_QFID_' + option.key + '_' + optionName, | |
155 | checked = (option.key === checkedValue) ? ' checked="checked"' : ''; | |
156 | ||
157 | renderedOptions += '<input type="radio" ' + | |
158 | ' value=' + option.key + | |
159 | ' id="' + optionId +'"' + | |
160 | ' name="' + optionName + '"' + | |
161 | checked + | |
162 | ' class="crm-form-radio"' + | |
163 | optionAttributes + | |
164 | '><label for="' + optionId + '">' + option.value + '</label> '; | |
4b472ff2 | 165 | }); |
3ef93345 MD |
166 | |
167 | $parent.prepend(renderedOptions); | |
168 | } | |
53f2643c | 169 | }); |