Revize dd522430
Přidáno uživatelem Filip Jani před téměř 6 roky(ů)
app/bootstrap.php | ||
---|---|---|
17 | 17 |
$configurator->addConfig(__DIR__ . '/config/config.neon'); |
18 | 18 |
$configurator->addConfig(__DIR__ . '/config/config.local.neon'); |
19 | 19 |
$configurator->addConfig(__DIR__ . '/config/model.neon'); |
20 |
$configurator->addConfig(__DIR__ . '/config/components.neon'); |
|
20 | 21 | |
21 | 22 |
$container = $configurator->createContainer(); |
22 | 23 |
app/component/ExampleGrid.php | ||
---|---|---|
1 |
<?php |
|
2 | ||
3 | ||
4 |
namespace App\Components; |
|
5 | ||
6 | ||
7 |
use App\Utils\DataGrid\DataGrid; |
|
8 |
use Model\Repository\LineRepository; |
|
9 |
use Ublaboo\DataGrid\Exception\DataGridException; |
|
10 | ||
11 |
/** |
|
12 |
* Ukázkový datagrid, bude smazán při předání |
|
13 |
* - všechny možnosti použití gridu lze vidět na |
|
14 |
* https://gitlab.com/Fifal/dvm/blob/21afc037e3604093197e140defc05925df0b8c28/web-project/app/components/variant/VariantGrid.php |
|
15 |
* |
|
16 |
* @package App\Components |
|
17 |
*/ |
|
18 |
class ExampleGrid extends DataGrid |
|
19 |
{ |
|
20 |
/** @var LineRepository */ |
|
21 |
private $lineRepository; |
|
22 | ||
23 |
public function __construct(LineRepository $lineRepository) |
|
24 |
{ |
|
25 |
$this->lineRepository = $lineRepository; |
|
26 | ||
27 |
parent::__construct(); |
|
28 |
} |
|
29 | ||
30 |
/** |
|
31 |
* Abstraktní metoda, slouží k nastavení primárního klíče a nastavení datasource |
|
32 |
* 1. $this->setPrimaryKey(); |
|
33 |
* 2. $this->setDataSource(); |
|
34 |
* |
|
35 |
* @throws DataGridException |
|
36 |
*/ |
|
37 |
public function init() |
|
38 |
{ |
|
39 |
$this->setPrimaryKey(LineRepository::COLUMN_ID); |
|
40 |
$this->setDataSource($this->lineRepository->findAll()); |
|
41 |
} |
|
42 | ||
43 |
/** |
|
44 |
* Definice sloupečků, akcí, vyhledávácích filtrů gridu |
|
45 |
* |
|
46 |
* @throws DataGridException |
|
47 |
*/ |
|
48 |
public function define() |
|
49 |
{ |
|
50 |
$this->addColumnNumber(LineRepository::COLUMN_ID, "ID"); |
|
51 |
$this->addColumnText(LineRepository::COLUMN_TRANSLITERATION, "Transliterace"); |
|
52 |
$this->addFilterText(LineRepository::COLUMN_TRANSLITERATION, "Transliterace"); |
|
53 | ||
54 |
$this->addAction(LineRepository::COLUMN_TRANSLITERATION, "Smazat"); |
|
55 |
} |
|
56 |
} |
|
57 | ||
58 |
interface IExampleGirdFactory |
|
59 |
{ |
|
60 |
/** |
|
61 |
* Funkce create je implementována již v předkovi |
|
62 |
* |
|
63 |
* @return ExampleGrid |
|
64 |
*/ |
|
65 |
public function create(); |
|
66 |
} |
app/config/components.neon | ||
---|---|---|
1 |
services: |
|
2 |
# Gridy |
|
3 |
- App\Components\IExampleGirdFactory |
|
4 | ||
5 |
# Formuláře |
app/presenters/HomepagePresenter.php | ||
---|---|---|
2 | 2 | |
3 | 3 |
namespace App\Presenters; |
4 | 4 | |
5 |
use App\Components\IExampleGirdFactory; |
|
5 | 6 |
use Nette; |
6 | 7 | |
7 | 8 | |
8 | 9 |
final class HomepagePresenter extends Nette\Application\UI\Presenter |
9 | 10 |
{ |
11 |
/** @var IExampleGirdFactory */ |
|
12 |
private $exampleGridFactory; |
|
13 | ||
14 |
public function __construct(IExampleGirdFactory $exampleGridFactory) |
|
15 |
{ |
|
16 |
parent::__construct(); |
|
17 | ||
18 |
$this->exampleGridFactory = $exampleGridFactory; |
|
19 |
} |
|
20 | ||
21 |
public function actionDefault(){ |
|
22 | ||
23 |
} |
|
24 | ||
25 |
public function createComponentDataGrid(){ |
|
26 |
return $this->exampleGridFactory->create(); |
|
27 |
} |
|
10 | 28 |
} |
app/presenters/templates/@layout.latte | ||
---|---|---|
1 | 1 |
<!DOCTYPE html> |
2 | 2 |
<html> |
3 | 3 |
<head> |
4 |
<meta charset="utf-8">
|
|
5 |
<meta name="viewport" content="width=device-width">
|
|
4 |
<meta charset="utf-8">
|
|
5 |
<meta name="viewport" content="width=device-width">
|
|
6 | 6 | |
7 |
<title>{ifset title}{include title|stripHtml} | {/ifset}Nette Web</title> |
|
7 |
<title>{ifset title}{include title|stripHtml} | {/ifset}Nette Web</title> |
|
8 | ||
9 |
<!-- jQuery --> |
|
10 |
<script |
|
11 |
src="https://code.jquery.com/jquery-3.3.1.min.js" |
|
12 |
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" |
|
13 |
crossorigin="anonymous"></script> |
|
14 | ||
15 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.js" |
|
16 |
integrity="sha256-wqAoCRn9//AnHSl4qbXVhqdvmgFQqN5Elqp4Eb2wOXA=" crossorigin="anonymous"></script> |
|
17 | ||
18 |
<!-- Bootstrap CDN --> |
|
19 |
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" |
|
20 |
integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous"> |
|
21 |
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" |
|
22 |
integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" |
|
23 |
crossorigin="anonymous"></script> |
|
24 | ||
25 |
<!-- Bootstrap Select --> |
|
26 |
<link rel="stylesheet" |
|
27 |
href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.4/css/bootstrap-select.min.css"> |
|
28 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.4/js/bootstrap-select.min.js"></script> |
|
29 | ||
30 |
<!-- Bootstrap Datepicker --> |
|
31 |
<link rel="stylesheet" |
|
32 |
href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker3.min.css" |
|
33 |
integrity="sha256-mlKJFBS1jbZwwDrZD1ApO7YFS6MA1XDN37jZ9GDFC64=" crossorigin="anonymous"/> |
|
34 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/js/bootstrap-datepicker.min.js" |
|
35 |
integrity="sha256-tW5LzEC7QjhG0CiAvxlseMTs2qJS7u3DRPauDjFJ3zo=" crossorigin="anonymous"></script> |
|
36 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/locales/bootstrap-datepicker.cs.min.js" |
|
37 |
integrity="sha256-pbW7ult8QcDlimj+JQplrsCieqCvQ/8VGr7ZdTuev8c=" crossorigin="anonymous"></script> |
|
38 | ||
39 |
<!-- Font awesome --> |
|
40 |
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" |
|
41 |
integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous"> |
|
42 | ||
43 | ||
44 |
<script src="https://nette.github.io/resources/js/netteForms.min.js"></script> |
|
45 |
<script src="{$basePath}/js/nette.ajax.js"></script> |
|
8 | 46 |
</head> |
9 | 47 | |
10 | 48 |
<body> |
11 |
<div n:foreach="$flashes as $flash" n:class="flash, $flash->type">{$flash->message}</div>
|
|
49 |
<div n:foreach="$flashes as $flash" n:class="flash, $flash->type">{$flash->message}</div> |
|
12 | 50 | |
13 |
{include content}
|
|
51 |
{include content} |
|
14 | 52 | |
15 |
{block scripts} |
|
16 |
<script src="https://nette.github.io/resources/js/netteForms.min.js"></script> |
|
17 |
{/block} |
|
53 |
{block scripts} |
|
54 |
<script> |
|
55 |
$(function () { |
|
56 |
$.nette.init(); |
|
57 |
}); |
|
58 |
</script> |
|
59 |
{/block} |
|
18 | 60 |
</body> |
19 | 61 |
</html> |
app/presenters/templates/Homepage/default.latte | ||
---|---|---|
1 | 1 |
{* This is the welcome page, you can delete it *} |
2 | 2 | |
3 | 3 |
{block content} |
4 |
<div id="banner"> |
|
5 |
<h1 n:block=title>Congratulations!</h1> |
|
6 |
</div> |
|
7 | 4 | |
8 |
<div id="content"> |
|
9 |
<h2>You have successfully created your <a href="https://nette.org">Nette</a> Web project.</h2> |
|
10 | ||
11 |
<p><img src="data:image/png;base64,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" alt=""> |
|
12 |
If you are exploring Nette for the first time, you should read the |
|
13 |
<a href="https://doc.nette.org/quickstart">Quick Start</a>, <a href="https://doc.nette.org">documentation</a>, |
|
14 |
<a href="https://pla.nette.org">tutorials</a> and <a href="https://forum.nette.org">forum</a>.</p> |
|
15 | ||
16 |
<h2>We hope you enjoy Nette!</h2> |
|
17 |
</div> |
|
18 | ||
19 |
<style> |
|
20 |
html { font: normal 18px/1.3 Georgia, "New York CE", utopia, serif; color: #666; -webkit-text-stroke: 1px rgba(0,0,0,0); overflow-y: scroll; } |
|
21 |
body { background: #3484d2; color: #333; margin: 2em auto; padding: 0 .5em; max-width: 600px; min-width: 320px; } |
|
22 | ||
23 |
a { color: #006aeb; padding: 3px 1px; } |
|
24 |
a:hover, a:active, a:focus { background-color: #006aeb; text-decoration: none; color: white; } |
|
25 | ||
26 |
#banner { border-radius: 12px 12px 0 0; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAB5CAMAAADPursXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAGBQTFRFD1CRDkqFDTlmDkF1D06NDT1tDTNZDk2KEFWaDTZgDkiCDTtpDT5wDkZ/DTBVEFacEFOWD1KUDTRcDTFWDkV9DkR7DkN4DkByDTVeDC9TDThjDTxrDkeADkuIDTRbDC9SbsUaggAAAEdJREFUeNqkwYURgAAQA7DH3d3335LSKyxAYpf9vWCpnYbf01qcOdFVXc14w4BznNTjkQfsscAdU3b4wIh9fDVYc4zV8xZgAAYaCMI6vPgLAAAAAElFTkSuQmCC); } |
|
27 | ||
28 |
h1 { font: inherit; color: white; font-size: 50px; line-height: 121px; margin: 0; padding-left: 4%; background: url(https://files.nette.org/images/logo-nette@2.png) no-repeat 95%; background-size: 130px auto; text-shadow: 1px 1px 0 rgba(0, 0, 0, .9); } |
|
29 |
@media (max-width: 600px) { |
|
30 |
h1 { background: none; font-size: 40px; } |
|
31 |
} |
|
32 | ||
33 |
#content { background: white; border: 1px solid #eff4f7; border-radius: 0 0 12px 12px; padding: 10px 4%; overflow: hidden; } |
|
34 | ||
35 |
h2 { font: inherit; padding: 1.2em 0; margin: 0; } |
|
36 | ||
37 |
img { border: none; float: right; margin: 0 0 1em 3em; } |
|
38 |
</style> |
|
5 |
<div class="container"> |
|
6 |
<div class="row"> |
|
7 |
<div class="col-md-12"> |
|
8 |
{control dataGrid} |
|
9 |
</div> |
|
10 |
</div> |
|
11 |
</div> |
app/utils/datagrid/DataGrid.php | ||
---|---|---|
1 |
<?php |
|
2 | ||
3 |
namespace App\Utils\DataGrid; |
|
4 | ||
5 |
use Nette\ComponentModel\IContainer; |
|
6 |
use Nette\Database\Table\Selection; |
|
7 |
use Ublaboo\DataGrid\Column\ColumnDateTime; |
|
8 |
use Ublaboo\DataGrid\Column\ColumnNumber; |
|
9 |
use Ublaboo\DataGrid\Column\ColumnText; |
|
10 |
use Ublaboo\DataGrid\DataGrid as BaseDataGrid; |
|
11 |
use Ublaboo\DataGrid\Exception\DataGridException; |
|
12 |
use Ublaboo\DataGrid\Filter\FilterText; |
|
13 |
use Ublaboo\DataGrid\Localization\SimpleTranslator; |
|
14 | ||
15 |
/** |
|
16 |
* Třída DataGrid poskytuje DataGrid s českou lokalizací, šablonou pro Bootstrap 4 a vyhledáváním s použitím LIKE |
|
17 |
* @package App\Utils\DataGrid |
|
18 |
*/ |
|
19 |
abstract class DataGrid extends BaseDataGrid |
|
20 |
{ |
|
21 |
/** |
|
22 |
* DataGrid konstruktor. |
|
23 |
* @param IContainer|null $parent |
|
24 |
* @param null $name |
|
25 |
*/ |
|
26 |
public function __construct(IContainer $parent = null, $name = null) |
|
27 |
{ |
|
28 |
parent::__construct($parent, $name); |
|
29 | ||
30 |
$translator = new SimpleTranslator([ |
|
31 |
'ublaboo_datagrid.no_item_found_reset' => 'Žádné položky nenalezeny. Filtr můžete vynulovat', |
|
32 |
'ublaboo_datagrid.no_item_found' => 'Žádné položky nenalezeny.', |
|
33 |
'ublaboo_datagrid.here' => 'zde', |
|
34 |
'ublaboo_datagrid.items' => 'Položky', |
|
35 |
'ublaboo_datagrid.all' => 'všechny', |
|
36 |
'ublaboo_datagrid.from' => 'z', |
|
37 |
'ublaboo_datagrid.reset_filter' => 'Resetovat filtr', |
|
38 |
'ublaboo_datagrid.group_actions' => 'Hromadné akce', |
|
39 |
'ublaboo_datagrid.show_all_columns' => 'Zobrazit všechny sloupce', |
|
40 |
'ublaboo_datagrid.hide_column' => 'Skrýt sloupec', |
|
41 |
'ublaboo_datagrid.action' => 'Akce', |
|
42 |
'ublaboo_datagrid.previous' => 'Předchozí', |
|
43 |
'ublaboo_datagrid.next' => 'Další', |
|
44 |
'ublaboo_datagrid.choose' => 'Vyberte', |
|
45 |
'ublaboo_datagrid.execute' => 'Provést', |
|
46 |
'ublaboo_datagrid.show_default_columns' => 'Zobrazit výchozí sloupce', |
|
47 |
'ublaboo_datagrid.filter_submit_button' => 'Filtrovat', |
|
48 | ||
49 |
'Name' => 'Jméno', |
|
50 |
'Inserted' => 'Vloženo' |
|
51 |
]); |
|
52 | ||
53 |
$this->setTranslator($translator); |
|
54 | ||
55 |
$this->setTemplateFile(__DIR__ . '/templates/datagrid.latte'); |
|
56 | ||
57 |
$this->setColumnsHideable(); |
|
58 | ||
59 |
$this->setAutoSubmit(false); |
|
60 | ||
61 |
$this->setStrictSessionFilterValues(false); |
|
62 | ||
63 |
$this->init(); |
|
64 | ||
65 |
$this->define(); |
|
66 |
} |
|
67 | ||
68 |
/** |
|
69 |
* Abstraktní metoda, slouží k nastavení primárního klíče a nastavení datasource |
|
70 |
* 1. $this->setPrimaryKey(); |
|
71 |
* 2. $this->setDataSource(); |
|
72 |
* |
|
73 |
* @throws DataGridException |
|
74 |
*/ |
|
75 |
public abstract function init(); |
|
76 | ||
77 |
/** |
|
78 |
* Definice sloupečků, akcí, vyhledávácích filtrů gridu |
|
79 |
* |
|
80 |
* @throws DataGridException |
|
81 |
*/ |
|
82 |
public abstract function define(); |
|
83 | ||
84 |
/** |
|
85 |
* Vrací vytvořený datagrid - používáno v továrničkách |
|
86 |
* |
|
87 |
* @return $this |
|
88 |
*/ |
|
89 |
public function create() |
|
90 |
{ |
|
91 |
return $this; |
|
92 |
} |
|
93 | ||
94 |
/** |
|
95 |
* Nastavuje každý sloupeček řaditelný jako výchozí nastavení |
|
96 |
* |
|
97 |
* @param string $key : column name |
|
98 |
* @param string $name : filter label |
|
99 |
* @param null $column |
|
100 |
* @return null|ColumnText |
|
101 |
*/ |
|
102 |
public function addColumnText($key, $name, $column = null): ColumnText |
|
103 |
{ |
|
104 |
$column = parent::addColumnText($key, $name, $column); |
|
105 |
$column->setSortable(); |
|
106 | ||
107 |
return $column; |
|
108 |
} |
|
109 | ||
110 |
/** |
|
111 |
* Nastavuje každý sloupeček řaditelný jako výchozí nastavení |
|
112 |
* |
|
113 |
* @param string $key : column name |
|
114 |
* @param string $name : filter label |
|
115 |
* @param null $column |
|
116 |
* @return ColumnNumber |
|
117 |
*/ |
|
118 |
public function addColumnNumber($key, $name, $column = null): ColumnNumber |
|
119 |
{ |
|
120 |
$column = parent::addColumnNumber($key, $name, $column); |
|
121 |
$column->setSortable(); |
|
122 | ||
123 |
return $column; |
|
124 |
} |
|
125 | ||
126 |
/** |
|
127 |
* Nastavuje každý sloupeček řaditelný jako výchozí nastavení |
|
128 |
* |
|
129 |
* @param string $key : column name |
|
130 |
* @param string $name : filter label |
|
131 |
* @param null $column |
|
132 |
* @return ColumnDateTime |
|
133 |
*/ |
|
134 |
public function addColumnDateTime($key, $name, $column = null): ColumnDateTime |
|
135 |
{ |
|
136 |
$column = parent::addColumnDateTime($key, $name, $column); |
|
137 |
$column->setSortable(); |
|
138 | ||
139 |
return $column; |
|
140 |
} |
|
141 | ||
142 |
/** |
|
143 |
* Umožňění filtrování sloupečků s textem podle jeho jednotlivých částí pomocí LIKE SQL commandu |
|
144 |
* |
|
145 |
* @param string $key : column name |
|
146 |
* @param string $name : filter label |
|
147 |
* @param null $columns |
|
148 |
* @return FilterText |
|
149 |
* @throws DataGridException |
|
150 |
*/ |
|
151 |
public function addFilterText($key, $name, $columns = null): FilterText |
|
152 |
{ |
|
153 |
$filterText = parent::addFilterText($key, $name, $columns); |
|
154 | ||
155 |
$filter = parent::getFilter($key); |
|
156 | ||
157 |
$filter->setCondition(function ($selection, $value) use ($key) |
|
158 |
{ |
|
159 |
/** @var Selection $selection */ |
|
160 |
$selection->where($key . ' LIKE', '%' . $value . '%'); |
|
161 |
}); |
|
162 | ||
163 |
return $filterText; |
|
164 |
} |
|
165 |
} |
app/utils/datagrid/templates/column_multi_action.latte | ||
---|---|---|
1 |
{** |
|
2 |
* @param $multi_action Ublaboo\DataGrid\Column\MultiAction |
|
3 |
*} |
|
4 | ||
5 |
<div class="dropdown"> |
|
6 |
{$multi_action->renderButton()|noescape} |
|
7 |
<ul class="dropdown-menu"> |
|
8 |
<li n:foreach="$multi_action->getActions() as $actionKey => $action"> |
|
9 |
{continueIf !$multi_action->testRowCondition($actionKey, $row)} |
|
10 | ||
11 |
{if $action->hasTemplate()} |
|
12 |
{include $action->getTemplate(), item => $row->getItem(), (expand) $action->getTemplateVariables(), row => $row} |
|
13 |
{else} |
|
14 |
{$action->render($row)|noescape} |
|
15 |
{/if} |
|
16 |
</li> |
|
17 |
</ul> |
|
18 |
</div> |
app/utils/datagrid/templates/column_status.latte | ||
---|---|---|
1 |
{** |
|
2 |
* @param $row Ublaboo\DataGrid\Row |
|
3 |
* @param $status Ublaboo\DataGrid\Column\ColumnStatus |
|
4 |
*} |
|
5 | ||
6 |
{var $active_option = $status->getCurrentOption($row)} |
|
7 | ||
8 |
<div class="dropdown"> |
|
9 |
{if $active_option} |
|
10 |
<button class="dropdown-toggle {$active_option->getClass()} {$active_option->getClassSecondary()}" type="button" data-toggle="dropdown"> |
|
11 |
{if $active_option->getIcon()}<i class="{$icon_prefix}{$active_option->getIcon()}"></i> {/if} |
|
12 |
{$active_option->getText()|translate} <i n:if="$status->hasCaret()" class="caret"></i> |
|
13 |
</button> |
|
14 |
{else} |
|
15 |
{$row->getValue($status->getColumn())} |
|
16 |
{/if} |
|
17 |
<ul class="dropdown-menu"> |
|
18 |
<li n:foreach="$status->getOptions() as $option"> |
|
19 |
<a class="{$option->getClassInDropdown()}" n:href="changeStatus!, id => $row->getId(), key => $status->getKey(), value => $option->getValue()"> |
|
20 |
{if $option->getIconSecondary()}<i class="datagrid-column-status-option-icon {$icon_prefix}{$option->getIconSecondary()}"></i> {/if} |
|
21 |
{$option->getText()|translate} |
|
22 |
</a> |
|
23 |
</li> |
|
24 |
</ul> |
|
25 |
</div> |
app/utils/datagrid/templates/datagrid.latte | ||
---|---|---|
1 |
{** |
|
2 |
* @param Column[] $columns Available columns |
|
3 |
* @param Action[] $actions Available actions |
|
4 |
* @param Export[] $exports Available exports |
|
5 |
* @param Filter[] $filters Available filters |
|
6 |
* @param ToolBarButton[] $toolbar_buttons Available toolbar_buttons |
|
7 |
* @param Form $filter Workaround for latte snippets |
|
8 |
* @param Row[] $rows List of rows (each contain a item from data source) |
|
9 |
* @param DataGrid $control Parent (DataGrid) |
|
10 |
* @param string $original_template Original template file path |
|
11 |
* @param string $icon_prefix Icon prefix (fa fa-) |
|
12 |
* @param array $columns_visibility What columns are visible |
|
13 |
* @param InlineEdit|null $inlineEdit Inline editing data |
|
14 |
* @param InlineEdit|null $inlineAdd Inline add data |
|
15 |
*} |
|
16 | ||
17 |
<div class="datagrid datagrid-{$control->getName()}" data-refresh-state="{link refreshState!}"> |
|
18 |
{** |
|
19 |
* Own data |
|
20 |
*} |
|
21 |
<div n:snippet="grid"> |
|
22 |
{snippetArea gridSnippets} |
|
23 |
{form filter, class => 'ajax'} |
|
24 |
{** |
|
25 |
* Filter form |
|
26 |
*} |
|
27 |
{if $control->hasOuterFilterRendering()} |
|
28 |
{block outer-filters} |
|
29 |
<div class="row text-right datagrid-collapse-filters-button-row" n:if="$control->hasCollapsibleOuterFilters()"> |
|
30 |
<div class="col-sm-12"> |
|
31 |
<button class="btn btn-xs btn-primary active" type="button" data-toggle="collapse" data-target="#datagrid-{$control->getName()}-row-filters"> |
|
32 |
<i n:block = "icon-filter" class="{$icon_prefix}filter"></i> {='ublaboo_datagrid.show_filter'|translate} |
|
33 |
</button> |
|
34 |
</div> |
|
35 |
</div> |
|
36 | ||
37 |
{if $control->hasCollapsibleOuterFilters() && !$filter_active} |
|
38 |
{var $filter_row_class = 'row-filters collapse'} |
|
39 |
{elseif $filter_active} |
|
40 |
{var $filter_row_class = 'row-filters collapse in'} |
|
41 |
{else} |
|
42 |
{var $filter_row_class = 'row-filters'} |
|
43 |
{/if} |
|
44 |
<div class="{$filter_row_class}" id="datagrid-{$control->getName()}-row-filters"> |
|
45 |
<div class="row"> |
|
46 |
{var $i = 0} |
|
47 |
{var $filter_columns_class = 'col-sm-' . (12 / $control->getOuterFilterColumnsCount())} |
|
48 |
<div class="datagrid-row-outer-filters-group {$filter_columns_class}" n:foreach="$filters as $f"> |
|
49 |
{** |
|
50 |
* Each fitler is rendered separately in its own template |
|
51 |
*} |
|
52 |
{var $filter_block = 'filter-' . $f->getKey()} |
|
53 |
{var $filter_type_block = 'filtertype-' . $f->getType()} |
|
54 | ||
55 |
{ifset #$filter_block} |
|
56 |
{include #$filter_block, filter => $f, input => $form['filter'][$f->getKey()], outer => TRUE} |
|
57 |
{else} |
|
58 |
{ifset #$filter_type_block} |
|
59 |
{include #$filter_type_block, filter => $f, input => $form['filter'][$f->getKey()], outer => TRUE} |
|
60 |
{else} |
|
61 |
{include $f->getTemplate(), filter => $f, input => $form['filter'][$f->getKey()], outer => TRUE} |
|
62 |
{/ifset} |
|
63 |
{/ifset} |
|
64 |
{var $i = $i+1} |
|
65 |
</div> |
|
66 |
<div class="col-sm-12" n:if="!$control->hasAutoSubmit()"> |
|
67 |
<div class="text-right datagrid-manual-submit"> |
|
68 |
{input $filter['filter']['submit']} |
|
69 |
</div> |
|
70 |
</div> |
|
71 |
</div> |
|
72 |
</div> |
|
73 |
{/block} |
|
74 |
{/if} |
|
75 |
<table class="{block table-class}table table-hover table-striped table-bordered table-sm{/block}" n:snippet="table" n:block="data"> |
|
76 |
<thead n:block="header"> |
|
77 |
<tr class="row-group-actions" n:if="$hasGroupActions || $exports || $toolbar_buttons || $control->canHideColumns() || $inlineAdd" n:block="group-actions"> |
|
78 |
<th colspan="{$control->getColumnsCount()}" class="ublaboo-datagrid-th-form-inline"> |
|
79 |
{if $hasGroupActions} |
|
80 |
{block group_actions} |
|
81 |
{='ublaboo_datagrid.group_actions'|translate}: |
|
82 |
{foreach $filter['group_action']->getControls() as $form_control} |
|
83 |
{if $form_control instanceof \Nette\Forms\Controls\SubmitButton} |
|
84 |
{input $form_control, class => 'btn btn-primary btn-sm', style => 'display:none'} |
|
85 |
{elseif $form_control->getName() == 'group_action'} |
|
86 |
{input $form_control, class => 'form-control input-sm form-control-sm', disabled => TRUE} |
|
87 |
{else} |
|
88 |
{input $form_control, style => 'display:none'} |
|
89 |
{/if} |
|
90 |
{/foreach} |
|
91 |
{if $control->shouldShowSelectedRowsCount()} |
|
92 |
<span class="datagrid-selected-rows-count"></span> |
|
93 |
{/if} |
|
94 |
{/block} |
|
95 |
{/if} |
|
96 | ||
97 |
<div class="datagrid-toolbar" n:if="$control->canHideColumns() || $inlineAdd || $exports || $toolbar_buttons"> |
|
98 |
<span n:if="$toolbar_buttons"> |
|
99 |
{foreach $toolbar_buttons as $toolbar_button}{$toolbar_button->renderButton()}{/foreach} |
|
100 |
</span> |
|
101 | ||
102 |
<span class="datagrid-exports" n:if="$exports" n:snippet="exports" n:block="exports"> |
|
103 |
{foreach $exports as $export}{$export->render()}{/foreach} |
|
104 |
</span> |
|
105 | ||
106 |
<div class="datagrid-settings" n:block="settings" n:if="$control->canHideColumns() || $inlineAdd"> |
|
107 |
{** |
|
108 |
* Inline add |
|
109 |
*} |
|
110 |
{if $inlineAdd} |
|
111 |
{$inlineAdd->renderButtonAdd()} |
|
112 |
{/if} |
|
113 | ||
114 |
{** |
|
115 |
* Hideable columns |
|
116 |
*} |
|
117 |
<div class="btn-group"> |
|
118 |
<button type="button" class="btn btn-xs btn-default btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" n:if="$control->canHideColumns()"> |
|
119 |
<i n:block = "icon-gear" class="{$icon_prefix}cog"></i> |
|
120 |
</button> |
|
121 |
<ul class="dropdown-menu dropdown-menu-right dropdown-menu--grid"> |
|
122 |
<li n:foreach="$columns_visibility as $v_key => $visibility"> |
|
123 |
{if $visibility['visible']} |
|
124 |
<a n:href="hideColumn!, column => $v_key" class="ajax dropdown-item"> |
|
125 |
<i n:block = "icon-checked" class="{$icon_prefix}check-square"></i> |
|
126 |
{include #column-header, column => $visibility['column']} |
|
127 |
</a> |
|
128 |
{else} |
|
129 |
<a n:href="showColumn!, column => $v_key" class="ajax dropdown-item"> |
|
130 |
<i n:block = "icon-unchecked" class="{$icon_prefix}square"></i> |
|
131 |
{include #column-header, column => $visibility['column']} |
|
132 |
</a> |
|
133 |
{/if} |
|
134 |
</li> |
|
135 |
<li role="separator" class="divider dropdown-divider"></li> |
|
136 |
<li> |
|
137 |
<a n:href="showAllColumns!" class="ajax dropdown-item"><i n:block = "icon-eye" class="{$icon_prefix}eye"></i> {='ublaboo_datagrid.show_all_columns'|translate}</a> |
|
138 |
</li> |
|
139 |
<li n:if="$control->hasSomeColumnDefaultHide()"> |
|
140 |
<a n:href="showDefaultColumns!" class="ajax dropdown-item"><i n:block = "icon-repeat" class="{$icon_prefix}redo"></i> {='ublaboo_datagrid.show_default_columns'|translate}</a> |
|
141 |
</li> |
|
142 |
</ul> |
|
143 |
</div> |
|
144 |
</div> |
|
145 |
</div> |
|
146 |
</th> |
|
147 |
</tr> |
|
148 |
<tr n:block="header-column-row"> |
|
149 |
<th n:snippet="thead-group-action" n:if="$hasGroupActions" n:attr="'rowspan=2' => !empty($filters) && !$control->hasOuterFilterRendering()" class="col-checkbox"> |
|
150 |
<input n:if="$hasGroupActionOnRows" n:class="$control->useHappyComponents() ? 'happy gray-border' , primary" name="{$control->getName()|lower}-toggle-all" type="checkbox" data-check="{$control->getName()}" data-check-all="{$control->getName()}"> |
|
151 |
</th> |
|
152 |
{foreach $columns as $key => $column} |
|
153 |
{var $th = $column->getElementForRender('th', $key)} |
|
154 |
{$th->startTag()|noescape} |
|
155 |
{var $col_header = 'col-' . $key . '-header'} |
|
156 | ||
157 |
{** |
|
158 |
* Column header can be defined also with block {col-<key>-header} |
|
159 |
*} |
|
160 |
{ifset #$col_header} |
|
161 |
{include #$col_header, column => $column} |
|
162 |
{else} |
|
163 |
{if $column->isSortable()} |
|
164 |
<a n:class="$column->isSortedBy() ? 'sort' : '', 'ajax', 'success'" href="{link sort!, sort => $control->getSortNext($column)}" id="datagrid-sort-{$key}"> |
|
165 |
{include #column-header, column => $column} |
|
166 | ||
167 |
{if $column->isSortedBy()} |
|
168 |
{if $column->isSortAsc()} |
|
169 |
<i n:block="icon-sort-up" class="{$icon_prefix}caret-up"></i> |
|
170 |
{else} |
|
171 |
<i n:block="icon-sort-down" class="{$icon_prefix}caret-down"></i> |
|
172 |
{/if} |
|
173 |
{else} |
|
174 |
<i n:block="icon-sort" class="{$icon_prefix}sort"></i> |
|
175 |
{/if} |
|
176 |
</a> |
|
177 |
{else} |
|
178 |
{include #column-header, column => $column} |
|
179 |
{/if} |
|
180 |
{/ifset} |
|
181 | ||
182 |
<div class="datagrid-column-header-additions"> |
|
183 |
<div class="btn-group column-settings-menu" n:if="$control->canHideColumns()"> |
|
184 |
<a class="dropdown-toggle success" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" href=""> |
|
185 |
<i n:block="icon-caret-down" class="{$icon_prefix}caret-down"></i> |
|
186 |
</a> |
|
187 |
<ul class="dropdown-menu dropdown-menu--grid"> |
|
188 |
<li> |
|
189 |
<a n:href="hideColumn!, column => $key" class="ajax dropdown-item"> |
|
190 |
<i n:block = "icon-eye-slash" class="{$icon_prefix}eye-slash"></i> {='ublaboo_datagrid.hide_column'|translate}</a> |
|
191 |
</li> |
|
192 |
</ul> |
|
193 |
</div> |
|
194 | ||
195 |
{if $control->hasColumnReset()} |
|
196 |
<a data-datagrid-reset-filter-by-column="{$key}" n:href="resetColumnFilter!, key => $key" n:class="isset($filters[$key]) && $filters[$key]->isValueSet() ? '' : 'hidden', 'ajax'" title="{='ublaboo_datagrid.reset_filter'|translate}"> |
|
197 |
<i n:block="icon-remove" class="{$icon_prefix}remove"></i> |
|
198 |
</a> |
|
199 |
{/if} |
|
200 |
</div> |
|
201 |
{$th->endTag()|noescape} |
|
202 |
{/foreach} |
|
203 |
<th n:if="$actions || $control->isSortable() || $items_detail || $inlineEdit || $inlineAdd" class="col-action text-center"> |
|
204 |
{='ublaboo_datagrid.action'|translate} |
|
205 |
</th> |
|
206 |
</tr> |
|
207 |
<tr n:block="header-filters" n:if="!empty($filters) && !$control->hasOuterFilterRendering()"> |
|
208 |
{foreach $columns as $key => $column} |
|
209 |
{var $th = $column->getElementForRender('th', $key)} |
|
210 |
{$th->startTag()|noescape} |
|
211 |
{var $col_header = 'col-filter-' . $key . '-header'} |
|
212 |
{if !$control->hasOuterFilterRendering() && isset($filters[$key])} |
|
213 |
{var $i = $filter['filter'][$key]} |
|
214 | ||
215 |
{var $filter_block = 'filter-' . $filters[$key]->getKey()} |
|
216 |
{var $filter_type_block = 'filtertype-' . $filters[$key]->getType()} |
|
217 | ||
218 |
{ifset #$filter_block} |
|
219 |
{include #$filter_block, filter => $filters[$key], input => $i, outer => FALSE} |
|
220 |
{else} |
|
221 |
{ifset #$filter_type_block} |
|
222 |
{include #$filter_type_block, filter => $filters[$key], input => $i, outer => FALSE} |
|
223 |
{else} |
|
224 |
{include $filters[$key]->getTemplate(), filter => $filters[$key], input => $i, outer => FALSE} |
|
225 |
{/ifset} |
|
226 |
{/ifset} |
|
227 | ||
228 |
{/if} |
|
229 |
{$th->endTag()|noescape} |
|
230 |
{/foreach} |
|
231 |
<th n:if="$actions || $control->isSortable() || $items_detail || $inlineEdit || $inlineAdd" class="col-action text-center"> |
|
232 |
{if !$control->hasAutoSubmit() && !$control->hasOuterFilterRendering()} |
|
233 |
{input $filter['filter']['submit']} |
|
234 |
{/if} |
|
235 |
</th> |
|
236 |
</tr> |
|
237 |
</thead> |
|
238 | ||
239 |
{block tbody} |
|
240 |
<tbody n:snippet="tbody" {if $control->isSortable()}data-sortable data-sortable-url="{plink $control->getSortableHandler()}" data-sortable-parent-path="{$control->getSortableParentPath()}"{/}> |
|
241 |
{snippetArea items} |
|
242 |
{if $inlineAdd && $inlineAdd->isPositionTop()} |
|
243 |
{include inlineAddRow, columns => $columns} |
|
244 |
{/if} |
|
245 | ||
246 |
{foreach $rows as $row} |
|
247 |
{var $item = $row->getItem()} |
|
248 | ||
249 |
{if !isset($toggle_detail)} |
|
250 |
{if $inlineEdit && $inlineEdit->getItemId() == $row->getId()} |
|
251 |
{php $inlineEdit->onSetDefaults($filter['inline_edit'], $item); } |
|
252 | ||
253 |
<tr data-id="{$row->getId()}" n:snippet="item-{$row->getId()}" n:class="$row->getControlClass()"> |
|
254 |
<td n:if="$hasGroupActions" class="col-checkbox"></td> |
|
255 | ||
256 |
{foreach $columns as $key => $column} |
|
257 |
{var $col = 'col-' . $key} |
|
258 | ||
259 |
{var $td = $column->getElementForRender('td', $key, $row)} |
|
260 |
{var $td->class[] = 'datagrid-inline-edit'} |
|
261 |
{$td->startTag()|noescape} |
|
262 |
{if isset($filter['inline_edit'][$key])} |
|
263 |
{input $filter['inline_edit'][$key]} |
|
264 |
{elseif $inlineEdit->showNonEditingColumns()} |
|
265 |
{include column-value, column => $column, row => $row, key => $key} |
|
266 |
{/if} |
|
267 |
{$td->endTag()|noescape} |
|
268 |
{/foreach} |
|
269 | ||
270 |
<td class="col-action col-action-inline-edit"> |
|
271 |
{input $filter['inline_edit']['cancel'], class => 'btn btn-xs btn-danger'} |
|
272 |
{input $filter['inline_edit']['submit'], class => 'btn btn-xs btn-primary'} |
|
273 |
{input $filter['inline_edit']['_id']} |
|
274 |
{input $filter['inline_edit']['_primary_where_column']} |
|
275 |
</td> |
|
276 |
</tr> |
|
277 |
{else} |
|
278 |
<tr data-id="{$row->getId()}" n:snippet="item-{$row->getId()}" n:class="$row->getControlClass()"> |
|
279 |
<td n:if="$hasGroupActions" class="col-checkbox"> |
|
280 |
{if $row->hasGroupAction()} |
|
281 |
<input n:class="$control->useHappyComponents() ? 'happy gray-border' , primary" type="checkbox" data-check="{$control->getName()}" data-check-all-{$control->getName()|noescape} name="{$control->getName()|lower}_group_action_item[{$row->getId()}]"> |
|
282 |
{/if} |
|
283 |
</td> |
|
284 |
{foreach $columns as $key => $column} |
|
285 |
{php $column = $row->applyColumnCallback($key, clone $column)} |
|
286 | ||
287 |
{var $td = $column->getElementForRender('td', $key, $row)} |
|
288 |
{$td->startTag()|noescape} |
|
289 |
{include column-value, column => $column, row => $row, key => $key} |
|
290 |
{$td->endTag()|noescape} |
|
291 |
{/foreach} |
|
292 |
<td n:if="$actions || $control->isSortable() || $items_detail || $inlineEdit || $inlineAdd" class="col-action"> |
|
293 |
{foreach $actions as $key => $action} |
|
294 |
{if $row->hasAction($key)} |
|
295 |
{if $action->hasTemplate()} |
|
296 |
{include $action->getTemplate(), item => $item, (expand) $action->getTemplateVariables(), row => $row} |
|
297 |
{else} |
|
298 |
{$action->render($row)|noescape} |
|
299 |
{/if} |
|
300 |
{/if} |
|
301 |
{/foreach} |
|
302 |
<span class="handle-sort btn btn-xs btn-default btn-secondary" n:if="$control->isSortable()"> |
|
303 |
<i n:block = "icon-arrows-v" class="{$icon_prefix}arrows-v"></i> |
|
304 |
</span> |
|
305 |
{if $inlineEdit && $row->hasInlineEdit()} |
|
306 |
{$inlineEdit->renderButton($row)|noescape} |
|
307 |
{/if} |
|
308 |
{if $items_detail && $items_detail->shouldBeRendered($row)} |
|
309 |
{$items_detail->renderButton($row)|noescape} |
|
310 |
{/if} |
|
311 |
</td> |
|
312 |
</tr> |
|
313 |
{/if} |
|
314 |
{/if} |
|
315 | ||
316 |
{** |
|
317 |
* Item detail |
|
318 |
*} |
|
319 |
{if $items_detail && $items_detail->shouldBeRendered($row)} |
|
320 |
<tr class="row-item-detail item-detail-{$row->getId()}" n:snippet="item-{$row->getId()}-detail"> |
|
321 |
{if isset($toggle_detail) && $toggle_detail == $row->getId()} |
|
322 |
{var $item_detail_params = ['item' => $item, '_form' => $filter] + $items_detail->getTemplateVariables()} |
|
323 | ||
324 |
{if isset($filter['items_detail_form'])} |
|
325 |
{var $item_detail_params['items_detail_form'] = $filter['items_detail_form']} |
|
326 |
{/if} |
|
327 | ||
328 |
{ifset #detail} |
|
329 |
<td colspan="{$control->getColumnsCount()}"> |
|
330 |
<div class="item-detail-content"> |
|
331 |
{include #detail, (expand) $item_detail_params} |
|
332 |
</div> |
|
333 |
</td> |
|
334 |
{elseif $items_detail} |
|
335 |
<td colspan="{$control->getColumnsCount()}"> |
|
336 |
<div class="item-detail-content"> |
|
337 |
{if $items_detail->getType() == 'template'} |
|
338 |
{include $items_detail->getTemplate(), (expand) $item_detail_params} |
|
339 |
{else} |
|
340 |
{$items_detail->render($item)|noescape} |
|
341 |
{/if} |
|
342 |
</div> |
|
343 |
</td> |
|
344 |
{/ifset} |
|
345 |
{/if} |
|
346 |
</tr> |
|
347 |
<tr class="row-item-detail-helper"></tr> |
|
348 |
{/if} |
|
349 |
{/foreach} |
|
350 | ||
351 |
{if $inlineAdd && $inlineAdd->isPositionBottom()} |
|
352 |
{include inlineAddRow, columns => $columns} |
|
353 |
{/if} |
|
354 | ||
355 |
<tr class="datagrid-row-columns-summary" n:if="!empty($rows) && ($columnsSummary || $control->hasSomeAggregationFunction())" n:snippet="summary"> |
|
356 |
<td n:if="$hasGroupActions" class="col-checkbox"></td> |
|
357 | ||
358 |
{if $columnsSummary && $columnsSummary->someColumnsExist($columns)} |
|
359 |
{include columnsSummary, columns => $columns} |
|
360 |
{/if} |
|
361 | ||
362 |
{if $control->hasSomeAggregationFunction()} |
|
363 |
{include aggregationFunctions, columns => $columns} |
|
364 |
{/if} |
|
365 | ||
366 |
<td n:if="$actions || $control->isSortable() || $items_detail || $inlineEdit || $inlineAdd" class="col-action"></td> |
|
367 |
</tr> |
|
368 | ||
369 |
{block noItems} |
|
370 |
<tr n:if="!$rows"> |
|
371 |
<td colspan="{$control->getColumnsCount()}"> |
|
372 |
{if $filter_active} |
|
373 |
{='ublaboo_datagrid.no_item_found_reset'|translate} <a class="link ajax" n:href="resetFilter!">{='ublaboo_datagrid.here'|translate}</a>. |
|
374 |
{else} |
|
375 |
{='ublaboo_datagrid.no_item_found'|translate} |
|
376 |
{/if} |
|
377 |
</td> |
|
378 |
</tr> |
|
379 |
{/block} |
|
380 |
{/snippetArea} |
|
381 |
</tbody> |
|
382 |
{/block} |
|
383 |
{block tfoot} |
|
384 |
<tfoot n:snippet="pagination"> |
|
385 |
{if $control->isPaginated() || $filter_active} |
|
386 |
<tr n:block="pagination"> |
|
387 |
<td colspan="{$control->getColumnsCount()}" n:if="!$control->isTreeView()" class="row-grid-bottom"> |
|
388 |
<div class="col-items"> |
|
389 |
<small class="text-muted" n:if="$control->isPaginated()"> |
|
390 |
({var $paginator = $control['paginator']->getPaginator()} |
|
391 | ||
392 |
{if $control->getPerPage() === 'all'} |
|
393 |
{='ublaboo_datagrid.items'|translate}: {='ublaboo_datagrid.all'|translate} |
|
394 |
{else} |
|
395 |
{='ublaboo_datagrid.items'|translate}: {$paginator->getOffset() > 0 ? $paginator->getOffset() + 1 : ($paginator->getItemCount() > 0 ? 1 : 0)} - {sizeof($rows) + $paginator->getOffset()} |
|
396 |
{='ublaboo_datagrid.from'|translate} {$paginator->getItemCount()} |
|
397 |
{/if}) |
|
398 |
</small> |
|
399 |
</div> |
|
400 |
<div class="col-pagination text-center"> |
|
401 |
{** |
|
402 |
* Pagination |
|
403 |
*} |
|
404 |
{control paginator} |
|
405 |
</div> |
|
406 |
<div class="col-per-page text-right"> |
|
407 |
{** |
|
408 |
* Items per page form (display only beside paginated grido) |
|
409 |
*} |
|
410 |
<a n:if="$filter_active" n:href="resetFilter!" class="ajax btn btn-danger btn-sm reset-filter">{='ublaboo_datagrid.reset_filter'|translate}</a> |
|
411 |
{if $control->isPaginated()} |
|
412 |
{input $filter['per_page'], data-autosubmit-per-page => TRUE, class => 'form-control input-sm form-control-sm'} |
|
413 |
{input $filter['per_page_submit'], class => 'datagrid-per-page-submit'} |
|
414 |
{/if} |
|
415 |
</div> |
|
416 |
</td> |
|
417 |
</tr> |
|
418 |
{/if} |
|
419 |
</tfoot> |
|
420 |
{/block} |
|
421 |
</table> |
|
422 |
{/form} |
|
423 |
{/snippetArea} |
|
424 |
</div> |
|
425 |
</div> |
|
426 | ||
427 | ||
428 |
{define inlineAddRow} |
|
429 |
{php $inlineAdd->onSetDefaults($filter['inline_add']); } |
|
430 | ||
431 |
<tr class="datagrid-row-inline-add datagrid-row-inline-add-hidden"> |
|
432 |
<td n:if="$hasGroupActions" class="col-checkbox"></td> |
|
433 | ||
434 |
{foreach $columns as $key => $column} |
|
435 |
{var $col = 'col-' . $key} |
|
436 | ||
437 |
{var $td = clone $column->getElementForRender('td', $key)} |
|
438 |
{var $td->class[] = 'datagrid-inline-edit'} |
|
439 |
{$td->startTag()|noescape} |
|
440 |
{if isset($filter['inline_add'][$key])} |
|
441 |
{input $filter['inline_add'][$key]} |
|
442 |
{/if} |
|
443 |
{$td->endTag()|noescape} |
|
444 |
{/foreach} |
|
445 | ||
446 |
<td class="col-action col-action-inline-edit"> |
|
447 |
{input $filter['inline_add']['cancel']} |
|
448 |
{input $filter['inline_add']['submit']} |
|
449 |
</td> |
|
450 |
</tr> |
|
451 |
{/define} |
|
452 | ||
453 | ||
454 |
{define columnsSummary} |
|
455 | ||
456 |
{foreach $columns as $key => $column} |
|
457 |
{var $td = $column->getElementForRender('td', $key)} |
|
458 | ||
459 |
{$td->startTag()|noescape} |
|
460 |
{$columnsSummary->render($key)} |
|
461 |
{$td->endTag()|noescape} |
|
462 |
{/foreach} |
|
463 | ||
464 |
{/define} |
|
465 | ||
466 | ||
467 |
{define aggregationFunctions} |
|
468 | ||
469 |
{foreach $columns as $key => $column} |
|
470 |
{var $td = $column->getElementForRender('td', $key)} |
|
471 | ||
472 |
{$td->startTag()|noescape} |
|
473 |
{if $aggregation_functions} |
|
474 |
{ifset $aggregation_functions[$key]} |
|
475 |
{$aggregation_functions[$key]->renderResult()|noescape} |
|
476 |
{/ifset} |
|
477 |
{else} |
|
478 |
{$multiple_aggregation_function->renderResult($key)|noescape} |
|
479 |
{/if} |
|
480 |
{$td->endTag()|noescape} |
|
481 |
{/foreach} |
|
482 | ||
483 |
{/define} |
|
484 | ||
485 | ||
486 |
{define column-header} |
|
487 |
{if $column->isHeaderEscaped()} |
|
488 |
{if $column instanceof \Nette\Utils\Html || !$column->isTranslatableHeader()} |
|
489 |
{$column->getName()|noescape} |
|
490 |
{else} |
|
491 |
{$column->getName()|translate|noescape} |
|
492 |
{/if} |
|
493 |
{else} |
|
494 |
{if $column instanceof \Nette\Utils\Html || !$column->isTranslatableHeader()} |
|
495 |
{$column->getName()} |
|
496 |
{else} |
|
497 |
{$column->getName()|translate} |
|
498 |
{/if} |
|
499 |
{/if} |
|
500 |
{/define} |
|
501 | ||
502 | ||
503 |
{define column-value} |
|
504 |
{var $col = 'col-' . $key} |
|
505 |
{var $item = $row->getItem()} |
|
506 | ||
507 |
{if $column->hasTemplate()} |
|
508 |
{include $column->getTemplate(), row => $row, item => $item, (expand) $column->getTemplateVariables()} |
|
509 |
{else} |
|
510 |
{ifset #$col} |
|
511 |
{include #$col, item => $item} |
|
512 |
{else} |
|
513 |
{if $column->isTemplateEscaped()} |
|
514 |
{$column->render($row)} |
|
515 |
{else} |
|
516 |
{$column->render($row)|noescape} |
|
517 |
{/if} |
|
518 |
{/ifset} |
|
519 |
{/if} |
|
520 |
{/define} |
|
521 | ||
522 |
<link href="{$basePath}/css/datagrid.min.css" rel="stylesheet" type="text/css"> |
|
523 |
<link href="{$basePath}/css/datagrid-spinners.min.css" rel="stylesheet" type="text/css"> |
|
524 | ||
525 |
<script src="{$basePath}/js/datagrid.min.js"></script> |
|
526 |
<script src="{$basePath}/js/datagrid-instant-url-refresh.min.js"></script> |
|
527 |
<script src="{$basePath}/js/datagrid-spinners.min.js"></script> |
app/utils/datagrid/templates/datagrid_filter_date.latte | ||
---|---|---|
1 |
{** |
|
2 |
* @param Filter $filter |
|
3 |
* @param Nette\Forms\Controls\TextInput $input |
|
4 |
* @param string $icon_prefix Icon prefix (fa fa-) |
|
5 |
*} |
|
6 | ||
7 |
{if $outer} |
|
8 |
<div class="row"> |
|
9 |
{label $input class => 'col-sm-3 control-label' /} |
|
10 |
<div class="col-sm-9 form-inline"> |
|
11 |
<div class="input-group input-group-sm datagrid-input-group-full-width"> |
|
12 |
{input $input} |
|
13 |
<label n:name="$input" class="input-group-addon input-group-append"> |
|
14 |
<i class="input-group-text {$icon_prefix}calendar"></i> |
|
15 |
</label> |
|
16 |
</div> |
|
17 |
</div> |
|
18 |
</div> |
|
19 |
{else} |
|
20 |
<div class="form-inline"> |
|
21 |
<div class="input-group input-group-sm"> |
|
22 |
{input $input} |
|
23 |
<label n:name="$input" class="input-group-addon input-group-append"> |
|
24 |
<i class="input-group-text {$icon_prefix}calendar"></i> |
|
25 |
</label> |
|
26 |
</div> |
|
27 |
</div> |
|
28 |
{/if} |
|
29 | ||
30 |
app/utils/datagrid/templates/datagrid_filter_daterange.latte | ||
---|---|---|
1 |
{** |
|
2 |
* @param Filter $filter |
|
3 |
* @param Nette\Forms\Container $input |
|
4 |
* @param string $icon_prefix Icon prefix (fa fa-) |
|
5 |
*} |
|
6 | ||
7 |
{var $container = $input} |
|
8 | ||
9 |
{if $outer} |
|
10 |
<div class="row"> |
|
11 |
{label $container['from'], class => 'col-sm-3 control-label' /} |
|
12 |
<div class="col-sm-4 form-inline"> |
|
13 |
<div class="input-group input-group-sm"> |
|
14 |
{input $container['from']} |
|
15 |
<label n:name="$container['from']" class="input-group-addon input-group-append"> |
|
16 |
<i class="input-group-text {$icon_prefix}calendar"></i> |
|
17 |
</label> |
|
18 |
</div> |
|
19 |
</div> |
|
20 |
{label $container['to'], class => 'filter-range-delimiter col-sm-1 control-label' /} |
|
21 |
<div class="col-sm-4 form-inline"> |
|
22 |
<div class="input-group input-group-sm"> |
|
23 |
{input $container['to']} |
|
24 |
<label n:name="$container['to']" class="input-group-addon input-group-append"> |
|
25 |
<i class="input-group-text {$icon_prefix}calendar"></i> |
|
26 |
</label> |
|
27 |
</div> |
|
28 |
</div> |
|
29 |
</div> |
|
30 |
{else} |
|
31 |
<div class="datagrid-col-filter-date-range form-inline"> |
|
32 |
<div class="input-group input-group-sm"> |
|
33 |
{input $container['from']} |
|
34 |
<label n:name="$container['from']" class="input-group-addon input-group-append"> |
|
35 |
<i class="input-group-text {$icon_prefix}calendar"></i> |
|
36 |
</label> |
|
37 |
</div> |
|
38 | ||
39 |
<div class="input-group input-group-sm"> |
|
40 |
{input $container['to']} |
|
41 |
<label n:name="$container['to']" class="input-group-addon input-group-append"> |
|
42 |
<i class="input-group-text {$icon_prefix}calendar"></i> |
|
43 |
</label> |
|
44 |
</div> |
|
45 |
</div> |
|
46 |
{/if} |
app/utils/datagrid/templates/datagrid_filter_range.latte | ||
---|---|---|
1 |
{** |
|
2 |
* @param Filter $filter |
|
3 |
* @param Nette\Forms\Container $input |
|
4 |
*} |
|
5 | ||
6 |
{var $container = $input} |
|
7 | ||
8 |
{if $outer} |
|
9 |
<div class="row"> |
|
10 |
{label $container['from'], class => 'col-sm-3 control-label' /} |
|
11 |
<div class="col-sm-4"> |
|
12 |
{input $container['from']} |
|
13 |
</div> |
|
14 |
{label $container['to'], class => 'filter-range-delimiter col-sm-1 control-label' /} |
|
15 |
<div class="col-sm-4"> |
|
16 |
{input $container['to']} |
|
17 |
</div> |
|
18 |
</div> |
|
19 |
{else} |
|
20 |
<div class="datagrid-col-filter-range form-inline"> |
|
21 |
<div class="input-group"> |
|
22 |
{input $container['from']} |
|
23 | ||
24 |
<div class="input-group-addon datagrid-col-filter-datte-range-delimiter">-</div> |
|
25 | ||
26 |
{input $container['to']} |
|
27 |
</div> |
|
28 |
</div> |
|
29 |
{/if} |
app/utils/datagrid/templates/datagrid_filter_select.latte | ||
---|---|---|
1 |
{** |
|
2 |
* @param Filter $filter |
|
3 |
* @param Nette\Forms\Controls\SelectBox $input |
|
4 |
*} |
|
5 | ||
6 |
{if $outer} |
|
7 |
<div class="row"> |
|
8 |
{label $input class => 'col-sm-3 control-label' /} |
|
9 |
<div class="col-sm-9"> |
|
10 |
{input $input} |
|
11 |
</div> |
|
12 |
</div> |
|
13 |
{else} |
|
14 |
{input $input} |
|
15 |
{/if} |
app/utils/datagrid/templates/datagrid_filter_text.latte | ||
---|---|---|
1 |
{** |
|
2 |
* @param Filter $filter |
|
3 |
* @param Nette\Forms\Controls\TextInput $input |
|
4 |
*} |
|
5 | ||
6 |
{if $outer} |
|
7 |
<div class="row"> |
|
8 |
{label $input class => 'col-sm-3 control-label' /} |
|
9 |
<div class="col-sm-9"> |
|
10 |
{input $input} |
|
11 |
</div> |
|
12 |
</div> |
|
13 |
{else} |
|
14 |
{input $input} |
|
15 |
{/if} |
app/utils/datagrid/templates/datagrid_tree.latte | ||
---|---|---|
1 |
{** |
|
2 |
* @param array $columns Available columns |
|
3 |
* @param array $actions Available actions |
|
4 |
* @param array $exports Available exports |
|
5 |
* @param Row[] $rows List of rows (each contain a item from data source) |
|
6 |
* @param DataGrid $control Parent (DataGrid) |
|
7 |
* @param string $original_template Original template file path |
|
8 |
* @param string $icon_prefix Icon prefix (fa fa-) |
|
9 |
*} |
|
10 | ||
11 |
{extends $original_template} |
|
12 | ||
13 |
<div class="datagrid-tree-item-children datagrid-tree" n:snippet="table" n:block="data" {if $control->isSortable()}data-sortable-tree data-sortable-url="{plink $control->getSortableHandler()}" data-sortable-parent-path="{$control->getSortableParentPath()}"{/if}> |
|
14 |
{snippetArea items} |
|
15 |
<div class="datagrid-tree-item datagrid-tree-header" n:snippet="item-header"> |
|
16 |
<div class="datagrid-tree-item-content" data-has-children=""> |
|
17 |
<div class="datagrid-tree-item-left"> |
|
18 |
{foreach $columns as $key => $column} |
|
19 |
<strong>{$column->getName()|translate}</strong> |
|
20 |
{breakIf TRUE} |
|
21 |
{/foreach} |
|
22 |
</div> |
|
23 | ||
24 |
<div class="datagrid-tree-item-right"> |
|
25 |
<div class="datagrid-tree-item-right-columns"> |
|
26 |
{foreach $columns as $key => $column} |
|
27 |
{continueIf $iterator->isFirst()} |
|
28 |
<div class="datagrid-tree-item-right-columns-column col-{$column->getColumnName()} text-{$column->hasAlign() ? $column->getAlign() : 'left'}"> |
|
29 |
<strong>{$column->getName()|translate}</strong> |
|
30 |
</div> |
|
31 |
{/foreach} |
|
32 |
</div> |
|
33 |
<div class="datagrid-tree-item-right-actions" n:if="($actions || $control->isSortable()) && $rows"> |
|
34 |
<div class="datagrid-tree-item-right-actions-action"> |
|
35 |
{var $tmp_row = reset($rows)} |
|
36 | ||
37 |
{foreach $actions as $key => $action} |
|
38 |
{if $tmp_row->hasAction($key)} |
|
39 |
{if $action->hasTemplate()} |
|
40 |
{include $action->getTemplate(), item => $tmp_row->getItem(), (expand) $action->getTemplateVariables(), row => $tmp_row} |
|
41 |
{else} |
|
42 |
{$action->render($tmp_row)|noescape} |
|
43 |
{/if} |
|
44 |
{/if} |
|
45 |
{/foreach} |
|
46 | ||
47 |
<span class="handle-sort btn btn-xs btn-default btn-secondary" n:if="$control->isSortable()"> |
|
48 |
<i class="{$icon_prefix}arrows"></i> |
|
49 |
</span> |
|
50 |
</div> |
|
51 |
</div> |
|
52 |
</div> |
|
53 |
</div> |
|
54 |
</div> |
|
55 | ||
56 |
{foreach $rows as $row} |
|
57 |
{var $has_children = $control->hasTreeViewChildrenCallback() ? $control->treeViewChildrenCallback($row->getItem()) : $row->getValue($tree_view_has_children_column)} |
|
58 |
{var $item = $row->getItem()} |
|
59 | ||
60 |
<div n:class="$has_children ? has-children, 'datagrid-tree-item'" data-id="{$row->getId()}" n:snippet="item-{$row->getId()}"> |
|
61 |
<div n:class="datagrid-tree-item-content, $row->getControlClass()" data-id="{$row->getId()}" data-has-children="{$has_children ? true : false}"> |
|
62 |
<div class="datagrid-tree-item-left"> |
|
63 |
<a n:href="getChildren! parent => $row->getId()" data-toggle-tree="true" n:class="!$has_children ? hidden, 'chevron ajax'"> |
|
64 |
<i n:block="icon-chevron" class="{$icon_prefix}chevron-right"></i> |
|
65 |
</a> |
|
66 |
{foreach $columns as $key => $column} |
|
67 |
{var $col = 'col-' . $key} |
|
68 |
{php $column = $row->applyColumnCallback($key, clone $column)} |
|
69 | ||
70 |
{if $column->hasTemplate()} |
|
71 |
{include $column->getTemplate(), item => $item, (expand) $column->getTemplateVariables()} |
|
72 |
{else} |
|
73 |
{ifset #$col} |
|
74 |
{include #$col, item => $item} |
|
75 |
{else} |
|
76 |
{if $column->isTemplateEscaped()} |
|
77 |
{$column->render($row)} |
|
78 |
{else} |
|
79 |
{$column->render($row)|noescape} |
|
80 |
{/if} |
|
81 |
{/ifset} |
|
82 |
{/if} |
|
83 | ||
84 |
{breakIf TRUE} |
|
85 |
{/foreach} |
|
86 |
</div> |
|
87 |
<div class="datagrid-tree-item-right"> |
|
88 |
<div class="datagrid-tree-item-right-columns"> |
|
89 |
{foreach $columns as $key => $column} |
|
90 |
{continueIf $iterator->isFirst()} |
|
91 | ||
92 |
<div class="datagrid-tree-item-right-columns-column text-{$column->hasAlign() ? $column->getAlign() : 'left'}"> |
|
93 |
{var $col = 'col-' . $key} |
|
94 |
{php $column = $row->applyColumnCallback($key, clone $column)} |
|
95 | ||
96 |
{if $column->hasTemplate()} |
|
97 |
{include $column->getTemplate(), row => $row, item => $item, (expand) $column->getTemplateVariables()} |
|
98 |
{else} |
|
99 |
{ifset #$col} |
|
100 |
{include #$col, item => $item} |
|
101 |
{else} |
|
102 |
{if $column->isTemplateEscaped()} |
|
103 |
{$column->render($row)} |
|
104 |
{else} |
|
105 |
{$column->render($row)|noescape} |
|
106 |
{/if} |
|
107 |
{/ifset} |
|
108 |
{/if} |
|
109 |
</div> |
|
110 |
{/foreach} |
|
111 |
</div> |
|
112 |
<div class="datagrid-tree-item-right-actions"> |
|
113 |
<div class="datagrid-tree-item-right-actions-action"> |
|
114 |
{foreach $actions as $key => $action} |
|
115 |
{if $row->hasAction($key)} |
|
116 |
{if $action->hasTemplate()} |
|
117 |
{include $action->getTemplate(), item => $item, (expand) $action->getTemplateVariables(), row => $row} |
|
118 |
{else} |
|
119 |
{$action->render($row)|noescape} |
|
120 |
{/if} |
|
121 |
{/if} |
|
122 |
{/foreach} |
|
123 | ||
124 |
<span class="handle-sort btn btn-xs btn-default btn-secondary" n:if="$control->isSortable()"> |
|
125 |
<i n:block = "icon-arrows" class="{$icon_prefix}arrows"></i> |
|
126 |
</span> |
|
127 |
</div> |
|
128 |
</div> |
|
129 |
</div> |
|
130 |
</div> |
|
131 |
<div class="datagrid-tree-item-children" {if $control->isSortable()}data-sortable-tree data-sortable-url="{plink $control->getSortableHandler()}"{/}></div> |
|
132 |
</div> |
|
133 |
{/foreach} |
|
134 |
{if !$rows} |
|
135 |
{='ublaboo_datagrid.no_item_found'|translate} |
|
136 |
{/if} |
|
137 |
{/snippetArea} |
|
138 |
</div> |
composer.json | ||
---|---|---|
19 | 19 |
"nette/security": "^2.4", |
20 | 20 |
"nette/utils": "^2.4", |
21 | 21 |
"latte/latte": "^2.4", |
22 |
"tracy/tracy": "^2.4" |
|
22 |
"tracy/tracy": "^2.4", |
|
23 |
"ublaboo/datagrid": "^5.6" |
|
23 | 24 |
}, |
24 | 25 |
"require-dev": { |
25 | 26 |
"nette/tester": "^2.0" |
composer.lock | ||
---|---|---|
4 | 4 |
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", |
5 | 5 |
"This file is @generated automatically" |
6 | 6 |
], |
7 |
"content-hash": "29742b99e1ba0714587bf91cdbaecb4d",
|
|
7 |
"content-hash": "6018197517a97474da6c1a7c8e26f4fc",
|
|
8 | 8 |
"packages": [ |
9 | 9 |
{ |
10 | 10 |
"name": "latte/latte", |
... | ... | |
1180 | 1180 |
], |
1181 | 1181 |
"time": "2018-09-18T10:22:16+00:00" |
1182 | 1182 |
}, |
1183 |
{ |
|
1184 |
"name": "paragonie/random_compat", |
|
1185 |
"version": "v9.99.99", |
|
1186 |
"source": { |
|
1187 |
"type": "git", |
|
1188 |
"url": "https://github.com/paragonie/random_compat.git", |
|
1189 |
"reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" |
|
1190 |
}, |
|
1191 |
"dist": { |
|
1192 |
"type": "zip", |
|
1193 |
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", |
|
1194 |
"reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", |
|
1195 |
"shasum": "" |
|
1196 |
}, |
|
1197 |
"require": { |
|
1198 |
"php": "^7" |
|
1199 |
}, |
|
1200 |
"require-dev": { |
|
1201 |
"phpunit/phpunit": "4.*|5.*", |
|
1202 |
"vimeo/psalm": "^1" |
|
1203 |
}, |
|
1204 |
"suggest": { |
|
1205 |
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." |
|
1206 |
}, |
|
1207 |
"type": "library", |
|
1208 |
"notification-url": "https://packagist.org/downloads/", |
|
1209 |
"license": [ |
|
1210 |
"MIT" |
|
1211 |
], |
|
1212 |
"authors": [ |
|
1213 |
{ |
|
1214 |
"name": "Paragon Initiative Enterprises", |
|
1215 |
"email": "security@paragonie.com", |
|
1216 |
"homepage": "https://paragonie.com" |
|
1217 |
} |
|
1218 |
], |
|
1219 |
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", |
|
1220 |
"keywords": [ |
|
1221 |
"csprng", |
|
1222 |
"polyfill", |
|
1223 |
"pseudorandom", |
|
1224 |
"random" |
|
1225 |
], |
|
1226 |
"time": "2018-07-02T15:55:56+00:00" |
|
1227 |
}, |
|
1228 |
{ |
|
1229 |
"name": "symfony/inflector", |
|
1230 |
"version": "v3.3.6", |
|
1231 |
"source": { |
|
1232 |
"type": "git", |
|
1233 |
"url": "https://github.com/symfony/inflector.git", |
|
1234 |
"reference": "aed5a0874a3bcfd8d0393a2d91b4cf828f29c7fb" |
|
1235 |
}, |
|
1236 |
"dist": { |
|
1237 |
"type": "zip", |
|
1238 |
"url": "https://api.github.com/repos/symfony/inflector/zipball/aed5a0874a3bcfd8d0393a2d91b4cf828f29c7fb", |
|
1239 |
"reference": "aed5a0874a3bcfd8d0393a2d91b4cf828f29c7fb", |
|
1240 |
"shasum": "" |
|
1241 |
}, |
|
1242 |
"require": { |
|
1243 |
"php": ">=5.5.9" |
|
1244 |
}, |
|
1245 |
"type": "library", |
|
1246 |
"extra": { |
|
1247 |
"branch-alias": { |
|
1248 |
"dev-master": "3.3-dev" |
|
1249 |
} |
|
1250 |
}, |
|
1251 |
"autoload": { |
|
1252 |
"psr-4": { |
|
1253 |
"Symfony\\Component\\Inflector\\": "" |
|
1254 |
}, |
|
1255 |
"exclude-from-classmap": [ |
|
1256 |
"/Tests/" |
|
1257 |
] |
|
1258 |
}, |
|
1259 |
"notification-url": "https://packagist.org/downloads/", |
|
1260 |
"license": [ |
|
1261 |
"MIT" |
|
1262 |
], |
|
1263 |
"authors": [ |
|
1264 |
{ |
|
1265 |
"name": "Bernhard Schussek", |
|
1266 |
"email": "bschussek@gmail.com" |
|
1267 |
}, |
|
1268 |
{ |
|
1269 |
"name": "Symfony Community", |
|
1270 |
"homepage": "https://symfony.com/contributors" |
|
1271 |
} |
|
1272 |
], |
|
1273 |
"description": "Symfony Inflector Component", |
|
1274 |
"homepage": "https://symfony.com", |
|
1275 |
"keywords": [ |
|
1276 |
"inflection", |
|
1277 |
"pluralize", |
|
1278 |
"singularize", |
|
1279 |
"string", |
|
1280 |
"symfony", |
|
1281 |
"words" |
|
1282 |
], |
|
1283 |
"time": "2017-04-12T14:14:56+00:00" |
|
1284 |
}, |
|
1285 |
{ |
|
1286 |
"name": "symfony/polyfill-php70", |
|
1287 |
"version": "v1.11.0", |
|
1288 |
"source": { |
|
1289 |
"type": "git", |
|
1290 |
"url": "https://github.com/symfony/polyfill-php70.git", |
|
1291 |
"reference": "bc4858fb611bda58719124ca079baff854149c89" |
|
1292 |
}, |
|
1293 |
"dist": { |
|
1294 |
"type": "zip", |
|
1295 |
"url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/bc4858fb611bda58719124ca079baff854149c89", |
|
1296 |
"reference": "bc4858fb611bda58719124ca079baff854149c89", |
|
1297 |
"shasum": "" |
|
1298 |
}, |
|
1299 |
"require": { |
|
1300 |
"paragonie/random_compat": "~1.0|~2.0|~9.99", |
|
1301 |
"php": ">=5.3.3" |
|
1302 |
}, |
|
1303 |
"type": "library", |
|
1304 |
"extra": { |
|
1305 |
"branch-alias": { |
|
1306 |
"dev-master": "1.11-dev" |
|
1307 |
} |
|
1308 |
}, |
|
1309 |
"autoload": { |
|
1310 |
"psr-4": { |
|
1311 |
"Symfony\\Polyfill\\Php70\\": "" |
|
1312 |
}, |
|
1313 |
"files": [ |
|
1314 |
"bootstrap.php" |
|
1315 |
], |
|
1316 |
"classmap": [ |
|
1317 |
"Resources/stubs" |
|
1318 |
] |
|
1319 |
}, |
|
1320 |
"notification-url": "https://packagist.org/downloads/", |
|
1321 |
"license": [ |
|
1322 |
"MIT" |
Také k dispozici: Unified diff
Re #7217 přidání datagridů