mirror of https://github.com/espruino/BangleApps
commit
1c8b1d5a98
|
@ -1,2 +1,3 @@
|
|||
0.01: New App!
|
||||
0.02: Refactor code to store grocery list in separate file
|
||||
0.03: Sort selected items to bottom and enable Widgets
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
var filename = 'grocery_list.json';
|
||||
var settings = require("Storage").readJSON(filename,1)|| { products: [] };
|
||||
let menu;
|
||||
|
||||
function updateSettings() {
|
||||
require("Storage").writeJSON(filename, settings);
|
||||
|
@ -11,19 +12,32 @@ function twoChat(n){
|
|||
return ''+n;
|
||||
}
|
||||
|
||||
const mainMenu = settings.products.reduce(function(m, p, i){
|
||||
const name = twoChat(p.quantity)+' '+p.name;
|
||||
m[name] = {
|
||||
value: p.ok,
|
||||
format: v => v?'[x]':'[ ]',
|
||||
onchange: v => {
|
||||
settings.products[i].ok = v;
|
||||
updateSettings();
|
||||
}
|
||||
};
|
||||
return m;
|
||||
}, {
|
||||
'': { 'title': 'Grocery list' }
|
||||
});
|
||||
function sortMenu() {
|
||||
mainMenu.sort((a,b) => {
|
||||
const byValue = a.value-b.value;
|
||||
return byValue !== 0 ? byValue : a.index-b.index;
|
||||
});
|
||||
if (menu) {
|
||||
menu.draw();
|
||||
}
|
||||
}
|
||||
|
||||
const mainMenu = settings.products.map((p,i) => ({
|
||||
title: twoChat(p.quantity)+' '+p.name,
|
||||
value: p.ok,
|
||||
format: v => v?'[x]':'[ ]',
|
||||
index: i,
|
||||
onchange: v => {
|
||||
settings.products[i].ok = v;
|
||||
updateSettings();
|
||||
sortMenu();
|
||||
}
|
||||
}));
|
||||
sortMenu();
|
||||
|
||||
mainMenu[''] = { 'title': 'Grocery list' };
|
||||
mainMenu['< Back'] = ()=>{load();};
|
||||
E.showMenu(mainMenu);
|
||||
|
||||
Bangle.loadWidgets();
|
||||
menu = E.showMenu(mainMenu);
|
||||
Bangle.drawWidgets();
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="../../css/spectre.min.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h4>List of products</h4>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>name</th>
|
||||
<th>quantity</th>
|
||||
<th>done</th>
|
||||
<th>actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="products">
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<br><br>
|
||||
<h4>Add a new product</h4>
|
||||
<form id="add_product_form">
|
||||
<div class="columns">
|
||||
<div class="column col-4 col-xs-12">
|
||||
<input class="form-input input-sm" type="text" id="add_product_name" placeholder="Name">
|
||||
</div>
|
||||
<div class="column col-4 col-xs-12">
|
||||
<input class="form-input input-sm" value="1" type="number" id="add_product_quantity" placeholder="Quantity">
|
||||
</div>
|
||||
<div class="column col-4 col-xs-12">
|
||||
<button id="add_product_button" class="btn btn-primary btn-sm">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<br><br>
|
||||
<button id="reset" class="btn btn-error">Reload</button>
|
||||
<button id="removeChecked" class="btn">Clear checked</button>
|
||||
<button id="save" class="btn btn-primary">Save</button>
|
||||
|
||||
<script src="../../core/lib/interface.js"></script>
|
||||
|
||||
<script>
|
||||
let settings;
|
||||
let products;
|
||||
|
||||
var $name = document.getElementById('add_product_name')
|
||||
var $form = document.getElementById('add_product_form')
|
||||
var $button = document.getElementById('add_product_button')
|
||||
var $quantity = document.getElementById('add_product_quantity')
|
||||
var $list = document.getElementById('products')
|
||||
var $reset = document.getElementById('reset')
|
||||
|
||||
$reset.addEventListener('click', reset)
|
||||
document.getElementById('save').addEventListener('click', save);
|
||||
document.getElementById('removeChecked').addEventListener('click', removeChecked);
|
||||
|
||||
$form.addEventListener('submit', event => {
|
||||
event.preventDefault()
|
||||
|
||||
var name = $name.value.trim()
|
||||
if(!name) return;
|
||||
|
||||
var quantity = parseInt($quantity.value)
|
||||
|
||||
products.push({
|
||||
name, quantity,
|
||||
ok: false
|
||||
})
|
||||
|
||||
renderProducts()
|
||||
$name.value = ''
|
||||
$quantity.value = 1
|
||||
})
|
||||
|
||||
function getData() {
|
||||
// show loading window
|
||||
Util.showModal("Loading...");
|
||||
Util.readStorage('grocery_list.json', data=>{
|
||||
// remove window
|
||||
Util.hideModal();
|
||||
|
||||
settings = JSON.parse(data || "{products: []}");
|
||||
products = settings.products;
|
||||
renderProducts();
|
||||
});
|
||||
}
|
||||
|
||||
function save(){
|
||||
settings.products = products;
|
||||
Util.showModal("Saving...");
|
||||
localStorage.setItem('grocery-product-list',JSON.stringify(products));
|
||||
Util.writeStorage("grocery_list.json", JSON.stringify(settings), () => {
|
||||
Util.hideModal();
|
||||
});
|
||||
}
|
||||
|
||||
function reset(){
|
||||
getData();
|
||||
}
|
||||
|
||||
function removeProduct(index){
|
||||
products = products.filter((p,i) => i!==index)
|
||||
renderProducts()
|
||||
}
|
||||
|
||||
function handleChecked(index) {
|
||||
products[index].ok = !products[index].ok;
|
||||
}
|
||||
|
||||
function removeChecked() {
|
||||
products = products.filter(p => !p.ok);
|
||||
renderProducts()
|
||||
}
|
||||
|
||||
function renderProducts(){
|
||||
$list.innerHTML = ''
|
||||
products.forEach((product,index) => {
|
||||
var $product = document.createElement('tr')
|
||||
$product.innerHTML = `<td>${product.name}</td>
|
||||
<td>${product.quantity}</td>
|
||||
<td><input type="checkbox" ${product.ok ? "checked" : ""} onchange="handleChecked(${index})"></td>
|
||||
<td><button class="btn btn-error" onclick="removeProduct(${index})">remove</button></td>`
|
||||
$list.appendChild($product)
|
||||
})
|
||||
|
||||
$name.focus()
|
||||
|
||||
}
|
||||
|
||||
// Called when app starts
|
||||
function onInit() {
|
||||
getData();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,13 +1,14 @@
|
|||
{
|
||||
"id": "grocery",
|
||||
"name": "Grocery",
|
||||
"version": "0.02",
|
||||
"version": "0.03",
|
||||
"description": "Simple grocery (shopping) list - Display a list of product and track if you already put them in your cart.",
|
||||
"icon": "grocery.png",
|
||||
"type": "app",
|
||||
"tags": "tool,outdoors,shopping,list",
|
||||
"supports": ["BANGLEJS", "BANGLEJS2"],
|
||||
"custom": "grocery.html",
|
||||
"interface": "interface.html",
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"grocery.app.js","url":"app.js"},
|
||||
|
|
Loading…
Reference in New Issue