(Hopefully) fix position of store-buttons, [WIP] check items, some bugfixes
parent
5206d3f6f6
commit
8b1e62be80
|
@ -39,9 +39,9 @@ body {
|
|||
}
|
||||
|
||||
.iconWrapper {
|
||||
float: right;
|
||||
margin-top: -30px;
|
||||
margin-right: 10px;
|
||||
/*float: right; */
|
||||
/*margin-top: -35px;*/
|
||||
/*margin-right: 10px;*/
|
||||
}
|
||||
.iconWrapper img {
|
||||
margin-left: 10px;
|
||||
|
@ -75,6 +75,7 @@ body {
|
|||
|
||||
#stores .card-header {
|
||||
font-weight: bold;
|
||||
height: 38px;
|
||||
}
|
||||
|
||||
.priceWrapper {
|
||||
|
@ -116,6 +117,10 @@ body.dollars span.price::after {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.checkedItem span {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.addItemForm div.form-control {
|
||||
transition: width 0.5s;
|
||||
}
|
||||
|
|
|
@ -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"){
|
||||
if(($temp = checkArgs(array("storeID"=>@$data['storeID'], "itemID"=>@$data['itemID'], "price"=>@$data['price']))) !== true){
|
||||
returns("Missing a value: $temp", 1);
|
||||
|
@ -198,7 +211,7 @@ if(!empty($data) && isset($user_id)){
|
|||
|
||||
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'] = [];
|
||||
if($result2->num_rows > 0){
|
||||
|
@ -371,13 +384,25 @@ function addItem($storeID, $name, $price){
|
|||
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){
|
||||
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'";
|
||||
$removeItemsql = "DELETE FROM plan_store_item WHERE `plan_item_id` = ($findRowSql) AND `price` = '$price';";
|
||||
if($db->query($removeItemsql) && mysqli_affected_rows($db) > 0){
|
||||
$removeItemSql = "DELETE FROM plan_store_item WHERE `plan_item_id` = ($findRowSql) AND `price` = '$price';";
|
||||
if($db->query($removeItemSql) && mysqli_affected_rows($db) > 0){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -33,32 +33,5 @@
|
|||
|
||||
<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>
|
||||
</html>
|
109
www/plan/plan.js
109
www/plan/plan.js
|
@ -2,7 +2,7 @@
|
|||
|
||||
class Store {
|
||||
constructor(title, storeID, state) {
|
||||
this.items = [];
|
||||
this.itemsObj = {};
|
||||
this.state = state || 'planning'; // states: planning/shopping/closed
|
||||
|
||||
let storeNum = $(".store").length+1;
|
||||
|
@ -11,19 +11,19 @@ class Store {
|
|||
|
||||
let html = "";
|
||||
html += "<div class='card store' style='width: 25rem; max-width: 90vw;'>";
|
||||
html += " <div class='card-header'>"+this.title+"</div>";
|
||||
html += " <div class='iconWrapper' style='float: left; margin-top: -35px; margin-left: 1px;'>";
|
||||
html += " <div class='iconWrapper' style='position: absolute; top: 1px; left: 1px;'>";
|
||||
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 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 += " </ul></nav>";
|
||||
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/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 += " </div>";
|
||||
html += " <div class='card-header'>"+this.title+"</div>";
|
||||
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 += " <li class='list-group-item emptyList'>No items added</li>";
|
||||
|
@ -98,14 +98,18 @@ class Store {
|
|||
|
||||
if(state === "planning"){
|
||||
this.state = "planning";
|
||||
this.selector.find('.itemAmountButtons').slideDown(animTime);
|
||||
this.selector.find('.itemAmountText').slideUp(animTime);
|
||||
this.selector.find('li:not(.checkedItem) .itemAmountButtons').slideDown(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('.remItem').show();
|
||||
}
|
||||
if(state !== "planning"){
|
||||
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();
|
||||
}
|
||||
|
||||
if(state === "shopping"){
|
||||
|
@ -117,10 +121,10 @@ class Store {
|
|||
|
||||
if(state === "closed"){
|
||||
this.state = "closed";
|
||||
this.selector.find('.remItem').hide();
|
||||
|
||||
}
|
||||
if(state !== "closed"){
|
||||
this.selector.find('.remItem').show();
|
||||
|
||||
}
|
||||
|
||||
if(prevState !== state){
|
||||
|
@ -196,21 +200,23 @@ class Store {
|
|||
}
|
||||
}
|
||||
|
||||
addItemHtml(text, price, itemID, amount){
|
||||
addItemHtml(text, price, itemID, amount, checked){
|
||||
amount = amount || 1;
|
||||
checked = Number(checked) || 0;
|
||||
|
||||
try {
|
||||
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";
|
||||
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 += " <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 += " <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 += " <input class='form-control itemAmount itemAmountBtn' type='number' value='"+amount+"' min='0' max='99' aria-label='Amount of item' >";
|
||||
if(price !== 0) {
|
||||
|
@ -218,7 +224,7 @@ class Store {
|
|||
}
|
||||
html += " <button class='btn btn-outline-success itemAmountBtn' type='button'>+</button>";
|
||||
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 += " </div>";
|
||||
html += " </span>";
|
||||
|
@ -237,27 +243,38 @@ class Store {
|
|||
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;
|
||||
|
||||
if(this.state === "planning"){
|
||||
|
||||
return ajaxReq({ plan: 'remItem', storeID: this.storeID, itemID: itemID, price: price })
|
||||
.done(json => {
|
||||
// console.log("remItem return:", json);
|
||||
return that.remItemHtml(itemID);
|
||||
});
|
||||
return ajaxReq({ plan: 'remItem', storeID: this.storeID, itemID: itemID, price: price })
|
||||
.done(json => {
|
||||
// console.log("remItem return:", json);
|
||||
return that.remItemHtml(itemID);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
remItemHtml(itemID){
|
||||
for(let i = 0; i < this.items.length; i++){
|
||||
if(this.items[i].itemID === itemID){
|
||||
this.items.splice(i,1);
|
||||
break;
|
||||
}
|
||||
// for(let i = 0; i < this.items.length; i++){
|
||||
// if(this.items[i].itemID === itemID){
|
||||
// this.items.splice(i,1);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
if(delete this.itemsObj[itemID]){
|
||||
this.selector.find('#item_'+itemID).remove();
|
||||
}
|
||||
this.selector.find('#item_'+itemID).remove();
|
||||
|
||||
this.verify();
|
||||
return true;
|
||||
|
@ -265,12 +282,15 @@ class Store {
|
|||
|
||||
setItemAmount(itemID, amount){
|
||||
// console.log(itemID, amount, this.items);
|
||||
this.items.forEach((item, key) => {
|
||||
if(item.itemID === itemID){
|
||||
this.items[key].amount = amount;
|
||||
this.selector.find('#item_'+itemID+" .priceWrapper .price").html(Number(amount*this.items[key].price).toFixed(2));
|
||||
}
|
||||
});
|
||||
// this.items.forEach((item, key) => {
|
||||
// if(item.itemID === itemID){
|
||||
// this.items[key].amount = amount;
|
||||
// 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"){
|
||||
this.itemAmountDelay = {};
|
||||
|
@ -295,14 +315,20 @@ class Store {
|
|||
verify(){
|
||||
// UPDATE TOTAL PRICE
|
||||
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;
|
||||
// console.log("verify - item: "+item.price+"*"+item.amount);
|
||||
});
|
||||
}
|
||||
|
||||
$(this.selector).find(".subtotal .price").html(total.toFixed(2));
|
||||
|
||||
// SHOW if-empty MESSAGE
|
||||
if(this.selector.find("li").length <= 1){
|
||||
if(this.selector.find(".storeItems li").length <= 1){
|
||||
this.selector.find(".emptyList").show();
|
||||
}
|
||||
|
||||
|
@ -387,7 +413,7 @@ class Store {
|
|||
// console.log("remItem", $(this).hasClass("confirm"), $(this));
|
||||
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 {
|
||||
$(this).tooltip('dispose');
|
||||
}
|
||||
|
@ -419,9 +445,9 @@ class Store {
|
|||
removeStore(){
|
||||
this.selector.remove();
|
||||
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 => {
|
||||
console.log("Delete store response:",json);
|
||||
// console.log("Delete store response:",json);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -473,8 +499,8 @@ function updateTotalPrice(){
|
|||
for(const storeKey in stores){
|
||||
const store = stores[storeKey];
|
||||
|
||||
for(const itemKey in store.items){
|
||||
totalPrice += store.items[itemKey].amount*store.items[itemKey].price;
|
||||
for(const itemID in store.itemsObj){
|
||||
totalPrice += store.itemsObj[itemID].amount*store.itemsObj[itemID].price;
|
||||
}
|
||||
}
|
||||
$("#totalPrice").html(totalPrice);
|
||||
|
@ -547,7 +573,8 @@ function getStores(spaceID){
|
|||
json.data[store].items[item].name,
|
||||
json.data[store].items[item].price,
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ CREATE OR REPLACE TABLE plan_store_item (
|
|||
`name` varchar(200) NOT NULL,
|
||||
`price` decimal(8,2) NOT NULL,
|
||||
`amount` tinyint(3) unsigned DEFAULT 1,
|
||||
`checked` BOOLEAN default 0,
|
||||
PRIMARY KEY (plan_item_id),
|
||||
CONSTRAINT plan_store_item_FK FOREIGN KEY (plan_store_id) REFERENCES `plan_store`(`plan_store_id`)
|
||||
) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
|
||||
|
|
Loading…
Reference in New Issue