[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/media/system/js/ -> draggable.js (source)

   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  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer