(Hopefully) fix position of store-buttons, [WIP] check items, some bugfixes

master
Eirik Th S 2021-06-13 01:57:04 +02:00
parent 5206d3f6f6
commit 8b1e62be80
5 changed files with 105 additions and 74 deletions

View File

@ -39,9 +39,9 @@ body {
} }
.iconWrapper { .iconWrapper {
float: right; /*float: right; */
margin-top: -30px; /*margin-top: -35px;*/
margin-right: 10px; /*margin-right: 10px;*/
} }
.iconWrapper img { .iconWrapper img {
margin-left: 10px; margin-left: 10px;
@ -75,6 +75,7 @@ body {
#stores .card-header { #stores .card-header {
font-weight: bold; font-weight: bold;
height: 38px;
} }
.priceWrapper { .priceWrapper {
@ -116,6 +117,10 @@ body.dollars span.price::after {
text-align: center; text-align: center;
} }
.checkedItem span {
text-decoration: line-through;
}
.addItemForm div.form-control { .addItemForm div.form-control {
transition: width 0.5s; transition: width 0.5s;
} }

View File

@ -98,6 +98,19 @@ if(!empty($data) && isset($user_id)){
} }
} }
else if($data['plan'] == "checkItem"){
if(($temp = checkArgs(array("storeID"=>@$data['storeID'], "itemID"=>@$data['itemID'], "checked"=>@$data['checked']))) !== true){
returns("Missing a value: $temp", 1);
}
if( checkItem($data['storeID'], $data['itemID'], $data['checked']) ){
returns();
}
else {
returns($db->error,1);
}
}
else if($data['plan'] == "remItem"){ else if($data['plan'] == "remItem"){
if(($temp = checkArgs(array("storeID"=>@$data['storeID'], "itemID"=>@$data['itemID'], "price"=>@$data['price']))) !== true){ if(($temp = checkArgs(array("storeID"=>@$data['storeID'], "itemID"=>@$data['itemID'], "price"=>@$data['price']))) !== true){
returns("Missing a value: $temp", 1); returns("Missing a value: $temp", 1);
@ -198,7 +211,7 @@ if(!empty($data) && isset($user_id)){
while($stores = $result->fetch_assoc()){ while($stores = $result->fetch_assoc()){
if($result2 = $db->query("SELECT `plan_item_id`, `name`, `price`, `amount` FROM plan_store_item WHERE `plan_store_id` = '$stores[plan_store_id]' ORDER BY pos")){ if($result2 = $db->query("SELECT `plan_item_id`, `name`, `price`, `amount`, `checked` FROM plan_store_item WHERE `plan_store_id` = '$stores[plan_store_id]' ORDER BY pos")){
$stores['items'] = []; $stores['items'] = [];
if($result2->num_rows > 0){ if($result2->num_rows > 0){
@ -371,13 +384,25 @@ function addItem($storeID, $name, $price){
return false; return false;
} }
function checkItem($storeID, $itemID, $checked){
global $db, $spaceID;
$verifyUserOwnershipSQL = "SELECT `plan_store_id` FROM plan_store WHERE `space_id` = '$spaceID' AND `plan_store_id` = '$storeID'";
$findRowSql = "SELECT `plan_item_id` FROM plan_store_item WHERE `plan_store_id` = ($verifyUserOwnershipSQL) AND `plan_item_id` = '$itemID'";
$checkItemSql = "UPDATE plan_store_item SET `checked` = ".($checked?1:0)." WHERE `plan_item_id` = ($findRowSql);";
if($db->query($checkItemSql)){
return true;
}
return false;
}
function remItem($storeID, $itemID, $price){ function remItem($storeID, $itemID, $price){
global $db, $spaceID; global $db, $spaceID;
$verifyUserOwnershipSQL = "SELECT `plan_store_id` FROM plan_store WHERE `space_id` = '$spaceID' AND `plan_store_id` = '$storeID'"; $verifyUserOwnershipSQL = "SELECT `plan_store_id` FROM plan_store WHERE `space_id` = '$spaceID' AND `plan_store_id` = '$storeID'";
$findRowSql = "SELECT `plan_item_id` FROM plan_store_item WHERE `plan_store_id` = ($verifyUserOwnershipSQL) AND `plan_item_id` = '$itemID'"; $findRowSql = "SELECT `plan_item_id` FROM plan_store_item WHERE `plan_store_id` = ($verifyUserOwnershipSQL) AND `plan_item_id` = '$itemID'";
$removeItemsql = "DELETE FROM plan_store_item WHERE `plan_item_id` = ($findRowSql) AND `price` = '$price';"; $removeItemSql = "DELETE FROM plan_store_item WHERE `plan_item_id` = ($findRowSql) AND `price` = '$price';";
if($db->query($removeItemsql) && mysqli_affected_rows($db) > 0){ if($db->query($removeItemSql) && mysqli_affected_rows($db) > 0){
return true; return true;
} }
return false; return false;

View File

@ -33,32 +33,5 @@
<script src='plan.js'></script> <script src='plan.js'></script>
<!--<div style='width: 30rem; margin: auto; margin-bottom: 100px;'>
<form action='#!' class='form-row input-group input-group-sm addItemForm'>
<div class="form-control form-floating">
<input type='text' id='newItemName0' class='form-control newItemName' placeholder='New Item Name' aria-label='New Item Name'>
<label for="newItemName0">New Item Name</label>
</div>
<div class="form-control form-floating">
<input type='number' id='newItemPrice0' class='form-control newItemPrice' value='0' min='0' step='.01' aria-label='Price'>
<label for="newItemPrice0">Price</label>
</div>
<div class='input-group-append'>
<input type='image' class='form-control addItem' src='../icon/plus.svg' alt='+'>
</div>
</form>
</div>-->
</body> </body>
</html> </html>

View File

@ -2,7 +2,7 @@
class Store { class Store {
constructor(title, storeID, state) { constructor(title, storeID, state) {
this.items = []; this.itemsObj = {};
this.state = state || 'planning'; // states: planning/shopping/closed this.state = state || 'planning'; // states: planning/shopping/closed
let storeNum = $(".store").length+1; let storeNum = $(".store").length+1;
@ -11,19 +11,19 @@ class Store {
let html = ""; let html = "";
html += "<div class='card store' style='width: 25rem; max-width: 90vw;'>"; html += "<div class='card store' style='width: 25rem; max-width: 90vw;'>";
html += " <div class='card-header'>"+this.title+"</div>"; html += " <div class='iconWrapper' style='position: absolute; top: 1px; left: 1px;'>";
html += " <div class='iconWrapper' style='float: left; margin-top: -35px; margin-left: 1px;'>";
html += " <nav aria-label='State changer'><ul class='pagination'>"; html += " <nav aria-label='State changer'><ul class='pagination'>";
html += " <li class='page-item planningState "+(this.state === 'planning'?"active":"")+"'><span class='page-link'><img src='../icon/list-check.svg' class='ariaButton' alt='Planning state' title='Planning state' data-toggle='tooltip' tabindex=0 role='button' /></span></li>"; html += " <li class='page-item planningState "+(this.state === 'planning'?"active":"")+"'><span class='page-link'><img src='../icon/list-check.svg' class='ariaButton' alt='Planning state' title='Planning state' data-toggle='tooltip' tabindex=0 role='button' /></span></li>";
html += " <li class='page-item shoppingState "+(this.state === 'shopping'?"active":"")+"'><span class='page-link'><img src='../icon/basket2.svg' class='ariaButton' alt='Shopping state' title='Shopping state' data-toggle='tooltip' tabindex=0 role='button' /></span></li>"; html += " <li class='page-item shoppingState "+(this.state === 'shopping'?"active":"")+"'><span class='page-link'><img src='../icon/basket2.svg' class='ariaButton' alt='Shopping state' title='Shopping state' data-toggle='tooltip' tabindex=0 role='button' /></span></li>";
html += " <li class='page-item closedState "+(this.state === 'closed'?"active":"")+"'><span class='page-link'><img src='../icon/check-all.svg' class='ariaButton' alt='Closed state' title='Closed state' data-toggle='tooltip' tabindex=0 role='button' /></span></li>"; html += " <li class='page-item closedState "+(this.state === 'closed'?"active":"")+"'><span class='page-link'><img src='../icon/check-all.svg' class='ariaButton' alt='Closed state' title='Closed state' data-toggle='tooltip' tabindex=0 role='button' /></span></li>";
html += " </ul></nav>"; html += " </ul></nav>";
html += " </div>"; html += " </div>";
html += " <div class='iconWrapper'>"; html += " <div class='iconWrapper' style='position: absolute; top: 6px; right: 6px;'>";
html += " <img src='../icon/pencil-square.svg' class='editStoreName ariaButton' alt='edit name' data-toggle='tooltip' title='Edit store name' tabindex=0 role='button' />"; html += " <img src='../icon/pencil-square.svg' class='editStoreName ariaButton' alt='edit name' data-toggle='tooltip' title='Edit store name' tabindex=0 role='button' />";
// html += " <img src='../icon/filter-square.svg' class='sortItems ariaButton' alt='sort items' data-toggle='tooltip' title='Sort items by appearance in store' tabindex=0 role='button' />"; // html += " <img src='../icon/filter-square.svg' class='sortItems ariaButton' alt='sort items' data-toggle='tooltip' title='Sort items by appearance in store' tabindex=0 role='button' />";
html += " <img src='../icon/x-circle.svg' class='removeStore ariaButton' alt='remove store' data-toggle='tooltip' title='Remove store' tabindex=0 role='button' />"; html += " <img src='../icon/x-circle.svg' class='removeStore ariaButton' alt='remove store' data-toggle='tooltip' title='Remove store' tabindex=0 role='button' />";
html += " </div>"; html += " </div>";
html += " <div class='card-header'>"+this.title+"</div>";
html += " <div class='card-body'>"; html += " <div class='card-body'>";
html += " <div class='draggable' style='width: 100%; height: 10px; border-width: 1px;'></div> <ul class='list-group list-group-flush storeItems'>"; html += " <div class='draggable' style='width: 100%; height: 10px; border-width: 1px;'></div> <ul class='list-group list-group-flush storeItems'>";
html += " <li class='list-group-item emptyList'>No items added</li>"; html += " <li class='list-group-item emptyList'>No items added</li>";
@ -98,14 +98,18 @@ class Store {
if(state === "planning"){ if(state === "planning"){
this.state = "planning"; this.state = "planning";
this.selector.find('.itemAmountButtons').slideDown(animTime); this.selector.find('li:not(.checkedItem) .itemAmountButtons').slideDown(animTime);
this.selector.find('.itemAmountText').slideUp(animTime); this.selector.find('li:not(.checkedItem) .itemAmountText').slideUp(animTime);
this.selector.find('.checkedItem .itemAmountText').slideDown(animTime);
this.selector.find('.addItemFormWrapper').slideDown(animTime); this.selector.find('.addItemFormWrapper').slideDown(animTime);
this.selector.find('.remItem').show();
} }
if(state !== "planning"){ if(state !== "planning"){
this.selector.find('.itemAmountButtons').slideUp(animTime); this.selector.find('.itemAmountButtons').slideUp(animTime);
this.selector.find('.itemAmountText:not(.oneItem)').slideDown(animTime); this.selector.find('.itemAmountText:not(.oneItem)').slideDown(animTime);
this.selector.find('.addItemFormWrapper').slideUp(animTime); this.selector.find('.addItemFormWrapper').slideUp(animTime);
this.selector.find('.remItem').hide();
} }
if(state === "shopping"){ if(state === "shopping"){
@ -117,10 +121,10 @@ class Store {
if(state === "closed"){ if(state === "closed"){
this.state = "closed"; this.state = "closed";
this.selector.find('.remItem').hide();
} }
if(state !== "closed"){ if(state !== "closed"){
this.selector.find('.remItem').show();
} }
if(prevState !== state){ if(prevState !== state){
@ -196,21 +200,23 @@ class Store {
} }
} }
addItemHtml(text, price, itemID, amount){ addItemHtml(text, price, itemID, amount, checked){
amount = amount || 1; amount = amount || 1;
checked = Number(checked) || 0;
try { try {
price = Number(price); price = Number(price);
this.items.push({ text: text, price: price, itemID: itemID, amount: amount }); this.itemsObj[itemID] = { text: text, price: price, itemID: itemID, amount: amount, checked: checked };
let html = "\n"; let html = "\n";
html += "<li class='list-group-item draggable' id='item_"+itemID+"' data-itemid='"+itemID+"' draggable='true'>"; html += "<li class='list-group-item draggable"+(checked?' checkedItem':'')+"' id='item_"+itemID+"' data-itemid='"+itemID+"' draggable='true'>";
html += " <span style='float: left;'>"+text+"</span>"; html += " <span style='float: left;'>"+text+"</span>";
html += " <div class='priceWrapper'><span class='price'>"+(price*amount).toFixed(2)+"</span>"; html += " <div class='priceWrapper'><span class='price'>"+(price*amount).toFixed(2)+"</span>";
html += "<img src='../icon/dash-circle.svg' alt='Remove item' class='remItem ariaButton' data-itemID='"+itemID+"' data-price='"+price+"' style='margin-right: 3px;' tabindex='0' role='button'></div>"; html += "<img src='../icon/dash-circle.svg' alt='Remove item' class='remItem ariaButton' data-itemID='"+itemID+"' data-price='"+price+"' style='margin-right: 3px;' tabindex='0' role='button'></div>";
html += " <span class='itemAmountWrapper' style='float: left; padding: 0 10px;'>"; html += " <span class='itemAmountWrapper' style='float: left; padding: 0 10px;'>";
html += " <div class='input-group itemAmountButtons' >"; // "+(this.state !== "planning"?"style='display: none;'":'')+" html += " <div class='input-group itemAmountButtons' "+(this.state !== "planning" || checked?"style='display: none;'":'')+">";
html += " <button class='btn btn-outline-danger itemAmountBtn' type='button'>-</button>"; html += " <button class='btn btn-outline-danger itemAmountBtn' type='button'>-</button>";
html += " <input class='form-control itemAmount itemAmountBtn' type='number' value='"+amount+"' min='0' max='99' aria-label='Amount of item' >"; html += " <input class='form-control itemAmount itemAmountBtn' type='number' value='"+amount+"' min='0' max='99' aria-label='Amount of item' >";
if(price !== 0) { if(price !== 0) {
@ -218,7 +224,7 @@ class Store {
} }
html += " <button class='btn btn-outline-success itemAmountBtn' type='button'>+</button>"; html += " <button class='btn btn-outline-success itemAmountBtn' type='button'>+</button>";
html += " </div>"; html += " </div>";
html += " <div class='itemAmountText "+(amount <= 1?"oneItem":"")+"' style='display: none;'>"; // "+(this.state !== "shopping"?"style='display: none;'":'')+" html += " <div class='itemAmountText "+(amount <= 1?"oneItem":"")+"' "+(this.state !== "shopping" || !checked?"style='display: none;'":'')+">"; //
html += " Amount: <span class='itemAmount' style='padding-left: 10px;'>"+amount+"</span>x <span class='price'>" + price.toFixed(2) + "</span>"; html += " Amount: <span class='itemAmount' style='padding-left: 10px;'>"+amount+"</span>x <span class='price'>" + price.toFixed(2) + "</span>";
html += " </div>"; html += " </div>";
html += " </span>"; html += " </span>";
@ -237,27 +243,38 @@ class Store {
return false; return false;
} }
remItem(pos, itemID, price){ checkItem(itemID){
let newChecked = true;
if(this.itemsObj[itemID].checked){
newChecked = false;
}
alert("Tries to "+(newChecked?"check":"uncheck")+" an item!");
}
remItem(itemID, price){
let that = this; let that = this;
if(this.state === "planning"){ if(this.state === "planning"){
return ajaxReq({ plan: 'remItem', storeID: this.storeID, itemID: itemID, price: price }) return ajaxReq({ plan: 'remItem', storeID: this.storeID, itemID: itemID, price: price })
.done(json => { .done(json => {
// console.log("remItem return:", json); // console.log("remItem return:", json);
return that.remItemHtml(itemID); return that.remItemHtml(itemID);
}); });
} }
} }
remItemHtml(itemID){ remItemHtml(itemID){
for(let i = 0; i < this.items.length; i++){ // for(let i = 0; i < this.items.length; i++){
if(this.items[i].itemID === itemID){ // if(this.items[i].itemID === itemID){
this.items.splice(i,1); // this.items.splice(i,1);
break; // break;
} // }
// }
if(delete this.itemsObj[itemID]){
this.selector.find('#item_'+itemID).remove();
} }
this.selector.find('#item_'+itemID).remove();
this.verify(); this.verify();
return true; return true;
@ -265,12 +282,15 @@ class Store {
setItemAmount(itemID, amount){ setItemAmount(itemID, amount){
// console.log(itemID, amount, this.items); // console.log(itemID, amount, this.items);
this.items.forEach((item, key) => { // this.items.forEach((item, key) => {
if(item.itemID === itemID){ // if(item.itemID === itemID){
this.items[key].amount = amount; // this.items[key].amount = amount;
this.selector.find('#item_'+itemID+" .priceWrapper .price").html(Number(amount*this.items[key].price).toFixed(2)); // this.selector.find('#item_'+itemID+" .priceWrapper .price").html(Number(amount*this.items[key].price).toFixed(2));
} // }
}); // });
this.itemsObj[itemID].amount = amount;
this.selector.find('#item_'+itemID+" .priceWrapper .price").html(Number(amount*this.itemsObj[itemID].price).toFixed(2));
if(typeof this.itemAmountDelay === "undefined"){ if(typeof this.itemAmountDelay === "undefined"){
this.itemAmountDelay = {}; this.itemAmountDelay = {};
@ -295,14 +315,20 @@ class Store {
verify(){ verify(){
// UPDATE TOTAL PRICE // UPDATE TOTAL PRICE
let total = 0; let total = 0;
this.items.forEach(item => { // this.items.forEach(item => {
// total += item.price*item.amount;
// console.log("verify - item:' "+item.price+"*"+item.amount);
// });
for(const itemId in this.itemsObj){
let item = this.itemsObj[itemId];
total += item.price*item.amount; total += item.price*item.amount;
// console.log("verify - item: "+item.price+"*"+item.amount); }
});
$(this.selector).find(".subtotal .price").html(total.toFixed(2)); $(this.selector).find(".subtotal .price").html(total.toFixed(2));
// SHOW if-empty MESSAGE // SHOW if-empty MESSAGE
if(this.selector.find("li").length <= 1){ if(this.selector.find(".storeItems li").length <= 1){
this.selector.find(".emptyList").show(); this.selector.find(".emptyList").show();
} }
@ -387,7 +413,7 @@ class Store {
// console.log("remItem", $(this).hasClass("confirm"), $(this)); // console.log("remItem", $(this).hasClass("confirm"), $(this));
if($(this).hasClass("confirm")){ if($(this).hasClass("confirm")){
that.remItem(key+1, $(this).attr('data-itemid'), $(this).attr("data-price")); that.remItem($(this).attr('data-itemid'), $(this).attr("data-price"));
try { try {
$(this).tooltip('dispose'); $(this).tooltip('dispose');
} }
@ -419,9 +445,9 @@ class Store {
removeStore(){ removeStore(){
this.selector.remove(); this.selector.remove();
if(this.storeID != null){ if(this.storeID != null){
ajaxReq({ plan: 'deleteStore', storeID: this.storeID, storeName: this.title, itemsLength: this.items.length }) ajaxReq({ plan: 'deleteStore', storeID: this.storeID, storeName: this.title, itemsLength: Object.keys(this.itemsObj).length })
.done(json => { .done(json => {
console.log("Delete store response:",json); // console.log("Delete store response:",json);
}); });
} }
} }
@ -473,8 +499,8 @@ function updateTotalPrice(){
for(const storeKey in stores){ for(const storeKey in stores){
const store = stores[storeKey]; const store = stores[storeKey];
for(const itemKey in store.items){ for(const itemID in store.itemsObj){
totalPrice += store.items[itemKey].amount*store.items[itemKey].price; totalPrice += store.itemsObj[itemID].amount*store.itemsObj[itemID].price;
} }
} }
$("#totalPrice").html(totalPrice); $("#totalPrice").html(totalPrice);
@ -547,7 +573,8 @@ function getStores(spaceID){
json.data[store].items[item].name, json.data[store].items[item].name,
json.data[store].items[item].price, json.data[store].items[item].price,
json.data[store].items[item].plan_item_id, json.data[store].items[item].plan_item_id,
json.data[store].items[item].amount); json.data[store].items[item].amount,
json.data[store].items[item].checked);
} }
stores[storeKey].setState(json.data[store].state, 1); stores[storeKey].setState(json.data[store].state, 1);
} }

View File

@ -53,6 +53,7 @@ CREATE OR REPLACE TABLE plan_store_item (
`name` varchar(200) NOT NULL, `name` varchar(200) NOT NULL,
`price` decimal(8,2) NOT NULL, `price` decimal(8,2) NOT NULL,
`amount` tinyint(3) unsigned DEFAULT 1, `amount` tinyint(3) unsigned DEFAULT 1,
`checked` BOOLEAN default 0,
PRIMARY KEY (plan_item_id), PRIMARY KEY (plan_item_id),
CONSTRAINT plan_store_item_FK FOREIGN KEY (plan_store_id) REFERENCES `plan_store`(`plan_store_id`) CONSTRAINT plan_store_item_FK FOREIGN KEY (plan_store_id) REFERENCES `plan_store`(`plan_store_id`)
) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci; ) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;