czwartek, Grudzień 4th, 2008

jQuery: Okno z potwierdzeniem

Pozostajemy przy tematyce praktycznych zastosowań jQuery. Potrzebowałem dzisiaj napisać okno potwierdzające jakąś operację w panelu administracyjnym. Sprawa wydaje się prosta i można by temat rozwiązać, zapominając o JavaScript ( Confirm ) albo PHP, ale zabawa polega na tym, jak to zrobić, żeby się nie narobić i jeszcze, żeby efekt był naprawdę przyzwoity?
Postaram się przedstawić przykładowe rozwiązanie problemu, przy założeniu, że element, który chcemy, aby został opatrzony potwierdzeniem przez użytkownika, jest linkiem.

1. Przykładowy plik HTML

Rozpoczynamy od pliku, na którym będziemy wykonywać nasze nikczemne testy:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Okno z potwierdzeniem</title>
</head>
<body>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque ultrices orci quis nisl. Aliquam at dolor. Sed consequat quam ac leo. Curabitur fringilla sodales sem. Praesent eleifend mauris ac ante dictum aliquet. Etiam sapien nulla, consequat eget, consequat vitae, molestie id, lectus. In hac habitasse platea dictumst. Aliquam feugiat odio ac lectus. Suspendisse egestas varius nisl. Morbi nulla. Pellentesque aliquet interdum felis. Vestibulum euismod luctus libero. Suspendisse sodales interdum enim. Pellentesque orci. Nullam massa nunc, eleifend vel, eleifend varius, congue eget, leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br/>
Cras aliquet, ligula quis rutrum accumsan, lorem velit dignissim lorem, fermentum dignissim ligula quam at ligula. Nulla dictum interdum purus. Aenean odio. Vestibulum pretium. Phasellus enim enim, semper aliquet, tempus ac, rutrum gravida, libero. Etiam neque odio, blandit nec, suscipit vel, pellentesque scelerisque, leo. In id metus. Vivamus rutrum. Nullam nec velit. Ut purus nisi, porta at, tincidunt sit amet, scelerisque pulvinar, sem. Sed adipiscing risus. In nisi. In et augue. Phasellus ullamcorper urna quis lacus tempus dapibus. Sed eget est. Etiam tellus erat, adipiscing nec, placerat sed, ultricies a, orci. Cras ac lectus. Curabitur mattis lorem nec nibh. <a href="http://poslinski.net" class="confirm">Maecenas</a> aliquet iaculis turpis.
</p>
<div id="confirm"></div>
</body>
</html>

Przykładowy tekst z generatora Lorem ipsum, trafił wewnątrz znacznika p. Zaraz przed zamknięciem znacznika body, umieściliśmy div#confirm, wewnątrz którego znajdować się będzie kod z naszym oknem do potwierdzania.

2. Warstwa prezentacji

Skupmy się na naszym oknie. W moim przypadku, jego kod html który będzie odpowiadał za całe okno, wyglądać będzie następująco:

<div id="confirm">
<div>
<div>
<h1>Czy na pewno chcesz usunąć ten element?</h1>
<p><button onClick="location.href='TUTAJ TRAFIAĆ BĘDZIE ZAWARTOŚĆ POLA HREF Z LINKU'"> TAK </button> <button> NIE </button></p>
</div><!-- end #confirm div div -->
</div><!-- end #confirm div -->
</div><!-- end #confirm -->

Kod wewnątrz #confirm, wygenerowany zostanie przez JavaScript. Warto jednak zastanowić się, dlaczego wygląda właśnie tak i dlaczego znajduje się na samym dole kodu strony?

Zacznijmy od przyczyny umieszczenia kodu na końcu. Określając position: absolute, dla #confirm, bez parametru z-index, kolejność obiektów z position: absolute, będzie odpowiadać kolejności w jakiej zostaną wygenerowane przez przeglądarkę. Ostatnio wygenerowane, pojawią się najwyżej stosu warstw z position: absolute, zatem, jeśli będą miały np. takie same wymiary, zasłonią warstwy, które pojawiły się w kodzie wcześniej.

Dlaczego wewnątrz confirm, umieściliśmy 2 razy div? Do wyjaśnienia tej kwesti, wystarczy zapoznać się z fragmentem kodu css, który umieścimy wewnątrz sekcji head:

