ublaboo/datagrid: mocný, rychlý, rozšiřitelný, hezký, anglicky dokumentovaný datagrid

Hurass
Člen | 114
+
0
-

@PavelJanda jak přesně funguje předání proměných šabloně?
Vytvářím akci:

$grid->addAction("edit")
	->setTemplate(self::BASE_ACTION_TEMPLATE, array(
		"class" => "btn btn-sm btn-default",
		"icon" => "edit",
		"link" => "User:edit",
		"title" => "Edit",
	));

V šabloně předpokládám, že by to mělo jít využít nějak takto:

<a href="#" class="{$class}">
	<i class="fa fa-{$icon}"></i>
	{$title}
</a>

Bohužel to nefunguje, nezná to ani jednu z těch proměnných, které jsem šabloně poslal.

Editoval Hurass (21. 2. 2016 13:20)

Pavel Janda
Člen | 977
+
0
-

@Hurass funguje to zatím jen u sloupců, nikoliv u akcí. Přidám, dej mi chvíli.

Pavel Janda
Člen | 977
+
0
-

@Hurass Je to v masteru. Zatím dělám na v2, tak to pak bude otagované tam.

Pavel Janda
Člen | 977
+
0
-

Je možné skrýt select box s výběrem počtu záznamů na stránku? Nerad bych to řešil v css, prostě bych chtěl, aby se to vůbec nevykreslovalo.

Lze nastavit custom šablona a přepsat block #pagination.

Hurass
Člen | 114
+
+1
-

@PavelJanda díky, měl jsi u těch proměných v akcích překlep, hodilo to error. Poslal jsem pull request.

Editoval Hurass (21. 2. 2016 18:08)

David Grudl
Nette Core | 8227
+
+9
-

Ahoj Pavle, zkouším teď na jednom projektu tvůj DataGrid. Moc se líbí, jak poctivě má zpracovanou dokumentaci.

Při prvních krůčcích jsem se nicméně na pár věcech vypekl nebo je musel zkoumat, tak jsem je sepsal. Neber to prosím jako kritiku, spíš jako výsledek user testingu, který může datagrid ještě více zpřístupnit nováčkům.

  • na stránce overview:
    • chybí informace, jak se instaluje přes composer (tj. název balíčku, lze zjistit až prokliknutím na github)
    • assety: není úplně jasné, k čemu jsou potřeba, bez kterých se mohu obejít a v jakém pořadí je načítat, dále zda nette.ajax.js vyžaduje i nějaké rozšíření (a asi i zmínit nutno volat $.nette.init())
    • asi by se hodily i odkazy, třeba happy.js neznám, web http://happyjs.com/ se kterým možná souvisí nefunguje, soudě podle analýzy standalone.js to tohle asi nebude. Zdroják by asi mohl být i v distribuci. Stejně tak v případě Bootstrap Datepicker je potřeba použít tento a nikoliv tento
    • chybí informace, že potřebuje CSS z Boostrap
    • chybí informace, že potřebuje Font Awesome
    • drobnost: v textu je špatný odkaz na stránku data source (datadource)
    • v ukázkovém kódu (Show me the code) by bylo fajn připomenout, že třída je Ublaboo\DataGrid\DataGrid (komentářem? nebo použít celý název?)
    • pod kódem je i zdroják šablony grid.img.latte, ale chybí další v kódu uvedené šablony. Je to někde na githubu?
  • na stránce data-source by mělo být zmíněno, že setPrimaryKey() je nutné volat před setDataSource() (asi by to mohl čeknout i datagrid)
  • na stránce column
    • je ten datagrid fakt příliš dlouhý
    • místo $column = $title by mělo být $column = $key
  • na stránce filter
    • není vysvětlené, k čemu je $name u filtrů (btw, nebylo by lepší API addColumnText()->addFilter(...)?)

Dál jsem se ještě nedostal. Každopádně dobrá práce!

Pavel Janda
Člen | 977
+
+1
-

@DavidGrudl Děkuji za reakci a úhel pohledu z této strany.

Opravdu jsem na to zanevřel. Tak nějak předpokládám, že všichni automaticky zkoumají kód a se vším si poradí. Což není pravda a napravím to.

Abych zodpověděl některé body:

  • happy je miniknihovnička (momentálně zde) pro „zkrášlení“ radio/checkbox inputů. Žádné závislosti (tedy, je potřeba html5 a CSS3).

