Získej svůj iPhone v nové soutěži! Získej svůj iPhone v nové soutěži!
Nová překladatelská soutěž ITnetwork.cz o telefon iPhone, sluchátka Beats a další věcné ceny za 4 hodiny práce.
Přidej si svou IT školu do profilu a najdi spolužáky zde na síti :)

Dokončení hvězdičkového hodnocení v JavaScriptu

JavaScript Hotová řešení Dokončení hvězdičkového hodnocení v JavaScriptu

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulém tutoriálu o tvorbě hvězdičkového hodnocení v JavaScriptu jsme rozpracovali HTML část. V dnešním dílu ji dokončíme a přidáme JavaScript. Hodnocení tím oživíme a také dokončíme.

Použití obrázkového písma

Elementům, do kterých chceme přiřadit obrázkový znak, přidáme třídu glyphicon a poté třídu, která reprezentuje znak. Seznam všech tříd pro jednotlivé znaky naleznete na http://getbootstrap.com/components/. Nám stačí znaky star a star-empty. Na úvod všechny hvězdičky necháme prázdné, spany budou vypadat následovně:

<span class="glyphicon glyphicon-star-empty review-star"></span>
<span class="glyphicon glyphicon-star-empty review-star"></span>
<span class="glyphicon glyphicon-star-empty review-star"></span>
<span class="glyphicon glyphicon-star-empty review-star"></span>
<span class="glyphicon glyphicon-star-empty review-star"></span>

Nyní budou naše hvězdičky vypadat následovně:

Prázdné hvězdičky v JavaScriptu

Jsou však docela malé. Přidejme CSS a do naší třídy review-star přidejme vlastnost font-size s hodnotou 25px, čímž hvězdičky zvětšíme. Také jim nastavíme kurzor myši na ruku. Když jsme již u CSS, nastavme formuláři centrování.

.review-star {
        font-size:25px;
        cursor: pointer;
}

form.review  {
        text-align: center;
}

Výsledek:

Hvězdičkové hodnocení v JavaScriptu

Již jste asi postřehli, že kdybychom zvolili obrázky, museli bychom otevírat grafický editor a zvětšovat obrázek (což ke všemu sníží jeho kvalitu) nebo ho pracně vytvářet znovu.

Označování hvězdiček při kliknutí

Začneme označováním hvězdičky kliknutím. V obsluze události pro načtení dokumentu si tedy načtěme hvězdičky podle třídy review-star a přidejme jim obsluhu události click na funkci setStars(), kterou vzápětí vytvoříme.

$(document).ready(function() {
        var stars = $(".review-star");
        stars.click(setStars);
});

setStars

Vytvořme si funkci setStars().

Ve funkci, která se volá při kliknutí na tlačítko, je objekt, na který uživatel klikne, nastaven do proměnné this. Tento element není elementem jQuery, ale to nám zrovna moc nevadí. Potřebujeme získat index v poli prvků elementů dané hvězdičky, což nám vrátí počet "vybraných" hvězdiček počítaný od nuly. Z prvku this si tedy vezmeme parentElement, poté children,... Jenže "pole" children není pole, ale jedná se o objekt HTMLCollection, který sice polem není, ale chová se jako pole. Bohužel však neobsahuje metodu indexOf(). V podstatě nám však v JavaScriptu (v jiných jazycích by se to muselo řešit složitěji) nic nebrání buďto metodu indexOf() objektu HTMLCollection doprogramovat ručně nebo mu prostě říci, aby přidal do objektu HtmlCollection funkci úplně stejnou jako je indexOf() na poli. Přidejme tedy na začátek souboru následující řádek.

HTMLCollection.prototype.indexOf = [].indexOf;

Nyní již na kolekci HTMLCollection můžeme zcela normálně zavolat metodu indexOf(), tak, jak jsme zvyklí na poli.

Uložme si tedy počet vybraných hvězdiček do proměnné a přičtěme k ní jedničku, abychom číslo dostali do uživateli přívětivější podoby než je počítání od nuly.

var selectedStars = this.parentElement.children.indexOf(this) + 1;

Nastavme tuto hodnotu inputu, který má id rating.

$("#rating").val(selectedStars);

returnStartState