<style type="text/css">
<!--
* { margin: 0px; padding: 0px; }
body { margin: 10px; }
p { width: 600px; margin: 0 auto; line-height: 25px; }

/* CONFIRM */
#confirm { display: none; position: absolute; height: 100%; width: 100%; background: #000; top: 0; left: 0; }
#confirm { height: expression(((window.Enumerable && window.Enumerable.max) ? [document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight].max() : document.documentElement.scrollHeight) + 'px' ); width: expression(((window.Enumerable && window.Enumerable.max) ? [document.body.scrollWidth, document.documentElement.scrollWidth, document.body.offsetWidth, document.documentElement.clientHeight].max() : document.documentElement.scrollWidth) + 'px' );  }
#confirm[id] { position:fixed; }
#confirm div { padding: 10px; margin-top: 200px; }
#confirm div div { background: #900c0c; width: 500px; margin:0 auto; border: 1px solid #CCC; overflow: hidden; }
#confirm div div h1 { font-size: 18px; color: #FFF; }
#confirm div div p { padding: 20px; }
-->
</style>

#confirm określa tutaj tło, które będzie „przykrywać” całą stronę. Druga linijka, (ta z dziwnym height i width), konieczna jest w przypadku Internet Explorer. #confirm[id] zrozumiały jest tylko dla nowocześniejszych przeglądarek i takie było zamierzenie, aby tło naszego okna miało rozmiar 100% na 100% i przewijało się razem ze stroną ( dla IE jest obliczane każdorazowo na bazie aktualnej szerokości i wysokości okna ).

Pierwszy div jest konieczny, aby wyśrodkować 2gi oraz, aby zrobić odstęp od góry okna po przez margin-top. Drugi div określa już nasze okno do potwierdzania, które może zostać wyśrodkowane, ponieważ znajduje się wewnątrz elementu blokowego z width: 100% ( Standardowa wartość dla elementu z display: block – którym jest div )

3. Czas na jQuery

Teraz pozostaje nam odpowiednio zareagować na kliknięcie linka, który znajduje się pod koniec bloku p, w którym umieściliśmy lorem ipsum’a:

<a href="http://poslinski.net" class="confirm">Maecenas</a>

W naszym przypadku, wszystkie linki z klasą confirm, będą reagowały na nasz skrypt. Możemy np. zastosować nasze potwierdzenie dla wszystkich linków, pozwalających na usuwanie jakiejś wartości z bazy danych.

Teraz wymagany kod JavaScript, który umieszczamy na dole strony:

<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".confirm").click(function(){
$("#confirm")
.css({opacity:0.95})
.fadeIn()
.html('<div><div><h1>Przekierować?</h1><p><button onClick=\"location.href=\'' + $(this).attr("href") + '\'\"> TAK </button> <button> NIE </button></p></div></div>');
return false;
});
$("#confirm").click(function(){$(this).fadeOut();});
});
</script>

W pierwszej linii ładujemy jQuery.

Następnie, główna gałąź naszego kodu $(document).ready, uaktywnia nasz kod, po pełnym załadowaniu strony.

Reagujemy na kliknięcie w element z klasą confirm, wywołując w tym przypadku serie metod, na elemencie o id=confirm. Na początek, dodajemy przeźroczystość (element wciąż jednak ma ustawione display: none), następnie korzystając z metody fadeIn, jQuery płynnie przechodzi z display: none do opacity: 0.95 ( w naszym przypadku ). Na koniec, wewnątrz elementu z #confirm, ładujemy kod html z naszymi dwoma divami, wewnątrz których umieszczamy nagłówek h1 oraz dwa przyciski button. Jak pewnie, zauważyliścię, jeden z nich, dodatkowo posiada zadeklarowane zdarzenie onClick, które będzie reagować na pozytywne potwierdzenie użytkownika, przekierowywując go do miejsca, które wskazywał kliknięty link.

Dlaczego return false na końcu tego bloku kodu? Aby przeglądarka, nie przekierowywała nas automatycznie, po kliknięciu na link, nasza funkcja musi zwracać wartość false, w przeciwnym wypadku nastąpi przekierowanie i z okna potwierdzającego będą nici.

