make drag & drop work with parameters

This commit is contained in:
Jakob Ketterl 2023-06-02 12:19:38 +02:00
parent eec1696e8f
commit d5ccaf1b9c
4 changed files with 75 additions and 74 deletions

View file

@ -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));
}
});
});
}

View file

@ -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));
}
});
});
}

View file

@ -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'
});
}
});
});

View file

@ -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",
],
}