Add a very simple javascript-only shopping list that works offline

The OfflineShoppingList disables auto-reloading by adding the 'fullscreen-card' class to the body. It also requests a confirmation on leaving the page because nothing is saved, not even into the local or session storage. Please consider this feature as a rough draft and foundation for discussion.
This commit is contained in:
Leroy Foerster 2019-09-01 23:07:37 +02:00
parent a4454f825a
commit 8192fb32f4
4 changed files with 85 additions and 3 deletions

View File

@ -81,6 +81,25 @@ class StockController extends BaseController
]); ]);
} }
public function OfflineShoppingList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{
$listId = 1;
if (isset($request->getQueryParams()['list']))
{
$listId = $request->getQueryParams()['list'];
}
return $this->AppContainer->view->render($response, 'offlineshoppinglist', [
'listItems' => $this->Database->shopping_list()->where('shopping_list_id = :1', $listId),
'products' => $this->Database->products()->orderBy('name'),
'quantityunits' => $this->Database->quantity_units()->orderBy('name'),
'missingProducts' => $this->StockService->GetMissingProducts(),
'productGroups' => $this->Database->product_groups()->orderBy('name'),
'shoppingLists' => $this->Database->shopping_lists()->orderBy('name'),
'selectedShoppingListId' => $listId
]);
}
public function ProductsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function ProductsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
return $this->AppContainer->view->render($response, 'products', [ return $this->AppContainer->view->render($response, 'products', [

View File

@ -50,6 +50,7 @@ $app->group('', function()
$this->get('/shoppinglist', '\Grocy\Controllers\StockController:ShoppingList'); $this->get('/shoppinglist', '\Grocy\Controllers\StockController:ShoppingList');
$this->get('/shoppinglistitem/{itemId}', '\Grocy\Controllers\StockController:ShoppingListItemEditForm'); $this->get('/shoppinglistitem/{itemId}', '\Grocy\Controllers\StockController:ShoppingListItemEditForm');
$this->get('/shoppinglist/{listId}', '\Grocy\Controllers\StockController:ShoppingListEditForm'); $this->get('/shoppinglist/{listId}', '\Grocy\Controllers\StockController:ShoppingListEditForm');
$this->get('/offlineshoppinglist', '\Grocy\Controllers\StockController:OfflineShoppingList');
} }
// Recipe routes // Recipe routes

View File

@ -0,0 +1,59 @@
@extends('layout.default')
@section('title', $__t('Shopping list'))
@section('activeNav', 'shoppinglist')
@section('viewJsName', 'shoppinglist')
@push('pageScripts')
<script src="{{ $U('/node_modules/datatables.net-rowgroup/js/dataTables.rowGroup.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/node_modules/datatables.net-rowgroup-bs4/js/rowGroup.bootstrap4.min.js?v=', true) }}{{ $version }}"></script>
<script>
$('.item-row').click(function (id){
$(this).toggleClass('text-strike-through bg-secondary text-light');
});
// Set this page to a fullscreen card to prevent auto-reloading on database change events
$('body').addClass('fullscreen-card');
// Ask for confirmation if user wants to leave. Data is not saved.
$(window).bind('beforeunload', function(){ return ''});
</script>
@endpush
@push('pageStyles')
<link href="{{ $U('/node_modules/datatables.net-rowgroup-bs4/css/rowGroup.bootstrap4.min.css?v=', true) }}{{ $version }}" rel="stylesheet">
@endpush
@section('content')
<h2>Offline {{$__t('Shopping list')}}</h2>
<table id="shoppinglist-table" class="table table-sm table-striped">
<thead>
<tr>
<th class="border-right d-none"></th>
<th>{{ $__t('Product') }} / <em>{{ $__t('Note') }}</em></th>
<th>{{ $__t('Amount') }}</th>
<th class="d-none">Hiden product group</th>
<th class="d-none">Hidden status</th>
</tr>
</thead>
<tbody class="d-none">
@foreach($listItems as $listItem)
<tr id="shoppinglistitem-{{ $listItem->id }}-row" class="item-row">
<td class="d-none"></td>
<td>
@if(!empty($listItem->product_id)) {{ FindObjectInArrayByPropertyValue($products, 'id', $listItem->product_id)->name }}<br>@else<em>{!! nl2br($listItem->note) !!}</em>@endif
</td>
<td>
{{ $listItem->amount }} @if(!empty($listItem->product_id)){{ $__n($listItem->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $listItem->product_id)->qu_id_purchase)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $listItem->product_id)->qu_id_purchase)->name_plural) }}@endif
</td>
<td class="d-none">
@if(!empty(FindObjectInArrayByPropertyValue($products, 'id', $listItem->product_id)->product_group_id)) {{ FindObjectInArrayByPropertyValue($productGroups, 'id', FindObjectInArrayByPropertyValue($products, 'id', $listItem->product_id)->product_group_id)->name }} @else <span class="font-italic font-weight-light">{{ $__t('Ungrouped') }}</span> @endif
</td>
<td class="d-none">
@if(FindObjectInArrayByPropertyValue($missingProducts, 'id', $listItem->product_id) !== null) belowminstockamount @endif
</td>
</tr>
@endforeach
</tbody>
</table>
@stop

View File

@ -23,6 +23,9 @@
<a class="btn btn-outline-dark responsive-button" href="{{ $U('/shoppinglistitem/new?list=' . $selectedShoppingListId) }}"> <a class="btn btn-outline-dark responsive-button" href="{{ $U('/shoppinglistitem/new?list=' . $selectedShoppingListId) }}">
<i class="fas fa-plus"></i> {{ $__t('Add item') }} <i class="fas fa-plus"></i> {{ $__t('Add item') }}
</a> </a>
<a class="btn btn-outline-dark responsive-button @if($listItems->count() == 0) disabled @endif" href="{{ $U('/offlineshoppinglist?list=' . $selectedShoppingListId) }}">
<i class="fas fa-clipboard-check"></i> Offline {{ $__t('Shopping list') }}
</a>
<a id="clear-shopping-list" class="btn btn-outline-danger responsive-button @if($listItems->count() == 0) disabled @endif" href="#"> <a id="clear-shopping-list" class="btn btn-outline-danger responsive-button @if($listItems->count() == 0) disabled @endif" href="#">
<i class="fas fa-trash"></i> {{ $__t('Clear list') }} <i class="fas fa-trash"></i> {{ $__t('Clear list') }}
</a> </a>