search check home clock-o tag tags chevron-left chevron-right chevron-up chevron-down twitter facebook github rss comment comments terminal code

[HTML5][jQuery] Jak stworzyć własne menu kontekstowe na stronie WWW?

[HTML5][jQuery] Jak stworzyć własne menu kontekstowe na stronie WWW?

Menu kontekstowe nie jest niczym nowym w aplikacjach desktopowych. Korzystamy z tego wygodnie na co dzień. Jednak, menu kontekstowe na stronie byłoby nowością i to całkiem użyteczną. W tym artykule zostanie opisany sposób na utworzenie menu podręcznego wraz z kilkoma akcjami jakie będzie można wykonać dzięki niemu.

Struktura HTML5

Na początek trzeba przygotować odpowiednią strukturę HTML zawierającą odpowiednie elementy ze specyfikacji HTML5. Struktura wygląda następująco:

<section>
	<menu type="context" id="hiddenmenu">
		<menuitem onclick="blockInput();" id="blockInput" label="Zablokuj pola" icon="images/PNG/Zip.png"></menuitem>
		<menuitem onclick="unblockInput();" id="unblockInput" label="Odblokuj pola" icon="images/PNG/Vector.png"></menuitem>
		<menuitem onclick="validateInput();" id="validateInput" label="Sprawdź poprawność pól" icon="images/PNG/RSS.png"></menuitem>
		<menuitem onclick="clearInput();" id="clearInput" label="Wyczyść pola" icon="images/PNG/Folder.png"></menuitem>
	</menu>
	<form action="index.php" method="post" contextmenu="hiddenmenu">
		<ul>
			<li>
				<label for="name">Nazwa: </label>
				<input type="text" name="name"/>
			</li>
			<li>
				<label for="mail">Email: </label>
				<input type="text" name="mail"/>
			</li>
			<li>
				<label for="kod">2+2=?: </label>
				<input type="text" name="kod"/>
			</li>
			<li>
				<input type="submit" name="submit" value="Wyślij" />
			</li>
		</ul>
	</form>
</section>

Wykorzystano tutaj nowy element: menu do którego został przypisany atrybut typu: context. Wewnątrz elementu menu znajdują się jego pozycje zapisane jako: menuitem. Każda pozycja ma przypisaną akcję za pomocą atrybutu: onclick oraz etykietę za pomocą atrybutu: label. Dodatkowo, można dołączyć plik z grafiką jako ikonę pozycji. Można to zrobić za pomocą atrybutu: icon.

Do formularza został dodany atrybut: conextmenu wraz z nazwą menu, które będzie menu kontekstowym dla formularza. Dzięki temu, przeglądarka będzie wiedziała do którego elementu będzie przypisane dane menu. Można stworzyć wiele róznych menu dla wielu różnych elementów. Wszystkie są przydzielane wedle id menu.

Akcje menu z wykorzystaniem jQuery

Aby powyższa struktura spełniała swoją funkcję menu kontekstowego należy utworzyć kod, który będzie odpalany po kliknięciu w taką pozycję. Zostały zdefiniowane 4 akcje: blokada i odblokowanie pól, walidacja pól (prymitywna) oraz czyszczenie pól. Do każdej z nich jest przypisana osobna funkcja zapisana w JS.

Funkcja blokowania pól

function blockInput() 	{
	//dodaj atrybut disabled do wszystkich elementów input typu text
	$('input[type="text"]').prop('disabled',true);
};

Funkcja odblokowywania pól

function unblockInput() {
	//usuń atrybut disabled wszystkich elementów input typu text
	$('input[type="text"]').removeProp('disabled',true);
};

Funkcja walidacji pól