To je vlastně všechno, zbytek nejsou otázky. :)

Zkusím stihnout zdokonalit dokumentaci dřív, než stihneš projít další stránky.

Editoval Pavel Janda (21. 2. 2016 23:39)

Pavel Janda
Člen | 977
+
+6
-

Nová verze – v2.0.0

  • Přidán bower balíček ublaboo-datagrid – více info o assetech zde (BC break)
  • Možnost vyhodit „all“ z items_per_page listu
  • Stringy k překladu jsou nyní vedené v tečkové notaci (possible BC break)
  • ActionCallback – akce rovnou na user callback
  • DoctrineDataSoruce: Práce s defaultními aliasy tabulek (není již třeba uvádět pro každý sloupec/filtr sloupec s aliasem znovu)
  • Standalone.js is no longer created within this repo (BC break)
  • Opravy

Děkujeme všem za PR, issues a další připomínky!

Editoval Pavel Janda (23. 2. 2016 15:31)

hury
Člen | 56
+
0
-

Ahoj, zkousim tvuj datagrid, vypada to pekne…
predem diky za odpoved :-)

(pouzivam nette/database)

ale nejak jsem nepochopil, jak pouziju sloupec z jine tabulky, aniz bych musel pouzivat joiny…
v o5/grido je toto reseno velmi jednoduse
$grid->addColumn('users_skupina.nazev', 'Členem')

table users:

id username users_skupina_id
1 abc 1
2 eee null
3 Drak 2

table users_skupina:

id nazev
1 Nicky
2 Borci

Druha otazka:
jde nejak udelat externi filter? Aby nebyl vypsany u policek :-)

Editoval hury (23. 2. 2016 13:14)

Pavel Janda
Člen | 977
+
0
-

@hury 2, $grid->setOuterFilterRendering(), je to v docu.

1, Neznám Grido do detailu, ale předpokládám, že s tím ti pomohla spíš NDBT než Grido. Když uděláš něco takového, tak by ti to mohlo vypsat požadovaná data:

$ndb->table('users')->select('users.*, : users_skupina.nazev')

Zkus to – ale spíš jsem to tak střelil od boku. Doufám chápeš moji pointu.

Je ale možné, že s tím Grido dělá nějaká kouzla, podávám se. :)

Editoval Pavel Janda (23. 2. 2016 14:05)

Pavel Janda
Člen | 977
+
0
-

@hury Zkusil jsem tvůj příklad na o5\gridu a chová se to stejně. Musíš si nějakým způsobem definovat tu referenci, žádná kouzla se nedějí.

hury
Člen | 56
+
0
-

Diky, ten outerFilter jsem uplne prehledl…

externi data jsem udelal pres

->setRenderer(function($item){
	if ($item->skupina_id !== null) {
		return $item->skupina->nazev;
	}
	else {
		return '-';
	}
});

mozna jsem jen ovlivnen vice gridy, posledni dobou zkousim vse mozne a nemuzu najit neco co budu pouzivat. Ten tvuj je na dobre ceste :-)

nejaka myslenka, jak udelat toto?
ruzne barevne tlacitka, pokud je $item aktivni, ci nikoli

$grid->addAction('detail','')->setIcon('search')->setClass(function($item){
	if ((int)$item->aktivni === 1) {
		return 'btn btn-xs btn-success';
	}
	else {
		return 'btn btn-xs btn-danger';
	}
});

pak jeste jedna otazka:
potrebuji udelat filterSelect, kde filtruji nad ruznymi sloupci…
(kazda hodnota ma ruzny WHERE …)
polozky selectu: vse, nove, stare, propadle

	vse = zadne omezeni...
	nove = tabulka.aktivni = 1 && tabulka.datum > '2016-01-01'
	stare = tabulka.datum < '2016-01-01'
	propadle = tabulka.aktivni = 0 && tabulka.stav = 'abc...'

je to jen priklad, takovy select by bala asi kravina :-)

Pavel Janda
Člen | 977
+
0
-

@hury
1, Jasně, taky to tak jde. Pokud bys chtěl, aby ti ta NDBT udělala join, tak zkus ten můj příklad, mně fungoval na stejné struktuře, jakou jsi psal. :) – Ale jak říkám, za to může NDBT, ne gridy.

