From d5ccaf1b9c106dbb7eda7f43f79c8c63b9512a6a Mon Sep 17 00:00:00 2001 From: Jakob Ketterl Date: Fri, 2 Jun 2023 12:19:38 +0200 Subject: [PATCH] make drag & drop work with parameters --- htdocs/lib/settings/DraggableList.js | 61 +++++++++++++++++++++++ htdocs/lib/settings/ProfileList.js | 72 ---------------------------- htdocs/settings.js | 14 +++++- owrx/controllers/assets.py | 2 +- 4 files changed, 75 insertions(+), 74 deletions(-) create mode 100644 htdocs/lib/settings/DraggableList.js delete mode 100644 htdocs/lib/settings/ProfileList.js diff --git a/htdocs/lib/settings/DraggableList.js b/htdocs/lib/settings/DraggableList.js new file mode 100644 index 00000000..dabd6976 --- /dev/null +++ b/htdocs/lib/settings/DraggableList.js @@ -0,0 +1,61 @@ +$.fn.draggableList = function(options) { + var isValidDrag = function(event) { + // check and avoid external drags + if (!event.originalEvent.dataTransfer.types.includes(options.dataType)) return false; + + var $target = $(event.target).closest(options.itemSelector); + + // check if we are a valid drop target + return !!$target.length; + } + + this.each(function () { + var $list = $(this); + var $items = $list.find(options.itemSelector); + $items.attr('draggable', 'true'); + $items.find('a').attr('draggable', 'false'); + var $draggedElement; + var originalIndex; + var $spinner = $('.overlay-spinner'); + + $list.on('dragstart', options.itemSelector, function(event){ + $draggedElement = $(event.originalEvent.target); + originalIndex = $draggedElement.index(); + event.originalEvent.dataTransfer.effectAllowed = 'move'; + event.originalEvent.dataTransfer.setData(options.dataType, $draggedElement.data(options.idProperty)); + }).on('dragenter', function(event) { + if (!isValidDrag(event)) return; + event.preventDefault(); + + var $target = $(event.target).closest(options.itemSelector); + if ($draggedElement.index() < $target.index()) { + $draggedElement.insertAfter($target); + } else { + $draggedElement.insertBefore($target); + } + }).on('dragover', function(event) { + if (!isValidDrag(event)) return; + event.preventDefault(); + }).on('drop', function(event) { + if (!isValidDrag(event)) return; + var $target = $(event.target).closest(options.itemSelector); + var index = $list.find(options.itemSelector).index($target); + + $spinner.addClass('d-flex'); + options.performMove(event.originalEvent.dataTransfer.getData(options.dataType), index).done(function() { + // done + }).fail(function() { + // backend reported error, restore original position + $draggedElement.remove().insertBefore($list.children().eq(originalIndex)); + }).always(function() { + $draggedElement = undefined; + $spinner.removeClass('d-flex'); + }); + }).on('dragend', options.itemSelector, function(event) { + if (event.originalEvent.dataTransfer.dropEffect === 'none') { + // drag was aborted - restore original position + $draggedElement.remove().insertBefore($list.children().eq(originalIndex)); + } + }); + }); +} \ No newline at end of file diff --git a/htdocs/lib/settings/ProfileList.js b/htdocs/lib/settings/ProfileList.js deleted file mode 100644 index 60058179..00000000 --- a/htdocs/lib/settings/ProfileList.js +++ /dev/null @@ -1,72 +0,0 @@ -$.fn.profileList = function() { - var dataType = 'application/x-profile'; - - var isValidDrag = function(event) { - // check and avoid external drags - if (!event.originalEvent.dataTransfer.types.includes(dataType)) return false; - - var $target = $(event.target).closest('.profile'); - - // check if we are a valid drop target - return !!$target.length; - } - - this.each(function () { - var $profileList = $(this); - var $profiles = $profileList.find('.profile'); - $profiles.attr('draggable', 'true'); - $profiles.find('a').attr('draggable', 'false'); - var $profileEl; - var originalIndex; - var $spinner = $('.overlay-spinner'); - - var moveProfile = function(profileId, index) { - var url = $profileList.find('.device a').attr('href'); - return $.ajax(url + '/moveprofile', { - data: JSON.stringify({profile_id: profileId, index: index}), - contentType: 'application/json', - method: 'POST' - }); - } - - $profileList.on('dragstart', '.profile', function(event){ - $profileEl = $(event.originalEvent.target); - originalIndex = $profileEl.index(); - event.originalEvent.dataTransfer.effectAllowed = 'move'; - event.originalEvent.dataTransfer.setData(dataType, $profileEl.data('profile-id')); - }).on('dragenter', function(event) { - if (!isValidDrag(event)) return; - event.preventDefault(); - - var $target = $(event.target).closest('.profile'); - if ($profileEl.index() < $target.index()) { - $profileEl.insertAfter($target); - } else { - $profileEl.insertBefore($target); - } - }).on('dragover', function(event) { - if (!isValidDrag(event)) return; - event.preventDefault(); - }).on('drop', function(event) { - if (!isValidDrag(event)) return; - var $target = $(event.target).closest('.profile'); - var index = $profileList.find('.profile').index($target); - - $spinner.addClass('d-flex'); - moveProfile(event.originalEvent.dataTransfer.getData(dataType), index).done(function() { - // done - }).fail(function() { - // backend reported error, restore original position - $profileEl.remove().insertBefore($profileList.children().eq(originalIndex)); - }).always(function() { - $profileEl = undefined; - $spinner.removeClass('d-flex'); - }); - }).on('dragend', '.profile', function(event) { - if (event.originalEvent.dataTransfer.dropEffect === 'none') { - // drag was aborted - restore original position - $profileEl.remove().insertBefore($profileList.children().eq(originalIndex)); - } - }); - }); -} \ No newline at end of file diff --git a/htdocs/settings.js b/htdocs/settings.js index 72328e24..6263d478 100644 --- a/htdocs/settings.js +++ b/htdocs/settings.js @@ -9,5 +9,17 @@ $(function(){ $('#scheduler').schedulerInput(); $('.exponential-input').exponentialInput(); $('.device-log-messages').logMessages(); - $('.profile-tabs').profileList(); + $('.profile-tabs').draggableList({ + dataType: 'application/x-profile', + itemSelector: '.profile', + idProperty: 'profile-id', + performMove: function(profileId, index) { + var url = $('.profile-tabs .device a').attr('href'); + return $.ajax(url + '/moveprofile', { + data: JSON.stringify({profile_id: profileId, index: index}), + contentType: 'application/json', + method: 'POST' + }); + } + }); }); \ No newline at end of file diff --git a/owrx/controllers/assets.py b/owrx/controllers/assets.py index f356c3cb..e5c86b2f 100644 --- a/owrx/controllers/assets.py +++ b/owrx/controllers/assets.py @@ -159,7 +159,7 @@ class CompiledAssetsController(GzipMixin, ModificationAwareController): "lib/settings/SchedulerInput.js", "lib/settings/ExponentialInput.js", "lib/settings/LogMessages.js", - "lib/settings/ProfileList.js", + "lib/settings/DraggableList.js", "settings.js", ], }