[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 /** 2 * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> 3 * @license GNU General Public License version 2 or later; see LICENSE.txt 4 */ 5 // The container where the draggable will be enabled 6 let url; 7 let direction; 8 let isNested; 9 let dragElementIndex; 10 let dropElementIndex; 11 let container = document.querySelector('.js-draggable'); 12 let form; 13 let formData; 14 15 if (container) { 16 /** The script expects a form with a class js-form 17 * A table with the tbody with a class js-draggable 18 * with a data-url with the ajax request end point and 19 * with a data-direction for asc/desc 20 */ 21 url = container.dataset.url; 22 direction = container.dataset.direction; 23 isNested = container.dataset.nested; 24 } else if (Joomla.getOptions('draggable-list')) { 25 const options = Joomla.getOptions('draggable-list'); 26 container = document.querySelector(options.id); 27 /** 28 * This is here to make the transition to new forms easier. 29 */ 30 31 if (!container.classList.contains('js-draggable')) { 32 container.classList.add('js-draggable'); 33 } 34 35 ({ 36 url 37 } = options); 38 ({ 39 direction 40 } = options); 41 isNested = options.nested; 42 } 43 44 if (container) { 45 // Get the form 46 form = container.closest('form'); // Get the form data 47 48 formData = new FormData(form); 49 formData.delete('task'); 50 formData.delete('order[]'); // IOS 10 BUG 51 52 document.addEventListener('touchstart', () => {}, false); 53 54 const getOrderData = (rows, inputRows, dragIndex, dropIndex) => { 55 let i; 56 const result = []; // Element is moved down 57 58 if (dragIndex < dropIndex) { 59 rows[dropIndex].setAttribute('value', rows[dropIndex - 1].value); 60 61 for (i = dragIndex; i < dropIndex; i += 1) { 62 if (direction === 'asc') { 63 rows[i].setAttribute('value', parseInt(rows[i].value, 10) - 1); 64 } else { 65 rows[i].setAttribute('value', parseInt(rows[i].value, 10) + 1); 66 } 67 } 68 } else { 69 // Element is moved up 70 rows[dropIndex].setAttribute('value', rows[dropIndex + 1].value); 71 rows[dropIndex].value = rows[dropIndex + 1].value; 72 73 for (i = dropIndex + 1; i <= dragIndex; i += 1) { 74 if (direction === 'asc') { 75 rows[i].value = parseInt(rows[i].value, 10) + 1; 76 } else { 77 rows[i].value = parseInt(rows[i].value, 10) - 1; 78 } 79 } 80 } 81 82 for (i = 0; i < rows.length - 1; i += 1) { 83 result.push(`order[]=$encodeURIComponent(rows[i].value)}`); 84 result.push(`cid[]=$encodeURIComponent(inputRows[i].value)}`); 85 } 86 87 return result; 88 }; 89 90 const rearrangeChildren = $parent => { 91 if (!$parent.dataset.itemId) { 92 return; 93 } 94 95 const parentId = $parent.dataset.itemId; // Get children list. Each child row should have 96 // an attribute data-parents=" 1 2 3" where the number is id of parent 97 98 const $children = container.querySelectorAll(`tr[data-parents~="$parentId}"]`); 99 100 if ($children.length) { 101 $parent.after(...$children); 102 } 103 }; 104 105 const saveTheOrder = el => { 106 let orderSelector; 107 let inputSelector; 108 let rowSelector; 109 const groupId = el.dataset.draggableGroup; 110 111 if (groupId) { 112 rowSelector = `tr[data-draggable-group="$groupId}"]`; 113 orderSelector = `[data-draggable-group="$groupId}"] [name="order[]"]`; 114 inputSelector = `[data-draggable-group="$groupId}"] [name="cid[]"]`; 115 } else { 116 rowSelector = 'tr'; 117 orderSelector = '[name="order[]"]'; 118 inputSelector = '[name="cid[]"]'; 119 } 120 121 const rowElements = [].slice.call(container.querySelectorAll(rowSelector)); 122 const rows = [].slice.call(container.querySelectorAll(orderSelector)); 123 const inputRows = [].slice.call(container.querySelectorAll(inputSelector)); 124 dropElementIndex = rowElements.indexOf(el); 125 126 if (url) { 127 // Detach task field if exists 128 const task = document.querySelector('[name="task"]'); // Detach task field if exists 129 130 if (task) { 131 task.setAttribute('name', 'some__Temporary__Name__'); 132 } // Prepare the options 133 134 135 const ajaxOptions = { 136 url, 137 method: 'POST', 138 data: `$new URLSearchParams(formData).toString()}&$getOrderData(rows, inputRows, dragElementIndex, dropElementIndex).join('&')}`, 139 perform: true 140 }; 141 Joomla.request(ajaxOptions); // Re-Append original task field 142 143 if (task) { 144 task.setAttribute('name', 'task'); 145 } 146 } // Update positions for a children of the moved item 147 148 149 rearrangeChildren(el); 150 }; // eslint-disable-next-line no-undef 151 152 153 dragula([container], { 154 // Y axis is considered when determining where an element would be dropped 155 direction: 'vertical', 156 // elements are moved by default, not copied 157 copy: false, 158 // elements in copy-source containers can be reordered 159 // copySortSource: true, 160 // spilling will put the element back where it was dragged from, if this is true 161 revertOnSpill: true, 162 163 // spilling will `.remove` the element, if this is true 164 // removeOnSpill: false, 165 accepts(el, target, source, sibling) { 166 if (isNested) { 167 if (sibling !== null) { 168 return sibling.dataset.draggableGroup && sibling.dataset.draggableGroup === el.dataset.draggableGroup; 169 } 170 171 return sibling === null || sibling && sibling.tagName.toLowerCase() === 'tr'; 172 } 173 174 return sibling === null || sibling && sibling.tagName.toLowerCase() === 'tr'; 175 }, 176 177 mirrorContainer: container 178 }).on('drag', el => { 179 let rowSelector; 180 const groupId = el.dataset.draggableGroup; 181 182 if (groupId) { 183 rowSelector = `tr[data-draggable-group="$groupId}"]`; 184 } else { 185 rowSelector = 'tr'; 186 } 187 188 const rowElements = [].slice.call(container.querySelectorAll(rowSelector)); 189 dragElementIndex = rowElements.indexOf(el); 190 }).on('drop', el => { 191 saveTheOrder(el); 192 }); 193 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |