Jiné renderování položek RadioListu
- medhi
- Generous Backer | 255
Výchozí Renderer vykresluje itemy radiolistu takto:
<label>
<input type="radio" name="species" value="snowman" >
Snowman
</label>
Já bych ale potřeboval vlastní renderer nastavit tak, aby se vypisovaly takto (nechci/nemůžu použít manuální renderování):
<input id="itemid1" type="radio" name="species" value="snowman" >
<label for="itemid1">Snowman</label>
Tedy ne vnořeně, ale za sebou. Předpokládám, že to nejde, už jenom kvůli tomu ID, které tam normálně není. Nikde jsem to řešení ani nenašel.
Můj důvod: Chci nastylovat label jako tlačítko a potřebuji mu nastavit
jiný styl, pokud je input checked. To jde pouze v druhém případě (pomocí
selectoru .input-class:checked+.label-class
). V prvním případě
to nejde, protože CSS nezná způsob, jak nastavit třídu rodiče
konkrétního elementu (možná to půjde v budoucnu pseudoelementem
:has()
).
Díky moc
- Ondřej Kubíček
- Člen | 494
a není jednodušší, prostě jen když je radio checked, nastavit labelu nějakou třídu a nastylovat jak potřebuješ?
- Jan Tvrdík
- Nette guru | 2595
Pokud ten label obalíš <span>
(do labelu můžeš
předat Html instance), tak můžeš
použít .input-class:checked + span
- dakur
- Člen | 493
@medhi Podle mě nemáš bez manual renderingu nebo JS šanci.
Z hlediska frontenďáka uvažuješ správně, korektní struktura je opravdu
taková a jinak to nezprovozníš – z povahy, jak +
funguje.
<input>
<label>...</label>
Řeší se to tady ale opakovaně, že lidé potřebují drobnou úpravu rendereru, ale wrappers je málo a manual rendering zas moc. Myslím, že by stálo za to umožnit programátorovi nějak zasáhnout do struktury vykreslování formuláře, jen nevím jak. 🙂
- medhi
- Generous Backer | 255
dakur napsal(a):
@medhi Podle mě nemáš bez manual renderingu nebo JS šanci. Z hlediska frontenďáka uvažuješ správně, korektní struktura je opravdu taková a jinak to nezprovozníš – z povahy, jak
+
funguje.<input> <label>...</label>
Řeší se to tady ale opakovaně, že lidé potřebují drobnou úpravu rendereru, ale wrappers je málo a manual rendering zas moc. Myslím, že by stálo za to umožnit programátorovi nějak zasáhnout do struktury vykreslování formuláře, jen nevím jak. 🙂
Myslel jsem si to, díky. Budu bádat jak to udělat jinak a kouknu do zdrojáků, jestli by taková fíčura byla složitá na přidání.
- medhi
- Generous Backer | 255
Jan Tvrdík napsal(a):
Pokud ten label obalíš
<span>
(do labelu můžeš předat Html instance), tak můžeš použít.input-class:checked + span
To nejde, CSS selektor .input-class:checked + span
najde:
<input class="input-class" checked> <span></span>
nikoli
<span>
<label>
<input type="radio" name="species" value="snowman" >
Snowman
</label>
</span>
- dakur
- Člen | 493
a kouknu do zdrojáků, jestli by taková fíčura byla složitá na přidání.
Já myslím, že nebyla. Myslím, že by stačilo jen mít někde nějaký
Nette\Utils\Html
parametr, který by reprezentoval DOM celého toho
form fieldu. Pak by tam ještě musely být nějaké dva placeholdery, které by
označkovaly, co je teda ten input a co label, aby s tím mohlo nette/forms
dále pracovat a věšet na to své věci. Něco v tomto smyslu:
$radioList->setDOM(
Html::el('div')
->addHtml(Html::el('input', [RadioList::INPUT_PLACEHOLDER]))
->addHtml(Html::el('label', [RadioList::LABEL_PLACEHOLDER])
->addHtml(Html::el('span')->setText('span inside of <label>')))
->addHtml(Html::el('span')->setText('another span after <label>'))
);
/* output:
* <div> <-- this one implicitly by Nette or whatever group element is there by default
* <div>
* <input ...>
* <label ...>
* <span>span inside of <label></span>
* </label>
* <span>another span after <label></span>
* </div>
* </div>
*/
Ale určitě by to chtělo někoho vzdělanějšího a s větším nadhledem než jsem já. 🙂
Editoval dakur (10. 3. 2021 14:46)
- Kamil Valenta
- Člen | 820
Pokud ten radiolist definuješ takto:
$form->addRadioList('test', 'TEST', [
1 => \Nette\Utils\Html::el('span')->setText('1'),
2 => \Nette\Utils\Html::el('span')->setText('2'),
]);
Získáš strukturu:
<label>
<input type="radio" name="test" value="1" >
<span>1</span>
</label>
A to už selektorem „+“ nastyluješ…
--
IMHO i @JanTvrdík tím „ten label“ nemyslel HTML značku, ale
samotný popisek radio buttonu…
Editoval Kamil Valenta (15. 2. 2021 11:27)
- medhi
- Generous Backer | 255
Kamil Valenta napsal(a):
Pokud ten radiolist definuješ takto:
$form->addRadioList('test', 'TEST', [ 1 => \Nette\Utils\Html::el('span')->setText('1'), 2 => \Nette\Utils\Html::el('span')->setText('2'), ]);
Získáš strukturu:
<label> <input type="radio" name="test" value="1" > <span>1</span> </label>
A to už selektorem „+“ nastyluješ…
--
IMHO i @JanTvrdík tím „ten label“ nemyslel HTML značku, ale samotný popisek radio buttonu…
Pokud tedy pomocí CSS skryju <label>
a
<input>
a nastyluju <span>
jako tlačítko
(viz. Můj důvod: Chci nastylovat label jako tlačítko a potřebuji mu
nastavit jiný styl, pokud je input checked.), jak potom bude fungovat
klikání na ten span, aby se měnila hodnota inputu?
- Kamil Valenta
- Člen | 820
A není rychlejší to vyzkoušet? :)
<label> bych asi neskrýval, když je nadřazený tomu <span>.
<style type="text/css">
input {
display: none;
}
input + span {
padding: 10px;
background: red;
}
input:checked + span {
background: green;
}
</style>
<label>
<input type="radio" name="test" value="1" >
<span>1</span>
</label>
<label>
<input type="radio" name="test" value="2" >
<span>2</span>
</label>
Editoval Kamil Valenta (15. 2. 2021 13:21)
- dakur
- Člen | 493
😮 To není moc intuitivní API.. 🤔
@medhi Btw, stylovat label
nebo cokoliv jiného jako
tlačítko není vůbec dobrý nápad. Pokud potřebuješ tlačítko, použij
tlačítko (tedy button
) a změn styl. Jinak si koleduješ o user
experience problém – viz https://www.vzhurudolu.cz/prirucka/button#…
Editoval dakur (15. 2. 2021 12:36)
- medhi
- Generous Backer | 255
Kamil Valenta napsal(a):
A není rychlejší to vyzkoušet? :)
<label> bych asi nezkrýval, když je nadřazený tomu <span>.
<style type="text/css"> input { display: none; } input + span { padding: 10px; background: red; } input:checked + span { background: green; } </style> <label> <input type="radio" name="test" value="1" > <span>1</span> </label> <label> <input type="radio" name="test" value="2" > <span>2</span> </label>
Máš naprostou pravdu, ten span je v label, takže klikání funguje. Docela pěknej hack, díky moc.
Má to tedy jednu nevýhodu – tlačítko <span>
je
uzavřeno v <label>
a tedy nelze potom třeba použít
Bootstrapí groupování tlačítek.
Editoval medhi (15. 2. 2021 12:49)
- medhi
- Generous Backer | 255
dakur napsal(a):
😮 To není moc intuitivní API.. 🤔
@medhi Btw, stylovat
label
nebo cokoliv jiného jako tlačítko není vůbec dobrý nápad. Pokud potřebuješ tlačítko, použij tlačítko (tedybutton
) a změn styl. Jinak si koleduješ o user experience problém – viz https://www.vzhurudolu.cz/prirucka/button#…
Není, ale je to jediná možnost, jak to udělat a vlastně to neni tak hrozný, jak jsem čekal, že by mohlo být.
Já nepotřebuji ani tak tlačítko, jako jakýsi „switch“, tedy radiobutton renderovat jako přepínač, v mém případě složený z komponent Bootstrapových tlačítek. Myslím, že to v tomto případě docela legitimní věc.
- dakur
- Člen | 493
Aha, takže ne tlačítko, ale přepínač, už chápu. 🙂 Bootstrap v5 ho má v sobě mimochodem, ale chápu, že kvůli tomu nejde upgradovat celý projekt. https://getbootstrap.com/…ecks-radios/#…
Editoval dakur (15. 2. 2021 12:58)
- medhi
- Generous Backer | 255
dakur napsal(a):
Aha, takže ne tlačítko, ale přepínač, už chápu. 🙂 Bootstrap v5 ho má v sobě mimochodem, ale chápu, že kvůli tomu nejde upgradovat celý projekt. https://getbootstrap.com/…ecks-radios/#…
Já to mám v5, ale tohle je checkbox switch, já potřebuju switch pro 3+ možnosti :) Tedy musím použít RadioList nebo Select.