New drag-and-drop system

master
Eirik Th S 2022-02-09 16:51:19 +01:00
parent b3fe240f55
commit de091bf3ab
6 changed files with 149 additions and 17 deletions

View File

@ -1,3 +1,4 @@
2022-02-09 Fixed drag-and-drop on iOS.
2022-02-02 Fixed wrong strikethrough.
2022-01-26 Search for products and some UI-fixes.
2022-01-19 Revamped the login-system.

2
www/js/sortable/Sortable.min.js vendored Normal file

File diff suppressed because one or more lines are too long

76
www/js/sortable/jquery-sortable.js vendored Normal file
View File

@ -0,0 +1,76 @@
(function (factory) {
"use strict";
var sortable,
jq,
_this = this
;
if (typeof define === "function" && define.amd) {
try {
define(["sortablejs", "jquery"], function(Sortable, $) {
sortable = Sortable;
jq = $;
checkErrors();
factory(Sortable, $);
});
} catch(err) {
checkErrors();
}
return;
} else if (typeof exports === 'object') {
try {
sortable = require('sortablejs');
jq = require('jquery');
} catch(err) { }
}
if (typeof jQuery === 'function' || typeof $ === 'function') {
jq = jQuery || $;
}
if (typeof Sortable !== 'undefined') {
sortable = Sortable;
}
function checkErrors() {
if (!jq) {
throw new Error('jQuery is required for jquery-sortablejs');
}
if (!sortable) {
throw new Error('SortableJS is required for jquery-sortablejs (https://github.com/SortableJS/Sortable)');
}
}
checkErrors();
factory(sortable, jq);
})(function (Sortable, $) {
"use strict";
$.fn.sortable = function (options) {
var retVal,
args = arguments;
this.each(function () {
var $el = $(this),
sortable = $el.data('sortable');
if (!sortable && (options instanceof Object || !options)) {
sortable = new Sortable(this, options);
$el.data('sortable', sortable);
} else if (sortable) {
if (options === 'destroy') {
sortable.destroy();
$el.removeData('sortable');
} else if (options === 'widget') {
retVal = sortable;
} else if (typeof sortable[options] === 'function') {
retVal = sortable[options].apply(sortable, [].slice.call(args, 1));
} else if (options in sortable.options) {
retVal = sortable.option.apply(sortable, args);
}
}
});
return (retVal === void 0) ? this : retVal;
};
});

View File