2, Momentálně můžeš takovýmto callbackem ovlivňovat třídu celé ROW (viz – dole – Row Callback). Ale líbí se mi určování title, class, confirm a podobně callbackem, dávám do issues a hned večer napíšu.

3, Definuj si vlastní podmínky filtru:

$grid->addFilterSelect('status', ['....'])->setCondition(function($fluent, $value) {
	switch ($value) {
		case 'vse':
			break;

		case 'nove':
			$fluent->where('...')
			break;

		case 'stare':
			$fluent->where('...')
			break;
	}
});

Editoval Pavel Janda (23. 2. 2016 15:52)

Pavel Kravčík
Člen | 1195
+
0
-

@PavelJanda: Nová verze vypadá super. Ty překlady jsou mnohem lepší takhle.

Chvíli mi trvalo dát do kupy JS (jsem nicka – nepoužívám balíčkovač na JS, jen composer). Všiml jsem si jen dvou drobností u item-detail.

V minulé verzi fungoval bez jquery-sortable(), to je asi úplně nepodstatné. Jen mi překvapila ta závislost navíc.

A když definuji grouped-action a vyberu vše a následně kliknu na „eye-icon“ pro zobrazení detailu, tak se řádek odoznačí. Zkoušel jsem na lokále i na demíčku. Asi by bylo lepší, kdyby zůstal řádek označený.

Pavel Janda
Člen | 977
+
+1
-

@PavelKravčík item-detail nefunguje bez jquery sortable? To bych se divil. Tenhle scirpt je tam jen kvůli sortění tabulky a tree view, ale nemá co do činění s item detailem. Mrknu na to.

Teď se posílá snippet a překreslí se jak položka, tak detail položky. Ta položka se posílá zbytečně. Super, píšu si, dík.

Edit

Assety: No já jsem taky backenďák. Pravda ale je, že to usnadňuje závislosti.. Tak jsem se k tomu dokopal. Kdo si s tím nebude vědět rady, snad to vykouká z cest assetů v dokumentaci.

Editoval Pavel Janda (23. 2. 2016 15:59)

Pavel Janda
Člen | 977
+
+2
-

v2.0.2 opravuje oboje – Není třeba jquery sortable, pokud nechci sortit a neposílá se v xhr response item row.

Pavel Kravčík
Člen | 1195
+
0
-

@PavelJanda:

A ještě zmizí checkbox. Ale nijak hlouběji jsem netestoval.

http://imgur.com/Upn756T

EDIT: To je fofr, skvělá práce!
EDIT2: Nasazeno a „working like a charm“. :)

Editoval Pavel Kravčík (23. 2. 2016 16:29)

Pavel Janda
Člen | 977
+
0
-

@PavelKravčík DataGrid použivá mojí miniaturní library happy (bower install happy), která dělá ty pěkné checkboxy. Includuješ scripty té knihovničky? Pokud bys je nehctěl používat, lze je vypnout: $grid->useHappyComponents(FALSE).

Pavel Kravčík
Člen | 1195
+
0
-

@PavelJanda: Jasně, používám, je to pěkné. Našel jsem si to podle odpovědi na D.Grudla, ale přemýšlel jsem zezačátku, jestli neudělat vlastní šablonu a dát tam to současné řešení, které mám na „hezké“ checkboxy. Každopádně tenhle doplněk je paráda.

Ještě jeden nedostatek tu vidím: Absenci donations. :)

Pavel Janda
Člen | 977
+
+3
-

@PavelKravčík Hehe, nejlepší donations jsou do kódu. :)
Možná tam nějaké tlačítko přidáme. :)

Pavel Kravčík
Člen | 1195
+
0
-

@PavelJanda: Na to musí být člověk dobrý programátor a kamarádit se s Gitem. :) Já si frčím v SVN a nemám důvod přecházet. GitHub mám jen na hvězdičkování Nette-doplňků.

hury
Člen | 56
+
0
-

tady to tedy frci :-)

btw, nejaky duvod, proc s nepreklada filter?

pouzivam kdyby/translator
$grid->setTranslator($this->translator);

nazvy sloupcu i grid jsou v pohode, prekladaji se… ale toto nefunguje:
$grid->addFilterText('hledat', 'grid.hledat-cokoli', ['nazev', 'popis']);

Pavel Janda
Člen | 977
+
0
-

@hury Chyba.