function validateInput() {
	//tekst ostrzeżeń wyświetlanych w trakcie przeprowadzania walidacji
	var emptyAlert 	= 'To pole nie może być puste!';
	var invalidMail	= 'Adres email jest niepoprawny!';
	var wrongText	= 'Wpisz poprawne dane w pole!';
	//wyszukujemy wszystkie elementy input typu tekstowego i dokonujemy walidacji
	$('input[type="text"]').each(function() {
		//definiujemy skróconą wersję odniesienia do elementu
		var i	= $(this);
		//pobieramy wartość elementu
		var val = i.val();
		//pobieramy wartość elementu o nazwie kod
		var kod = $('input[name="kod"]').val();
		//jeśli długość tekstu jest równa 0 to wpisz w danym polu tekst ostrzeżenia i dodaj odpowiednią klasę
		if(val.length==0) {
			if(i.hasClass('error'))
				i.val(emptyAlert);
			else
				i.val(emptyAlert).addClass('error');
		}
		//jeśli pole podczas walidacji nie ma poprawionych wartości pól wyświetl alert
		else if(val==emptyAlert || val==invalidMail || kod!=4)
			alert(wrongText);
		else {
			if(i.hasClass('error'))
				i.removeClass('error',500);
		}
	});
};

Funkcja czyszczenia pól

function clearInput()	{
	$('input[type="text"]').each(function() {
		//animuj usuwanie tekstu z pola
		$(this).animate({
            	'color': '#fff'
        	}, 500, 'linear', function(){
            	$(this).val('').css('color','#000');
        	});
		//animuj usuwanie klasy
		if($(this).hasClass('error'))
			$(this).removeClass('error',500);
	});
}

Podsumowanie

Mając zdefiniowany kod strony tak jak to zostało przedstawione powyżej osiągniemy efekt menu kontekstowego z dodatkowymi opcjami dla naszej strony. Należy pamiętać o tym, aby dołączyć bibliotekę jQuery oraz jQuery UI, aby cały mechanizm działał poprawnie.
Niestety, efekt będzie widoczny tylko w najnowszej wersji Firefoxa. Szkoda, bo to jest bardzo ciekawy efekt, który na pewno przyniósłby dużo pożytku. Z niecierpliwością będę czekał na implementację odpowiednich tagów i atrybutów w innych przeglądarkach.

Demo z tego artykułu jest dostępne tutaj: HTML5 menu kontekstowe

AKTUALIZACJA

Właśnie się pojawił plugin do jQuery, który dodaje obsługę kontekstowego menu także do innych przeglądarek. Plugin można znaleźć TUTAJ.

  • Michał

    Znalazłem jeden błąd. Po zablokowaniu pól, klikając na nie prawym przyciskiem myszy nie pojawia się menu.

  • Świetne, nie słyszałem o tej możliwości html5.

    Dla starszych przeglądarek można by dodać obsługę zdarzenia ‚contextmenu’ i wyświetlać menu samodzielnie.
    Jedną z wad jest to, że nadpisuje to domyślne menu kontekstowe zamiast dopisywać do niego pojedyncze własne elementy.

  • Piotr Nalepa

    Nie trzeba klikać pól bezpośrednio. Można klikać obszar formularza.

  • joru

    ?Niestety, efekt będzie widoczny tylko w najnowszej wersji Firefoxa.? a ja tam wole, jak strona za dużo nie może, strona mogąca zablokować możliwość prawokliku nie jest fajna

  • Piotr Nalepa

    W sensie, dodanie obsługi zdarzenia „contextmenu” powoduje nadpisywanie domyślnego menu kontekstowego, zamiast dopisywania pozycji do menu jak to ma miejsce w przykładzie, tak?

  • Bardzo fajny artykuł. HTML5 daje ogromną moc. Nie słyszałem wcześniej o takiej możliwości. Czekam na kolejne odsłony HTML5 z Twojej strony 🙂

  • Świetna sprawa!

    Propozycja rozwinięcia skryptu: wykonanie post przez jQuery z dodatkowym parametrem (żeby nie wykonywał dodania / edycji, czy czegokolwiek, tylko walidował) i zwrócenie odpowiedzi (np. JSON) przez skrypt obsługujący wysłane dane odnośnie poprawności danych.

  • Piotr Nalepa

    To jest ciekawa opcja do zrobienia. Dla chętnego nic trudnego. Na potrzeby tego artykułu wystarcza jednak to co jest.

  • Kshyhoo

    Brak obrazka „Commmand.png”.

  • Comandeer

    Fajna rzecz. Tylko, że lisek korzysta z niestandardowego menuitem, zamiast z command. i IMO powinno zastępować domyślne menu, a nie dodawać komendy (albo przynajmniej powinna być możliwość podmiany)