mirror of
https://github.com/grocy/grocy.git
synced 2026-04-05 12:26:15 +02:00
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:
parent
a4454f825a
commit
8192fb32f4
|
|
@ -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', [
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
59
views/offlineshoppinglist.blade.php
Normal file
59
views/offlineshoppinglist.blade.php
Normal 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
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user