@ -152,7 +152,7 @@ if(!empty($data) && isset($user_id)){
returns("Missing a value: $temp", 1);
}
if( moveItem($data['storeID'], $data['itemID'], $data['afterID']) ){
if( moveItem($data['storeID'], $data['itemID'], $data['afterID'], @$data['newStoreId']) ){
returns();
}
@ -412,10 +412,10 @@ function remItem($storeID, $itemID, $price){
return false;
}
function moveItem($storeID, $itemID, $afterID){
function moveItem($storeID, $itemID, $afterID, $newStoreId = null){
global $db;
$verifyUserOwnershipSQL = getVerifyStoreOwnerSQL($storeID);
/*$verifyUserOwnershipSQL = getVerifyStoreOwnerSQL($storeID);
$sameStoreCheckSQL = "SELECT (SELECT plan_store_id FROM plan_store_item WHERE `plan_item_id` = $itemID AND `plan_store_id` = ($verifyUserOwnershipSQL)) moved, (SELECT plan_store_id FROM plan_store_item WHERE plan_item_id = $afterID) after";
$differentStoreAddSQL = "";
@ -427,6 +427,13 @@ function moveItem($storeID, $itemID, $afterID){
$storeID = $stores[1];
$differentStoreAddSQL = ", plan_store_id = $storeID";
}
}*/
$differentStoreAddSQL = "";
if($newStoreId != null){
$storeID = $newStoreId;
$differentStoreAddSQL = ", plan_store_id = $storeID";
}
$verifyUserOwnershipSQL = getVerifyStoreOwnerSQL($storeID);

View File

@ -3,6 +3,10 @@
<head>
<?=getHtmlHeaders($rPath);?>
<title>Plan - PaperBag - Plan Your Shopping</title>
<!-- jsDelivr :: Sortable :: Latest (https://www.jsdelivr.com/package/npm/sortablejs) -->
<script src="/js/sortable/Sortable.min.js"></script> <!-- CDN: https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js -->
<script src="/js/sortable/jquery-sortable.js"></script> <!-- CDN: https://cdn.jsdelivr.net/npm/jquery-sortablejs@latest/jquery-sortable.js -->
</head>
<body id='plan'>
<div id="page-container">
@ -37,7 +41,7 @@
<script src='plan.js'></script>
<script src='recipe.js'></script>
<script src='product.js'></script>
<script src='draggingClass.js'></script>
<!-- <script src='draggingClass.js'></script>-->
</div>
<?php include $rPath.'webdata/footer.html'; ?>
</div>

View File

@ -1,4 +1,7 @@
/*jshint sub:true, esversion: 6, -W083 */
const debug = false;
// Default timer for jquery slide, except set to 0 if the user prefers reduced motion.
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const slideTimer = prefersReducedMotion?0:400;
@ -29,7 +32,7 @@ class Store {
html += " <div class='card-body'>";
html += " <ul class='list-group list-group-flush storeItems dragHolder'>";
html += " <li class='list-group-item emptyList'>No items added</li>";
html += " <li class='list-group-item draggable' data-itemid='0' data-storeid='"+this.storeID+"' style='height: 10px; width: 100%;'></li>";
// html += " <li class='list-group-item draggable' data-itemid='0' data-storeid='"+this.storeID+"' style='height: 10px; width: 100%;'></li>";
html += " </ul>";
html += HtmlElements.store.addItemSection;
@ -62,12 +65,10 @@ class Store {
if($(ev.currentTarget).hasClass('planningState')){
this.setState('planning');
// this.selector.find(".newItemName").first().focus();
this.selector.find(".card-body").focus();
}
else if($(ev.currentTarget).hasClass('shoppingState')){
this.setState('shopping');
// this.selector.find(".checkItems input").first().focus();
this.selector.find(".card-body").focus();
}
else if($(ev.currentTarget).hasClass('closedState')){
@ -88,7 +89,46 @@ class Store {
});
// INIT DRAGGING
this.draggingClass = new Draggable("draggable", 'dragHolder', 'drag-over', "#store"+storeNum,(moved, after)=> {
this.selector.find('.dragHolder').sortable({
handle: '.draggable',
filter: '.priceWrapper, .itemButtons',
group: 'shared',
ghostClass: 'bg-secondary',
delay: 100,
delayOnTouchOnly: true,
onEnd: (evt) => {
let newStore;
if(evt.from !== evt.to){
console.info("Item is moved to a new list.");
let fromStoreElem= $(evt.from);
if(fromStoreElem.find("li").length <= 1){
fromStoreElem.find('.emptyList').show();
}
let toStoreElem= $(evt.to);
newStore = toStoreElem.attr('data-storeid');
toStoreElem.find('.emptyList').hide();
}
else if(evt.oldIndex === evt.newIndex){
console.warn("Item wasn't moved! (?)");
return;
}
let itemElem = $(evt.item);
let itemId = itemElem.attr('data-itemid');
let afterId = itemElem.prev().attr('data-itemid');
if(typeof afterId === "undefined"){
afterId = 0;
}
this.setItemPosition(itemId, afterId, newStore);
}
});
/*this.draggingClass = new Draggable("draggable", 'dragHolder', 'drag-over', "#store"+storeNum,(moved, after)=> {
// console.log(moved, after);
let movedID = moved.attr('data-itemid');
@ -101,7 +141,7 @@ class Store {
$("#refreshAll").trigger('click');
}
}
});
});*/
}
setState(state, animTime){
@ -110,22 +150,22 @@ class Store {
if(state === "planning"){
this.state = "planning";
this.selector.find('ul').addClass('storePlanState');
this.selector.find('ul').addClass('storePlanState').find('li:not(.emptyList)').addClass('draggable');
this.selector.find('li:not(.checkedItem) .itemAmountButtons').slideDown(animTime);
// this.selector.find('li:not(.checkedItem) .itemAmountText').slideUp(animTime);
// this.selector.find('.checkedItem .itemAmountText:not(.oneItem)').slideDown(animTime);
this.selector.find('.addItemFormWrapper').slideDown(animTime);
this.selector.find('.remItem').show();
this.draggingClass.unpause();
// this.draggingClass.unpause();
}
if(state !== "planning"){
this.selector.find('ul').removeClass('storePlanState');
this.selector.find('ul').removeClass('storePlanState').find('li').removeClass('draggable');
this.selector.find('.itemAmountButtons').slideUp(animTime);
// this.selector.find('.itemAmountText:not(.oneItem)').slideDown(animTime);
this.selector.find('.addItemFormWrapper').slideUp(animTime);
this.selector.find('.remItem').hide();
this.draggingClass.pause();
// this.draggingClass.pause();
}
if(state === "shopping"){
@ -291,7 +331,7 @@ class Store {
if(newChecked === true){
this.selector.find('#item_'+itemID).addClass("checkedItem");
this.draggingClass.moveToBottomAnimated('#item_'+itemID);
// this.draggingClass.moveToBottomAnimated('#item_'+itemID);
}
else {
this.selector.find('#item_'+itemID).removeClass("checkedItem");
@ -353,10 +393,12 @@ class Store {
}, 500);
}
setItemPosition(itemID, afterID){
setItemPosition(itemID, afterID, newStore){
afterID = afterID || 0;
newStore = newStore || this.storeID;
if(itemID !== afterID){
return ajaxReq({ plan: 'moveItem', storeID: this.storeID, itemID: itemID, afterID: afterID });
return ajaxReq({ plan: 'moveItem', storeID: this.storeID, itemID: itemID, afterID: afterID, newStoreId: newStore });
}
return false;
}
@ -414,7 +456,7 @@ class Store {
});
// DRAGGABLE
this.draggingClass.update();
// this.draggingClass.update();
/*let draggingObj = null, dragPos = null;
this.selector.find('.draggable').unbind().on('dragstart dragover dragenter dragleave dragend', ev => {
// this.selector.find('.draggable').hammer().bind('swipe', ev => {