Ta technicky nejpodstatnější část je za námi. Nyní je však dobré uživateli zvýraznit tolik hvězdiček, kolik vybral. Protože to budeme dělat na více místech, vytvoříme si na to funkci returnStarState().

V té si znovu načteme hvězdičky. Čistě teoreticky bychom mohli mít hvězdičky uložené globálně, ale to se nedoporučuje kvůli udržovatelnosti a přehlednosti zdrojového kódu a předáváním dat se pro zjednodušení zabývat nebudeme, tak si je načteme znovu.

Nejprve vyresetujeme stav všech hvězdiček. Hvězdičky budeme označovat změnou třídy glyphicon-star-empty za glyphicon-star. Proto všem hvězdičkám odstraníme třídu glyphicon-star a všem nastavíme třídu glyphicon-star-empty.

var stars = $(".review-star");
stars.addClass("glyphicon-star-empty");
stars.removeClass("glyphicon-star");

Poté cyklem projdeme počet vybraných hvězdiček a těmto hvězdičkám to uděláme naopak, odstraníme třídy glyphicon-star-empty a přidáme glyphicon-star. Řídící proměnnou v cyklu můžeme vyčíst z hodnoty v skrytém políčku.

for (var i = 0; i < $("#rating").val(); i++) {
        $(stars[i]).removeClass("glyphicon-star-empty");
        $(stars[i]).addClass("glyphicon-star");
}

Funkci zavolejme na konci funkce setStars(). Při kliknutí na hvězdičku se všechny přední a ona sama vyplní.

Vyplnění hvězdiček

Hover hvězdiček

Hover hvězdiček musíme obsloužit sami a v CSS to nepůjde, protože musíme označit i předchozí hvězdičky. Vytvořme si funkci starHover(), která se zavolá při najetí myši a funkci při vyjetí již máme hotovou - využijeme returnStarState(). Nastavme tedy obsluhy události mouseenter a mouseleave hvězdičkám v obsluze události pro načtení dokumentu.

stars.mouseenter(starHover);
stars.mouseleave(returnStarState);

Ve funkci si musíme získat počet hvězdiček, které chce uživatel označit. I u obsluhy události mouseenter si opět získáme počet vybraných hvězdiček pomocí indexOf() na kolekci children rodiče elementu, nad který uživatel umístil kurzor. Ten je opět v proměnné this. Všem jim opět vyresetujeme třídy a v cyklu je nastavíme "hoverovaným" hvězdičkám.

function starHover() {
        var stars = $(".review-star");
        var selectedStars = this.parentElement.children.indexOf(this) + 1;
        stars.addClass("glyphicon-star-empty");
        stars.removeClass("glyphicon-star");

        for (var i = 0; i < selectedStars; i++) {
                $(stars[i]).removeClass("glyphicon-star-empty");
                $(stars[i]).addClass("glyphicon-star");
        }
}

Na začátku scriptu je dobré možná ještě označit několik hvězdiček do výchozího stavu, což lze udělat několika cestami, například zavoláním metody (javascriptové, nikoli jQuery) click() na objekt hvězdičky.

stars[2].click();

Gratuluji. Script máme hotový, můžeme jej vyzkoušet. Přidejme si do formuláře nějaké potvrzovací tlačítko a sledujme, že můžeme vybírat hvězdičky a jak se při odeslání formuláře počet vybraných hvězdiček umístí do adresního okna prohlížeče.

Hotové hvězdičkové hodnocení v JavaScriptu

 

Stáhnout

Staženo 128x (1.98 kB)
Aplikace je včetně zdrojových kódů v jazyce javascript

 

 

Článek pro vás napsal Michal Žůrek (misaz)
Avatar
Jak se ti líbí článek?
7 hlasů
Autor se věnuje tvorbě aplikací pro počítače, mobilní telefony, mikroprocesory a tvorbě webových stránek a webových aplikací. Nejraději programuje ve Visual Basicu a TypeScript. Ovládá HTML, CSS, JavaScript, TypeScript, C# a Visual Basic.
Miniatura
Všechny články v sekci
Hotová řešení v JavaScriptu
Aktivity (1)

 

 

Komentáře

Avatar
Honza Bittner
Šupák
Avatar
Honza Bittner:13.4.2015 22:55