A teď: fix je jednoduchý, přidám řádek $form->setTranslator($this->getTranslator());. Jenže takhle se budou překládat i select boxy. Musím se rozhodnout, jestli se budou překládat i options selectů..

hury
Člen | 56
+
0
-

toto me stve i u formulare…
reseni se mi vubec nelibi (ale treba to delam blbe, a jde to lepe :-))

$form->setTranslator($this->translator);

$form->addText('aresIc', 'sign.form.ic', 12, 20); // tady je to v pohode...

$form->addSelect('aresZeme', $this->translator->translate('sign.form.zeme'), $seznamZemiSelect)
     ->setTranslator(null) // kvuli seznamu zemi - aby se to neprekladalo
     ->setPrompt($this->translator->translate('sign.form.vyberte'));

nejake elegantnejsi reseni by bodlo… neco jako:

$form->addSelect('aresZeme', 'sign.form.zeme', $seznamZemiSelect)
     ->translateLabel()
     ->translateOptions(false)
     ->translatePrompt();
Pavel Janda
Člen | 977
+
+1
-

Poradim ti asi lepsi reseni. Koukni se do ublaboo/controls. Je am select, kteremu se neprekladaji opions. A je tam i stejne fungujici NotTranslatableRadioList.

Editoval Pavel Janda (23. 2. 2016 17:43)

Hurass
Člen | 114
+
0
-

Mám jeden problém s řazezím na joinované tabulky. Používám Kdyby/Doctrine. Konkrétně vypisuju data z tabuky user která má vazbu n:1 na tabulku user_role.

Třída App\ModelUser:

/**
 * @ORM\ManyToOne(targetEntity="UserRole", inversedBy="users", cascade={"persist"})
 */
protected $userRole;

Ukázka jak tvořím grid:

$grid->setDataSource(
	$this->userRepository->createQueryBuilder("u")
		->leftJoin(\App\Model\UserRole::class, "ur", \Kdyby\Doctrine\Dql\Join::WITH, "ur.id = u.userRole")
);

$grid->addColumnText("role", "Role", "ur.name")
		->setSortable();

Vypíše se vše v pořádku, řadit jde podle všech slouplců, ale né právě Role, která je $name ve tříde App\Model\UserRole.

Při pokusi seřadit data podle role se vygeneruje DQL:

SELECT u
FROM App\Model\User u
LEFT JOIN App\Model\UserRole ur WITH ur.id = u.userRole
ORDER BY u.ur.name ASC

Předpokládám, že by to mělo být takto:

SELECT u
FROM App\Model\User u
LEFT JOIN App\Model\UserRole ur WITH ur.id = u.userRole
ORDER BY ur.name ASC

Poradí mi někdo, jak toho docílit?

Pavel Janda
Člen | 977
+
+1
-

@Hurass můžeš zkusit master?

Hurass
Člen | 114
+
0
-

Funguje, díky!

Pavel Janda
Člen | 977
+
0
-

@hury v2.0.4 opravuje překládání filtrů. Selectům se nepřekládají options.

Pavel Janda
Člen | 977
+
0
-

Nová verze – v2.1:

  • Možnost definovat icon, title, confirmation dialog a class Column\Action callbackem
  • DataGrid::setDefaultSort does not need a session in time anymore
  • Fixy

Editoval Pavel Janda (25. 2. 2016 0:10)

pitr82
Člen | 121
+
0
-

Ahoj,
zkoušel jsem podle návodu (mimochodem pěkně dokumentovaný) Item Detail a má dvě otázky.

  1. Nejde mi přistoupit k proměnné jako k oběktu $item->id ale jen přes pole $item[‚id‘]
  2. musím dvakrát kliknout pro rozbalení detailu.

    Poprvé se provede ajax, ale nezobrazí se detail, podruhé už detail zobrazí.

Pavel Janda
Člen | 977
+
0
-

@pitr82

2, Zkoušíš to na existujícím projektu, nebo na sandboxu? Kdybys to zkoušel na nějakém sandboxu, tak to můžeš hodin na git a já se na to podívám.

Takhle tam může být chybka z více důvodů.

  • Máš popořadě naincludované všechny scripty jako je to v docu? – Nehází ti console žádné errory?
  • Používáš poslední verzi DataGridu – v2.1.1?
  • Jak stahuješ scripty? Přes bower?

