PaperBag/plan/plan.js

359 lines
11 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

/*jshint sub:true, esversion: 6, -W083 */
class Store {
constructor(title, storeID) {
this.items = [];
let storeNum = $(".store").length+1;
this.title = title || "Store "+storeNum;
this.storeID = storeID || null;
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'>";
html += " <img src='../icon/pencil-square.svg' class='editStoreName' alt='edit name' data-toggle='tooltip' title='Edit store name' tabindex=0 role='button' />";
html += " <img src='../icon/x-circle.svg' class='removeStore' alt='remove store' data-toggle='tooltip' title='Remove store' tabindex=0 role='button' />";
html += " </div>";
html += " <div class='card-body'>";
html += " <ul class='list-group list-group-flush'>";
html += " <li class='list-group-item emptyList'>No items added</li>";
html += " </ul>";
html += " <hr>";
html += " <form action='#!' class='form-row input-group input-group-sm addItemForm'>";
html += " <input type='text' class='form-control newItemName' placeholder='New Item Name' data-toggle='tooltip' title='New Item Name' aria-label='New Item Name'>";
html += " <input type='number' class='form-control newItemPrice' value='0' min='0' step='.01' data-toggle='tooltip' title='Price' aria-label='Price'>";
html += " <div class='input-group-append'>";
html += " <input type='image' class='form-control addItem' src='../icon/plus.svg' alt='+'>";
html += " </div>";
html += " </form>";
// html += " <button class='save'>Save</button>";
html += " </div>";
html += " <div class='card-footer subtotal'>Subtotal: <span class='price'>0.00 kr</span></div>";
html += "</div>";
this.selector = $(html).appendTo("#stores");
let that = this;
this.selector.find(".addItemForm").on('submit', function(ev){
ev.preventDefault();
that.addItem($(this).find('.newItemName').val(), $(this).find('.newItemPrice').val())
.done(json => {
$(this).find('.newItemPrice').val(0);
$(this).find('.newItemName').val("").focus();
});
});
this.selector.find('.editStoreName').one('click keyup', ev => { this.editNameFn(ev); });
this.selector.find('.removeStore').on('click keyup', ev => {
if(ev.type == 'click' || ev.keyCode == 13){
if(confirm("Are you sure you want to remove this store?")){ this.removeStore(); }
}
});
$(function () {
$('[data-toggle="tooltip"]').tooltip();
});
/** DEV **/
// this.selector.find('.save').click(ev => { this.save(); });
}
editNameFn(ev){
if(ev.type == 'click' || ev.keyCode == 13){
$(ev.target).parent().hide();
let headerElem = $(ev.target).parent().parent().find(".card-header");
let orgHtml = headerElem.html();
headerElem.html("<span style='display: none;'>"+orgHtml+"</span><form action='#' class='changeNameForm'><input type='text' class='newName' value='"+orgHtml+"'><input type='image' src='../icon/pencil-square.svg'></form>");
headerElem.find(".changeNameForm").on('submit keyup', ev2 => {
if(ev2.type == "submit"){
ev2.preventDefault();
let newName = $(ev2.target).find(".newName").val();
let that = this;
this.rename(newName).done(json => {
// success
headerElem.html(newName);
that.selector.find('.iconWrapper').show();
that.selector.find('.editStoreName').one('click keyup', ev3 => { this.editNameFn(ev3); });
});
}
});
headerElem.find(".newName").on('keyup', ev3 => { this.resetEditNameFn(ev3); });
// $("body").one('click', ev3 => { this.resetEditNameFn(ev3); });
}
}
resetEditNameFn(ev){
if(
(ev.type=="keyup" && ev.keyCode === 27) ||
ev.type != "keyup"
){
// cancel
let orgHtml = this.selector.find('.card-header span').html();
this.selector.find('.card-header').html(orgHtml);
this.selector.find('.iconWrapper').show();
this.selector.find('.editStoreName').one('click keyup', ev3 => { this.editNameFn(ev3); });
}
}
addItem(text, price){
if(text.length > 0){
if(this.storeID === null){
this.getStoreID().done(json => { this.addItem(text, price); });
return;
}
let that = this;
return $.ajax({
method: "POST",
url: "do.php",
data: { plan: 'addItem', storeID: this.storeID, name: text, price: price },
dataType: 'JSON'
})
.done(json => {
if(handleJsonErrors(json)){
return false;
}
// console.log("addItem return:", json);
return that.addItemHtml(text, price);
})
.fail(handleAjaxErrors);
}
return false;
}
addItemHtml(text, price){
try {
price = Number(price);
this.items.push({ text: text, price: price });
this.selector.find("ul").append("<li class='list-group-item'><span>"+text+"</span><span class='price'>"+price.toFixed(2)+" kr <button class='remItem' data-price='"+price+"' data-toggle='tooltip' title='Remove item' style='background: url(../icon/dash.svg); height: 20px; width: 20px;'></button></span></li>");
this.selector.find(".emptyList").hide();
this.verify();
return true;
}
catch(e){
alert("Something failed. Try again.");
console.error(e, e.stack);
}
return false;
}
remItem(pos, price){
let that = this;
return $.ajax({
method: "POST",
url: "do.php",
data: { plan: 'remItem', storeID: this.storeID, position: pos, price: price },
dataType: 'JSON'
})
.done(json => {
if(handleJsonErrors(json)){
return false;
}
// console.log("remItem return:", json);
return that.remItemHtml(pos);
})
.fail(handleAjaxErrors);
}
remItemHtml(pos){
this.items.splice(pos,1);
$(this.selector).find(".remItem").unbind().each((key, val) => {
if(key == pos){
$(val).parent().parent().remove();
}
});
this.verify();
return true;
}
verify(){
// UPDATE TOTAL PRICE
let total = 0;
this.items.forEach(item => {
total += item.price;
});
$(this.selector).find(".subtotal .price").html(total.toFixed(2)+" kr");
// SHOW if-empty MESSAGE
if(this.selector.find("li").length <= 1){
this.selector.find(".emptyList").show();
}
// BIND remove-buttons
$(this.selector).find(".remItem").unbind().each((key, val) => {
let that = this;
$(val).click(function(){
that.remItem(key, $(this).attr("data-price"));
try {
$(this).tooltip('dispose');
}
catch(ignore){}
});
});
}
// save(){
// $.ajax({
// method: "POST",
// url: "do.php",
// data: { plan: 'saveStore', storeName: this.title, items: this.items },
// dataType: 'JSON'
// })
// .done(json => {
// // json = JSON.parse(body);
// if(handleJsonErrors(json)){
// return;
// }
// // console.log(json);
// })
// .fail(handleAjaxErrors);
// }
removeStore(){
this.selector.remove();
if(this.storeID != null){
$.ajax({
method: "POST",
url: "do.php",
data: { plan: 'deleteStore', storeID: this.storeID, storeName: this.title, itemsLength: this.items.length },
dataType: 'JSON'
})
.done(json => {
if(handleJsonErrors(json)){
return;
}
console.log("Delete store response:",json);
})
.fail(handleAjaxErrors);
}
}
getStoreID(){
let that = this;
return $.ajax({
method: "POST",
url: "do.php",
data: { plan: 'saveStore', storeName: this.title },
dataType: 'JSON'
})
.done(json => {
if(handleJsonErrors(json)){
return false;
}
console.log("getStore:", json);
that.storeID = json['data'];
return that.storeID;
})
.fail(handleAjaxErrors);
}
rename(newName){
if(this.storeID !== null){
return $.ajax({
method: "POST",
url: "do.php",
data: { plan: 'renameStore', storeID: this.storeID, newName: newName },
dataType: 'JSON'
})
.done(json => {
if(handleJsonErrors(json)){
return false;
}
return true;
})
.fail(handleAjaxErrors);
}
//TODO:
console.log("No store-id");
}
}
var stores = [];
$("#addStore").click(ev => {
stores.push(new Store());
});
$("#refreshAll").click(ev => {
stores = [];
getStores();
});
// GET STORES
function getStores(){
$("#stores").html("");
$.getJSON('do.php', { plan: '' })
.done(json => {
if(handleJsonErrors(json)){
return;
}
// console.log(json);
for(const store in json.data){
storeID = stores.length;
stores.push(new Store(json.data[store].name, json.data[store].plan_store_id));
for(const item in json.data[store].items){
stores[storeID].addItemHtml(json.data[store].items[item].name, json.data[store].items[item].price);
}
}
})
.fail(handleAjaxErrors);
}
getStores();
function handleJsonErrors(json){
if(typeof json.status != "undefined" && json.status != 0){
alert(json.message);
return true;
}
return false;
}
function handleAjaxErrors(jqxhr, textStatus, error){
if(textStatus === "parsererror" && jqxhr.responseText != ""){
alert("An error occured:\n"+jqxhr.responseText);
}
else {
alert("An error occured:\n"+error);
}
}