PluginProbe ʕ •ᴥ•ʔ
Auto Post Cleaner / trunk
Auto Post Cleaner vtrunk
3.12.0 3.13.1 3.2.4 3.2.5 3.3.0 3.3.10 3.3.11 3.3.8 3.4.2 3.5.3 3.6.0 3.7.0 3.7.1 3.7.2 3.7.3 3.7.5 3.7.6 3.8.0 3.9.0 3.9.4 3.9.6 3.9.7 trunk 3.0.0 3.1.0 3.10.1 3.10.2 3.11.4
delete-old-posts-programmatically / assets / js / delp_multi_select.js
delete-old-posts-programmatically / assets / js Last commit date
alpine.min.js 5 years ago deloldp_alpine.js 7 months ago delp_multi_select.js 7 months ago delp_script.js 1 month ago
delp_multi_select.js
260 lines
1 /*
2 * Created by David Adams
3 * https://codeshack.io/multi-select-dropdown-html-javascript/
4 *
5 * Released under the MIT license
6 */
7 class MultiSelect {
8
9 constructor(element, options = {}) {
10 let defaults = {
11 placeholder: 'Select item(s)',
12 max: null,
13 search: true,
14 selectAll: true,
15 listAll: true,
16 closeListOnItemSelect: false,
17 name: '',
18 width: '',
19 height: '',
20 dropdownWidth: '',
21 dropdownHeight: '',
22 data: [],
23 onChange: function() {},
24 onSelect: function() {},
25 onUnselect: function() {}
26 };
27 this.options = Object.assign(defaults, options);
28 this.selectElement = typeof element === 'string' ? document.querySelector(element) : element;
29 for(const prop in this.selectElement.dataset) {
30 if (this.options[prop] !== undefined) {
31 this.options[prop] = this.selectElement.dataset[prop];
32 }
33 }
34 this.name = this.selectElement.getAttribute('name') ? this.selectElement.getAttribute('name') : 'multi-select-' + Math.floor(Math.random() * 1000000);
35 if (!this.options.data.length) {
36 let options = this.selectElement.querySelectorAll('option');
37 for (let i = 0; i < options.length; i++) {
38 this.options.data.push({
39 value: options[i].value,
40 text: options[i].innerHTML,
41 selected: options[i].selected,
42 html: options[i].getAttribute('data-html')
43 });
44 }
45 }
46 this.element = this._template();
47 this.selectElement.replaceWith(this.element);
48 this._updateSelected();
49 this._eventHandlers();
50 }
51
52 _template() {
53 let optionsHTML = '';
54 for (let i = 0; i < this.data.length; i++) {
55 optionsHTML += `
56 <div class="multi-select-option${this.selectedValues.includes(this.data[i].value) ? ' multi-select-selected' : ''}" data-value="${this.data[i].value}">
57 <span class="multi-select-option-radio"></span>
58 <span class="multi-select-option-text">${this.data[i].html ? this.data[i].html : this.data[i].text}</span>
59 </div>
60 `;
61 }
62 let selectAllHTML = '';
63 if (this.options.selectAll === true || this.options.selectAll === 'true') {
64 selectAllHTML = `<div class="multi-select-all">
65 <span class="multi-select-option-radio"></span>
66 <span class="multi-select-option-text">Select all</span>
67 </div>`;
68 }
69 let template = `
70 <div class="multi-select ${this.name}"${this.selectElement.id ? ' id="' + this.selectElement.id + '"' : ''} style="${this.width ? 'width:' + this.width + ';' : ''}${this.height ? 'height:' + this.height + ';' : ''}">
71 ${this.selectedValues.map(value => `<input type="hidden" name="${this.name}[]" value="${value}">`).join('')}
72 <div class="multi-select-header" style="${this.width ? 'width:' + this.width + ';' : ''}${this.height ? 'height:' + this.height + ';' : ''}">
73 <span class="multi-select-header-max">${this.options.max ? this.selectedValues.length + '/' + this.options.max : ''}</span>
74 <span class="multi-select-header-placeholder">${this.placeholder}</span>
75 </div>
76 <div class="multi-select-options" style="${this.options.dropdownWidth ? 'width:' + this.options.dropdownWidth + ';' : ''}${this.options.dropdownHeight ? 'height:' + this.options.dropdownHeight + ';' : ''}">
77 ${this.options.search === true || this.options.search === 'true' ? '<input type="text" class="multi-select-search" placeholder="Search...">' : ''}
78 ${selectAllHTML}
79 ${optionsHTML}
80 </div>
81 </div>
82 `;
83 let element = document.createElement('div');
84 element.innerHTML = template;
85 return element;
86 }
87
88 _eventHandlers() {
89 let headerElement = this.element.querySelector('.multi-select-header');
90 this.element.querySelectorAll('.multi-select-option').forEach(option => {
91 option.onclick = () => {
92 let selected = true;
93 if (!option.classList.contains('multi-select-selected')) {
94 if (this.options.max && this.selectedValues.length >= this.options.max) {
95 return;
96 }
97 option.classList.add('multi-select-selected');
98 if (this.options.listAll === true || this.options.listAll === 'true') {
99 if (this.element.querySelector('.multi-select-header-option')) {
100 let opt = Array.from(this.element.querySelectorAll('.multi-select-header-option')).pop();
101 opt.insertAdjacentHTML('afterend', `<span class="multi-select-header-option" data-value="${option.dataset.value}">${option.querySelector('.multi-select-option-text').innerHTML}</span>`);
102 } else {
103 headerElement.insertAdjacentHTML('afterbegin', `<span class="multi-select-header-option" data-value="${option.dataset.value}">${option.querySelector('.multi-select-option-text').innerHTML}</span>`);
104 }
105 }
106 this.element.querySelector('.multi-select').insertAdjacentHTML('afterbegin', `<input type="hidden" name="${this.name}[]" value="${option.dataset.value}">`);
107 this.data.filter(data => data.value == option.dataset.value)[0].selected = true;
108 } else {
109 option.classList.remove('multi-select-selected');
110 this.element.querySelectorAll('.multi-select-header-option').forEach(headerOption => headerOption.dataset.value == option.dataset.value ? headerOption.remove() : '');
111 this.element.querySelector(`input[value="${option.dataset.value}"]`).remove();
112 this.data.filter(data => data.value == option.dataset.value)[0].selected = false;
113 selected = false;
114 }
115 if (this.options.listAll === false || this.options.listAll === 'false') {
116 if (this.element.querySelector('.multi-select-header-option')) {
117 this.element.querySelector('.multi-select-header-option').remove();
118 }
119 headerElement.insertAdjacentHTML('afterbegin', `<span class="multi-select-header-option">${this.selectedValues.length} selected</span>`);
120 }
121 if (!this.element.querySelector('.multi-select-header-option')) {
122 headerElement.insertAdjacentHTML('afterbegin', `<span class="multi-select-header-placeholder">${this.placeholder}</span>`);
123 } else if (this.element.querySelector('.multi-select-header-placeholder')) {
124 this.element.querySelector('.multi-select-header-placeholder').remove();
125 }
126 if (this.options.max) {
127 this.element.querySelector('.multi-select-header-max').innerHTML = this.selectedValues.length + '/' + this.options.max;
128 }
129 if (this.options.search === true || this.options.search === 'true') {
130 this.element.querySelector('.multi-select-search').value = '';
131 }
132 this.element.querySelectorAll('.multi-select-option').forEach(option => option.style.display = 'flex');
133 if (this.options.closeListOnItemSelect === true || this.options.closeListOnItemSelect === 'true') {
134 headerElement.classList.remove('multi-select-header-active');
135 }
136 this.options.onChange(option.dataset.value, option.querySelector('.multi-select-option-text').innerHTML, option);
137 if (selected) {
138 this.options.onSelect(option.dataset.value, option.querySelector('.multi-select-option-text').innerHTML, option);
139 } else {
140 this.options.onUnselect(option.dataset.value, option.querySelector('.multi-select-option-text').innerHTML, option);
141 }
142 };
143 });
144 headerElement.onclick = () => headerElement.classList.toggle('multi-select-header-active');
145 if (this.options.search === true || this.options.search === 'true') {
146 let search = this.element.querySelector('.multi-select-search');
147 search.oninput = () => {
148 this.element.querySelectorAll('.multi-select-option').forEach(option => {
149 option.style.display = option.querySelector('.multi-select-option-text').innerHTML.toLowerCase().indexOf(search.value.toLowerCase()) > -1 ? 'flex' : 'none';
150 });
151 };
152 }
153 if (this.options.selectAll === true || this.options.selectAll === 'true') {
154 let selectAllButton = this.element.querySelector('.multi-select-all');
155 selectAllButton.onclick = () => {
156 let allSelected = selectAllButton.classList.contains('multi-select-selected');
157 this.element.querySelectorAll('.multi-select-option').forEach(option => {
158 let dataItem = this.data.find(data => data.value == option.dataset.value);
159 if (dataItem && ((allSelected && dataItem.selected) || (!allSelected && !dataItem.selected))) {
160 option.click();
161 }
162 });
163 selectAllButton.classList.toggle('multi-select-selected');
164 };
165 }
166 if (this.selectElement.id && document.querySelector('label[for="' + this.selectElement.id + '"]')) {
167 document.querySelector('label[for="' + this.selectElement.id + '"]').onclick = () => {
168 headerElement.classList.toggle('multi-select-header-active');
169 };
170 }
171 document.addEventListener('click', event => {
172 if (!event.target.closest('.' + this.name) && !event.target.closest('label[for="' + this.selectElement.id + '"]')) {
173 headerElement.classList.remove('multi-select-header-active');
174 }
175 });
176 }
177
178 _updateSelected() {
179 if (this.options.listAll === true || this.options.listAll === 'true') {
180 this.element.querySelectorAll('.multi-select-option').forEach(option => {
181 if (option.classList.contains('multi-select-selected')) {
182 this.element.querySelector('.multi-select-header').insertAdjacentHTML('afterbegin', `<span class="multi-select-header-option" data-value="${option.dataset.value}">${option.querySelector('.multi-select-option-text').innerHTML}</span>`);
183 }
184 });
185 } else {
186 if (this.selectedValues.length > 0) {
187 this.element.querySelector('.multi-select-header').insertAdjacentHTML('afterbegin', `<span class="multi-select-header-option">${this.selectedValues.length} selected</span>`);
188 }
189 }
190 if (this.element.querySelector('.multi-select-header-option')) {
191 this.element.querySelector('.multi-select-header-placeholder').remove();
192 }
193 }
194
195 get selectedValues() {
196 return this.data.filter(data => data.selected).map(data => data.value);
197 }
198
199 get selectedItems() {
200 return this.data.filter(data => data.selected);
201 }
202
203 set data(value) {
204 this.options.data = value;
205 }
206
207 get data() {
208 return this.options.data;
209 }
210
211 set selectElement(value) {
212 this.options.selectElement = value;
213 }
214
215 get selectElement() {
216 return this.options.selectElement;
217 }
218
219 set element(value) {
220 this.options.element = value;
221 }
222
223 get element() {
224 return this.options.element;
225 }
226
227 set placeholder(value) {
228 this.options.placeholder = value;
229 }
230
231 get placeholder() {
232 return this.options.placeholder;
233 }
234
235 set name(value) {
236 this.options.name = value;
237 }
238
239 get name() {
240 return this.options.name;
241 }
242
243 set width(value) {
244 this.options.width = value;
245 }
246
247 get width() {
248 return this.options.width;
249 }
250
251 set height(value) {
252 this.options.height = value;
253 }
254
255 get height() {
256 return this.options.height;
257 }
258
259 }
260 document.querySelectorAll('[data-multi-select]').forEach(select => new MultiSelect(select));