Funguje ti správně demo na ublaboo.paveljanda.com/datagrid?

1, Mohl bys mi ukázat, jak máš napsanou celou component factory v presenteru? Jakou vrstvu mezi databází a aplikací používáš?

Editoval Pavel Janda (25. 2. 2016 14:20)

pitr82
Člen | 121
+
0
-

@PavelJanda

Ad 1, samozřejmě pro vyzkoušení jsem použil Pole

Ad 2, Samozřejmě jsem zapomněl na netteForms.js

Dík za super datagrid, jak budu mít zase stupidní problém, tak se ozvu :-)

P.s. Neplánujete udělat ještě udělat ve stejné kvalite dateTimePicker/datePicker ?

Pavel Janda
Člen | 977
+
0
-

@pitr82 :) Jsem rád, že je používán.
Co myslíš tím „ve stejné kvalitě“? Myslíš aby vypadaly podobně jako ty checkboxy? Nebo se ti jen nepodařilo nahrát bootstrap-datapicker? Ten je tam nyní normálně využit.

Kdyby to první, tak rovnou odpovím, že já určitě asi ne. :) Jsem primárně backenďák a nemyslím, že mám znalosti na to, abych napsal lepší..

pitr82
Člen | 121
+
0
-

@PavelJanda

Nemyslím nový datepicekr ale addon pro nette, když jej používám jednoduše ve Vašem datagridu, tak bych jej rád používal i jako addon ve formulářích. Jednotná grafika atd.

Pavel Kravčík
Člen | 1195
+
0
-

@PavelJanda:

Co něco takového do další verze? Tj. správa hromadných akcí jako u obyčejných. Myslíš, že už je to trochu složitější oříšek. :)