Michal Žůrek (misaz) proč, když už jQuery používáš, jej nevyužíváš všude, kde můžeš? :)

// nezkoušeno, ale idea je asi jasná

var selectedStars = this.parentElement.children.indexOf(this) + 1;
=>
var selectedStars = $(this).index();

Jinak tady jde vidět také dobře poměrná nevýhoda těchto univerzálních fontů, kde musíš odstraňovat jednu třídu a přidávat druhou, místo abys jen toognul jednu.
Ideálním stavem by bylo něco ve stylu "icon" a "icon icon--empty". :)

Odpovědět  +5 13.4.2015 22:55
Milovník Dartu. Student FIT ČVUT. Sleduj mě na https://twitter.com/tenhobi a ptej se na cokoli na https://github.com/...
Avatar
davidh
Člen
Avatar
davidh:29.5.2015 21:19

Zdravím jak docílím toho, abych měl v více formulářů tohoto typu na jedné stránce?

 
Odpovědět 29.5.2015 21:19
Avatar
Odpovídá na davidh
Michal Žůrek (misaz):29.5.2015 22:04

nijak, musíš si to naprogramovat aby to pracovalo v rámci toho divu. Kvůli jednoduchosti s tímto scénářem nepočítáme.

Odpovědět 29.5.2015 22:04
Nesnáším {}, proto se jim vyhýbám.
Avatar
Odpovídá na Michal Žůrek (misaz)
Vít Cigánek:3.12.2015 19:04

Není trošku špatně, že se spoléhá na kod z jiných stranek ať už se to týka jquery a nebo ikonbootstrapu. Když je stránka nedostupná tak to nefunguje, jestli chápu dobře. A to se týka jak knihoven jquery tak bootstrapu v tomto případě. Ja raději všechno cpu přímo na web.

 
Odpovědět 3.12.2015 19:04
Avatar
Odpovídá na Vít Cigánek
Michal Žůrek (misaz):3.12.2015 20:11

má to výhody i nevýhody (ale nevýhod méně). Že by ten server byl nedostupný je dost nepravděpodobné. jedná se o speciální CDN servery, které jsou na to dělané a jsou na jiné doméně, takže se na ně neposílají cookies, čímž je přenos dat mírně rychlejší. Nezabírá to místo na disku mého serveru a pokud v URL není specifikována verze (jakože mi ji z důvodů kompatibilit specifikovanou máme), tak je to vždy i aktuální. I o to bych se musel na svém serveru ručně starat.

Odpovědět 3.12.2015 20:11
Nesnáším {}, proto se jim vyhýbám.
Avatar
Peter Rumanovský:13.12.2016 23:43

Zdravim, neviem najst presne kam to mam pisat preto to pisem sem aj ked je to odveci tema - k JS som sa este nedostal ale snazim sa uz vyse tyzdna poriesit jeden problem a to - mam export dat z webu (HTML) do excelu kde som musel pouzit nasledujuci JS nakolko mi iny v IE 11 nefungoval avsak mam problem a to, ze potrebujem aby export vynechal posledne 3 stlpce. Dakujem za kazdu radu

function fnExcelReport()
        {
              var tab_text="<table border='2px'><tr bgcolor='#87AFC6'>";
              var textRange; var j=0;
              tab = document.getElementById('excel_aktivne'); // id of table

              for(j = 0 ; j < tab.rows.length ; j++)
              {
                    tab_text=tab_text+tab.rows[j].innerHTML+"</tr>";
                    //tab_text=tab_text+"</tr>";
              }

              tab_text=tab_text+"</table>";


              var ua = window.navigator.userAgent;
              var msie = ua.indexOf("MSIE ");

              if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./))      // If Internet Explorer
              {
                 txtArea1.document.open("txt/html","replace");
                 txtArea1.document.write(tab_text);
                 txtArea1.document.close();
                 txtArea1.focus();
                 sa=txtArea1.document.execCommand("SaveAs",true,"excel_aktivne_akcie.xls");
              }
              else //other browser not tested on IE 11
                 sa = window.open('data:application/vnd.ms-excel,' + encodeURIComponent(tab_text));
                return (sa);
        }
 
Odpovědět 13.12.2016 23:43
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 6 zpráv z 6.