Řešení podobného zadání jsou na netu mraky – takže k tomuto mraku přispěji dalším obláčkem. Aby řešení bylo co nejvíce univerzální, stanovil jsem si tyto podmínky:
- Všechny ovládané zaškrtávátka musí být uzavřeny do elementu <fieldset>
- První zaškrtávátko slouží pro výběr všeho.
Obecné Html a javacript
Html kód splňující výše uvedené podmínky pak vypadá takto:
<fieldset>
<input type="checkbox" name="all" /><label for="all">Vyber ve</label><br /><br/>
<input type="checkbox" name="praha" /><label for="praha">Praha</label><br />
<input type="checkbox" name="brno" /><label for="brno">Brno</label><br />
<input type="checkbox" name="ostrava" /><label for="ostrava">Ostrava</label>
</fieldset>
<input type="checkbox" name="all" /><label for="all">Vyber ve</label><br /><br/>
<input type="checkbox" name="praha" /><label for="praha">Praha</label><br />
<input type="checkbox" name="brno" /><label for="brno">Brno</label><br />
<input type="checkbox" name="ostrava" /><label for="ostrava">Ostrava</label>
</fieldset>
selectAllCheckbox.js
- jQuery(function () {
- jQuery('fieldset :checkbox').click(function () {
- var $checkboxes = jQuery(this).closest('fieldset').find(':checkbox');
- if ($checkboxes.index(this) == 0) {
- $checkboxes.not(this).attr('checked', this.checked);
- }
- else {
- $checkboxes.setSelectAllCheckbox();
- }
- });
- jQuery('fieldset').each(function () {
- jQuery(this).find(':checkbox').setSelectAllCheckbox();
- });
- })
- jQuery.fn.setSelectAllCheckbox = function SetSelectAll() {
- var first = this.first();
- jQuery(first).attr('checked', this.not(first).filter(':checked').length == (this.length - 1));
- }
Kód na řádcích 2-10 zajišťuje, že při každém kliknutí na zaškrtávátko umístněné v elementu <fieldset> je zjištěno, zda se jedná o první zaškrtávátko v daném elementu. Pokud ano, nastaví se všechna ostatní zaškrtávátka podle stavu právě kliknutého (řádek 5.). Pokud ne, provede se funkce na řádcích 17. – 20.
Kód na řádcích 12. 15. slouží pro správná nastavení po načtení stránky do prohlížeče.
Upozorňuji, že kód není dokonalý, například neřeší důsledně situace, kdy je do sebe zanořeno více elementů fieldset.
Html helper method
Element <fieldset> nemusím generovat ručně. Můžeme použít rozšíření HtmlHelperu a použít tuto konstrukci v našem view. Tvorbu jednoduchých rozšíření nemá asi cenu popisovat, proto rovnou popíši něco o stupeň složitější, tedy konstrukci podobnou @using(Html.BeginForm….):
@using (Html.BeginSelectAllCheckbox())
{
<input type="checkbox" name="all" /><label for="all">Vyber ve</label><br />
@Html.CheckBox("Praha")<label>Praha</label><br />
@Html.CheckBox("Brno")<label>Brno</label><br />
@Html.CheckBox("Ostrava")<label>Ostrava</label>
}
{
<input type="checkbox" name="all" /><label for="all">Vyber ve</label><br />
@Html.CheckBox("Praha")<label>Praha</label><br />
@Html.CheckBox("Brno")<label>Brno</label><br />
@Html.CheckBox("Ostrava")<label>Ostrava</label>
}
Metoda BeginSelectAllCheckbox je pak statické metoda statické třídy, která vypadá takto:
public static class HelperExtension
{
public static IDisposable BeginSelectAllCheckbox(this HtmlHelper helper )
{
Action begin = () => {helper.ViewContext.Writer.Write("<fieldset>");};
Action end = () => {helper.ViewContext.Writer.Write("</fieldset>");};
return new DisposableHelper(begin, end);
}
private class DisposableHelper : IDisposable
{
private readonly Action end;
public DisposableHelper(Action begin, Action end)
{
this.end = end;
begin();
}
public void Dispose()
{
end();
}
}
}
{
public static IDisposable BeginSelectAllCheckbox(this HtmlHelper helper )
{
Action begin = () => {helper.ViewContext.Writer.Write("<fieldset>");};
Action end = () => {helper.ViewContext.Writer.Write("</fieldset>");};
return new DisposableHelper(begin, end);
}
private class DisposableHelper : IDisposable
{
private readonly Action end;
public DisposableHelper(Action begin, Action end)
{
this.end = end;
begin();
}
public void Dispose()
{
end();
}
}
}
Přiložen je i ukázkový MVC projekt s veškerým kódem.
Žádné komentáře:
Okomentovat