$grid->addGroupAction('gruppen', Zaplatit smlouvy');

$grid->allowRowsGroupAction('gruppen', function($row)
{
	return $row->status != \Psa\Entity\ImportEntity::STATUS_MANUAL;
});
Pavel Janda
Člen | 977
+
0
-

@PavelKravčík Jak by se se choval checkbox, pokud by byl zaškrtnutý, po vybrání akce, která by nepodporovala vybrání vybrané položky? :D To zní strašně, je to pochopitelné?
Nebo by se prostě tyto položky neodeslaly?

Pavel Kravčík
Člen | 1195
+
0
-

@PavelJanda: Jasně, tomu rozumím. Myslel jsem něco jako onChange[], kontrola jen vybraných a nějaký disable. Moc hezké to není, proto jsem to jen nadhodil, kdyby existovalo hezčí řešení. Na nějakém starém gridu jsem to někde měl. Ale nic pěkného to nebylo.

exquis
Člen | 83
+
0
-

Ahoj, mám problém s automatickým potvrzováním filtrů. Projevuje se to např.:

  • ve filtru typu addFilterText(), když do něj kliknu a začnu psát slovo, tak se hned potvrdí a formulář se odešle aniž bych ho potvrdil a filtr se nezohlední
  • u typu addFilterDate stačí kliknout do pole pro zadání data, vyběhne bootstrap datepicker, ale hned po jeho zobrazení se formulář opět sám odešle, aniž bych stihnul vybrat datum, je to prakticky ihned

JS a CSS mám načtené všechny, console žádnou chybu nehlásí, myslel jsem si, že se do toho nějak míchá liveValidation (konkrétně nastavené wait:150), ale to jsem dal na false a stejně to dělá dál

function createComponentObjednavky() {
     $grid = new DataGrid();
     $grid->setDataSource($this->Orders->getTblOrders()->getAll());
     // Columns
     $grid->addColumnDateTime("issue_date", "Datum vytvoření")->setSortable();
     $grid->addColumnLink("order_number", "Číslo objednávky", "detailObjednavky")->setSortable();
     $grid->addColumnDateTime("name", "Jméno")->setSortable();
     // Filters
     $grid->addFilterDate('issue_date', 'Datum vytvoření');
     $grid->addFilterText('order_number', 'Objednávka');

     return $grid;
 }
{control objednavky}

EDIT: zdroje mám stažené skrze BOWER, takže ve špatných verzích by snad chyba být neměla.

Editoval exquis (28. 2. 2016 13:24)

Pavel Janda
Člen | 977
+
0
-

@exquis

  1. To je dost divné. Pravděpodobně ti do toho zasahují scripty třetích stran nebo tvoje. Dal jsem na github v rychlosti testovací array-datagrid-sandbox, kde se nic takového neděje a vše je přesně podle dokumentace. Stačí akorát composer update a bower install ublaboo-datagrid.
  2. Ano, to je pravda. Bohužel eventy tohoto typu nejsou v JS ideální na 100%. Momentálně se odesílá ajaxový request při každém input::onChange. A onchange v js znamená, že se pošle i v případě, že přejde input pouze do stavu focus.
harmim
Člen | 26
+
0
-

@PavelJanda proč něpřekládáš options v FilterSelect a replacements u jednotlivých columns?

Pavel Janda
Člen | 977
+
+1
-

@harmim
1, Protože jednodušeji nastavíš selectu datagridu přeložené options než odebereš překládání. Představ si, že bych to překládal – jak bys docílil toho, aby se překlady zrušily? Moc by to nešlo..

Kdy jsou potřeba nepřeložené selecty? Pokud jsi se s tím ještě nesetkal, tak například tehdy, pokud potřebuješ select jmen produktů, adres, jmen zákazníků, kódů zemí, telefonních čísel… – prostě veškerých dat, která bereš z databáze.

2, Ze stejného důvodu, z jakého nepřekládám ani hodnoty sloupců. Replacement je náhrada za hodnotu sloupce. A opět, vypíše se víceméně hodnota řádku databáze. Může to být jak číslo, tak text. Může to být text k překladu, nebo jenom poupravený text, který se překládat nemá.

Pokud potřebuješ překládat jedno či druhé, je třeba nejdřív vytvořit přeložený seznam a ten předat DataGridu.

exquis
Člen | 83
+
0
-

Je možné nějak nastavit šířku sloupce? ideálně v %

exquis
Člen | 83
+
0
-

@PavelJanda ještě jsem narazil na drobnou chybku – jakmile vypisuješ data pomocí nette/database a máš spojených více tabulek, tak hlásí chybu, že existuje více sloupců „ID“ a že nemá jak spočítat záznamy, to se mi povedlo obejít, když jsem natvrdo změnil, aby nedělal COUNT nad ID, ale „*“

/**
 * Get count of data
 * @return int
 */
public function getCount() {
    return $this->data_source->count("*");
}
Pavel Janda
Člen | 977
+
0
-

@exquis To doporučuji nechat na css. Jednotlivé sloupce jsou snadno indetifikovatelné, každý má třídu col-<key>.

Hm, to se mi sice nelíbí, ale pravděpodobně to tak budu muset udělat. Dík za tip, přidám.

Editoval Pavel Janda (2. 3. 2016 19:05)

exquis
Člen | 83
+
+1
-

Pavel Janda napsal(a):

@exquis To doporučuji nechat na css. Jednotlivé sloupce jsou snadno indetifikovatelné, každý má třídu col-<key>.

Hm, to se mi sice nelíbí, ale pravděpodobně to tak budu muset udělat. Dík za tip, přidám.

Už na to koukám, paráda, díky. I když myslím, že by bylo nebylo špatné udělat něco jako setWidth().. když si představím, že bych musel pro každý sloupec z rozsáhlejšího systému psát vlastní styl .. to by se pak hodilo v tu chvíli udělat v CSS třídy .col-width-10, 20, 30 atd a ty třídy pak jednotlivým sloupcům přiřazovat.

Jinak musím pochválit perfektní datagrid ;)

Pavel Janda
Člen | 977
+
0
-

@exquis Mně by se taky líbilo, kdyby to šlo takhle jednoduše. Napadá tě nějaký jiný nápad, než psát PHPčkem inline styly?

Šaman
Člen | 2661
+
+2
-

Co možnost nastavit sloupci vlastní třídu (ideláně udělat to univerzálně jako nastavení atributu), která se pak použije v každé TH a TD onoho sloupce?

newPOPE
Člen | 648
+
0
-

V zasade staci len nastavit to prvemu riadku ostatne by mali byt rovnake ak neberieme do uvahy colspan-y..

Pavel Janda
Člen | 977
+
0
-

@Šaman Tak by to jistě šlo. Tedy jich udělám 10. Jenže pak bude chtít někdo 15% šířku. Tak se přidá dalších 10. Pak bude chtít někdo 17,5%. :D Atp.

Bral bych to jako poslední možnost.