Jeżeli klikniemy gdziekolwiek indziej, niż w button z „TAK„, korzystając ze zdarzenia fadeOut(), płynnie zniknie blok z naszym potwierdzeniem, co realizuje $(„#confirm”).click( … ).

Całość napisanego kodu powinna wyglądać, mniej więcej tak:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Okno z potwierdzeniem</title>
<style type="text/css">
<!--
* { margin: 0px; padding: 0px; }
body { margin: 10px; }
p { width: 600px; margin: 0 auto; line-height: 25px; }

/* CONFIRM */
#confirm { display: none; position: absolute; height: 100%; width: 100%; background: #000; top: 0; left: 0; }
#confirm { height: expression(((window.Enumerable && window.Enumerable.max) ? [document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight].max() : document.documentElement.scrollHeight) + 'px' ); width: expression(((window.Enumerable && window.Enumerable.max) ? [document.body.scrollWidth, document.documentElement.scrollWidth, document.body.offsetWidth, document.documentElement.clientHeight].max() : document.documentElement.scrollWidth) + 'px' );  }
#confirm[id] { position:fixed; }
#confirm div { padding: 10px; margin-top: 200px; }
#confirm div div { background: #900c0c; width: 500px; margin:0 auto; border: 1px solid #CCC; overflow: hidden; }
#confirm div div h1 { font-size: 18px; color: #FFF; }
#confirm div div p { padding: 20px; }
-->
</style>
</head>
<body>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque ultrices orci quis nisl. Aliquam at dolor. Sed consequat quam ac leo. Curabitur fringilla sodales sem. Praesent eleifend mauris ac ante dictum aliquet. Etiam sapien nulla, consequat eget, consequat vitae, molestie id, lectus. In hac habitasse platea dictumst. Aliquam feugiat odio ac lectus. Suspendisse egestas varius nisl. Morbi nulla. Pellentesque aliquet interdum felis. Vestibulum euismod luctus libero. Suspendisse sodales interdum enim. Pellentesque orci. Nullam massa nunc, eleifend vel, eleifend varius, congue eget, leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br/>
Cras aliquet, ligula quis rutrum accumsan, lorem velit dignissim lorem, fermentum dignissim ligula quam at ligula. Nulla dictum interdum purus. Aenean odio. Vestibulum pretium. Phasellus enim enim, semper aliquet, tempus ac, rutrum gravida, libero. Etiam neque odio, blandit nec, suscipit vel, pellentesque scelerisque, leo. In id metus. Vivamus rutrum. Nullam nec velit. Ut purus nisi, porta at, tincidunt sit amet, scelerisque pulvinar, sem. Sed adipiscing risus. In nisi. In et augue. Phasellus ullamcorper urna quis lacus tempus dapibus. Sed eget est. Etiam tellus erat, adipiscing nec, placerat sed, ultricies a, orci. Cras ac lectus. Curabitur mattis lorem nec nibh. <a href="http://poslinski.net" class="confirm">Maecenas</a> aliquet iaculis turpis.
</p>
<div id="confirm"></div>
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".confirm").click(function(){
$("#confirm")
.css({opacity:0.95})
.fadeIn()
.html('<div><div><h1>Przekierować?</h1><p><button onClick=\"location.href=\'' + $(this).attr("href") + '\'\"> TAK </button> <button> NIE </button></p></div></div>');
return false;
});
$("#confirm").click(function(){$(this).fadeOut();});
});
</script>
</body>
</html>

Podsumowanie

Działający przykład, można zobaczyć tutaj.

To przykładowe rozwiązanie, nie zakłada wszystkich możliwości. Możemy kod rozbudować tak, aby potwierdzenie działało także dla formularzy, należało by wtedy sterować wysyłaniem formularza, co również możemy dokonać z poziomu jQuery. Można również, na bazie powyższego kodu stworzyć plugin do jQuery. Zapraszam do dyskusji w komentarzach do tego postu.

Be Sociable, Share!

Kategorie: jquery
Możesz śledzić komentarze do tego wpisu poprzez kanał RSS 2.0. Możesz również napisać własny komentarz, lub umieścić odnośnik do tego wpisu, na swojej stronie.

Jeden komentarz

Listopad 5, 2013

kod bardzo czytelny i łatwy do implementacji. serdecznie pozdrawiam


  • *

    Spam Protection by WP-SpamFree