EpicWEB.pl

webdesign, programowanie, phat lewt!

Ostatni projekt

ddrpl.com

Ostatnie wiadomości

[HTML5] Dodatkowe informacje o elemencie

HTML5 w jednym ze swoich udogodnień wprowadza bardzo przyjazne rozwiązanie pozwalające na przechowywanie informacji o dowolnym tagu. W celu szybszego zrozumienia o co chodzi, posłużmy się przykładem kodu HTML formularza wraz z walidacją danych:

<input type="text" id="email" name="email" class="text required requiredEmail" />

Istnieje wiele bibliotek JavaScript, służących do walidacji formularza po stronie przeglądarki, które w ten właśnie sposób odnajdują pola, które powinny być wypełnione (posiadają klasę required) i sprawdzają, jaką zawartość powinny posiadać (requiredEmail). Rozwiązanie to oczywiście działało, ale powstawały zbędne, nic nie znaczące klasy CSS.

Jak już wspomniałem, HTML5 pomoże nam i w takim przypadku. A to dzięki możliwości stosowania własnych atrybutów z rodziny data-*. Zamysł jest prosty - autor strony może osadzić dowolną informację używając nowego atrybutu - dane te nie są nigdzie wyświetlane, są one dostępne dla JavaScript oraz CSS (za pomocą funkcji attr()).

Jako autorzy strony posiadamy praktycznie pełną dowolność w wyborze nazwy atrybutu - specyfikacja narzuca jedynie, by nie zawierał on dużych liter. Poprawny przykład:

<input type="text" id="email" name="email" data-validate="true" data-validate-type="email" />

Zgodnie ze specyfikacją, wartości powinny być teraz dostępne jako część zbioru dataset z użyciem notacji CamelCase (znanej także jako Notacja Wielbłądzia):

document.getElementById('email').dataset.validate;
document.getElementById('email').dataset.validateType;

Niestety, do czasu implementacji tego rozwiązania przez przeglądarki dane te nie są dostępne i musimy dostać się do nich w inny sposób:

document.getElementById('email').getAttribute('data-validate');
document.getElementById('email').getAttribute('data-validate-type');

Na szczęście powyższe "obejście" problemu działa bez problemu na wszystkich liczących się przeglądarkach.

Poza oczywistym przykładem przechowywania danych na potrzeby walidacji nowy atrybut umożliwia np. sortowanie zestawów danych (tabel) po danych nie widocznych, lub wyświetlanych dla użytkownika w sposób trudny do zrozumienia dla skryptów, np:

<li data-date="2010-07-07T07:58:12"><a href="#">Spis wydarzeń w dniu 7 lipca, roku 2010</a></li>

[PHP/CSS/HTML] Kilka zakurzonych przykładów

Przy okazji porządków na serwerze znalazłem kolekcję swoich starych skryptów i innych dokumentów publikowanych jeszcze na starym blogu. Ponieważ wiem, że niektóre z nich jeszcze mogą się komuś przydać postanowiłem pomóc Google, które linkuje niemiłosiernie do nie istniejących już adresów i wrzucić skrypty do sieci.

Chciałbym przypomnieć, że skrypty te mogą być nie aktualne, mogą nie odzwierciedlać aktualnie stosowanych metod, nie działać czy też być proste do odtworzenia w totalnie lepszy sposób - jest to do przewidzenia, zważywszy, że większość z nich ma ponad dwa lata.

Poniżej lista z krótkimi opisami:

Jeszcze raz - to są stare skrypt, które mogą być już nie aktualne - proszę o nie wytykanie błędów ;-)

[CSS] "Odznaki" w czystym CSS.

Wraz z tym jak co raz więcej przeglądarek zaczyna obsługiwać nowe kolejne wersje CSS możliwe jest stosowanie coraz to nowych technik, w celu osiągnięcia efektów, które do tej pory wymagały przemyślnych tricków HTML/CSS/JS albo stosowania grafiki.

Jednym z takich elementów są "odznaki", zwykle dodawane do produktu czy usługi w celu zakomunikowania klientowi, że są one godne jego uwagi - przykładowa odznaka wygląda tak:

CSS3!

Zwykle w celu zastosowania takiego rozwiązania przygotowuje się obrazek graficzny z gwiazdką, czy też innym kształtem i umieszcza go na stronie jako obrazek czy też tło znacznika HTML. Jeżeli mamy kilka rozmiarów lub kolorów - trudno, robimy albo kilka obrazków, albo - dla trochę bardziej zaawansowanych - używamy odwrotnego obrazku jako maski kadrującej tło.

Na szczęście z nadejściem wsparcia dla nowszego CSS możliwe stało się wstawienie takiego (oraz podobnych) elementów bez użycia grafiki. Na początek pokażę co chcemy osiągnąć:

CSS3!

Wygląda tak samo (prawie) jak wyżej? Super - Twoja przeglądarka wspiera "zaawansowane" właściwości CSS. Nie wygląda tak samo? Przestań używać IE. Niestety, nawet IE9 preview nie wspiera w tym momencie zastosowanych tu technik, więc musisz sam siebie zapytać, czy IE nie stanowi większości Twoich odbiorców. Nie? Świetnie - przystąpimy do sekcji elementu. Na pierwszy ogień HTML:

<span class="badge"><span><span>CSS3!</span></span></span>

Jak widać, nie ma obrazków - są za to 3 zagnieżdżone elementy - w tym wypadku span, ale jeżeli np. chcesz, by element był klikalny i dobry dla SEO nic nie stoi na przeszkodzie by zamienić kombinację na np.:

<a class="badge"><span><strong>OKAZJA!</strong></span></a>

Ok, HTML wydaje się prosty - zostaje nam zatem CSS:

.badge,
.badge span {
    display: inline-block;
    width: 40px;
    height: 40px;
    background: red;
    color: white;
    line-height: 40px;
    text-align: center;
    -moz-transform: rotate(30deg);
    -webkit-transform: rotate(30deg);
    -o-transform: rotate(30deg);
    rotation: 30deg;
}

.badge {
    -moz-transform: rotate(300deg);
    -webkit-transform: rotate(300deg);
    -o-transform: rotate(300deg);
    rotation: 300deg;  
}

Ok, bez paniki - tak na prawdę jest to prostsze niż wygląda. Większość właściwości znamy już z poprzednich wersji CSS. display: inline-block oczywiście nakazuje traktowanie obiektu jako element blokowy, jednak pozostaje on w linii z tekstem, width i height określają szerokość i wysokość naszej odznaki. Dochodzi za to jedna nowa własność - rotation (zapisy -*-transform: rotate przeznaczone są dla konkretnych przeglądarek, samo rotation jest proponowane w standardzie CSS i niejako zapewnia nam kompatybilność, kiedy już właściwość ta będzie w pełni obsługiwana).

Co mówi nam ta właściwość? Prosto się domyśleć - nakazuje, by przeglądarka po wyrenderowaniu elementu obróciła go o podaną wartość wyrażoną w stopniach wg. jego środka. Jak widać przy 3 elementach suma obrotów sprowadza się do 360°, tak, by napis był w odpowiedniej postaci. De-facto nasza gwiazdka składa się z 3 nałożonych na siebie elementów:

    CSS3!

Oczywiście odpowiednio modyfikujące (dodając kolejne span) kod HTML oraz CSS (zmniejszając kąt oraz dobierając width/height) możemy zwiększyć ilość ramion naszej gwiazdy. A Ci, którzy wolą kwiatki, mogą zastosować jeszcze border-radius:

CSS3!

Oczywiście zdaję sobie sprawę, że póki IE nie zacznie obsługiwać poprawnie CSS nie ma co marzyć o stosowaniu takich technik w komercyjnych rozwiązaniach, ale samorozwój jest zawsze pożądany ;)

Aktualizacja

Wasacz, w komentarzu wypomina mi, że efekt ten można stworzyć także w CSS z wykorzystaniem selektora :after: oraz :before - i rzeczywiście jest taka możliwość:

CSS3!

By osiągnąć taki efekt musimy użyć nieco bardziej zawiłego CSS:

.badgeSt:after,
.badgeSt:before,
.badgeSt {
    display: inline-block;
    width: 40px;
    height: 40px;
    background: red;
    color: white;
    line-height: 40px;
    text-align: center; 
    position: relative;
}

.badgeSt:after 
.badgeSt:before {
    z-index: -1;
    content: "";   
    position: absolute;
    top: 0;
    left: 0;           
}

.badgeSt:after {
    -moz-transform: rotate(30deg);
    -webkit-transform: rotate(30deg);
    -o-transform: rotate(30deg);
    rotation: 30deg;  
}

.badgeSt:before {
    -moz-transform: rotate(-30deg);
    -webkit-transform: rotate(-30deg);
    -o-transform: rotate(-30deg);
    rotation: -30deg;
}

Pojawiają się dwa nowe zagadnienia - wspomniane :after, :before oraz właściwość content. Selektory pozwalają nam na stworzenie i ostylowanie elementu HTML który zostanie umieszczony (odpowiednio) za oraz przed zawartością wskazanego elementu - tak jakby został on na sztywno wpisany do znacznika. Nowo utworzony element nie jest jednak żadnym znacznikiem (nie jest to ani span, ani stron etc.) więc by został wyświetlony musimy wstawić do niego jakąś zawartość - chociażby pusty łańcuch znaków - tu właśnie wkracza kolejna nowość czyli content. Parametr ten pozwala nam na określenie zawartości znacznika za pomocą CSS (więcej w specyfikacji). Dla poprawy wyświetlania musimy jeszcze zastosować z-index tak, by nasz tekst był na wierzchu.

PHP - generowanie mapy witryny

Generowanie mapy witryny - prosta, wydawało by się - rzecz. Jednak, kiedy w naszej firmie pojawiło się wolne stanowisko programisty postanowiliśmy właśnie takie zadanie dać kandydatom do zrealizowania, w celu odsiania "programistów" od programistów.

Zadanie okazało się jednak wykraczające poza wszelkie normy i na jakieś 20 osób (na przestrzeni 5 miesięcy) udało się je zrobić 5. Z tego dwie skopiowały (nie do końca działające) rozwiązania z sieci...

Twoje zadanie - mając tabelę (CREATE TABLE `_tree` (`id` INT(11), `parent` INT(11), `sort` INT(11), `nazwa` VARCHAR(255))) napisz skrypt, który wygeneruje mapę witryny w HTML (w dowolnym standardzie). Większość osób zaczyna od napisania prostego zapytania wyciągającego wszystkie wpisy z parent = 0. Nieliczni dodadzą jeszcze sort. Później, jeżeli ktoś już to zrobi przystępuje do zagnieżdżania kolejnych poziomów while() a nam ręce opadają ...

Dlatego, drogi poszukiwaczu odpowiedzi w sieci, poniżej zamieszczam dwa rozwiązania - wykuj się ich na pamięć, przyjdź do nas i pewnie dostaniesz posadkę ...

Rozwiązanie 1 - rekurencja - dużo zapytań do SQL, mało myślenia:

function lev($parent) {
	$query = mysql_query('SELECT * FROM `_tree` WHERE `parent` = '.(int)$parent.' ORDER BY `sort` ASC');
	if(mysql_num_rows($query)) {
		echo '<ul>'."\n";
		while($dane = mysql_fetch_array($query, 1)) {
			echo '<li>'."\n";
			echo $dane['nazwa']."\n"; 
			lev($dane['id']);
			echo '</li>'."\n";
		}
		echo '</ul>'."\n";
	}
}

lev(0);

Rozwiązanie 2 - jedno zapytanie, nieco więcej myślenia:

function getData($parent) {
    $query = mysql_query('SELECT * FROM `_tree` WHERE `parent` >= '.(int)$parent.' ORDER BY `parent` ASC, `sort` ASC');
    $return = array();
    while($dane = mysql_fetch_array($query, 1)) {
        $return[] = $dane;
    }
    return $return;
}

function sortData($data, $root = 0, $level = 0) {
    static $return = array();
    foreach($data as $item) {
        if($item['parent'] == $root) {
            $item['level'] = $level;
            $return[] = $item;
            sortData($data, $item['id'], $level+1);
        }
    }
    return $return;    
}
foreach(sortData(getData(0)) as $item) {
    echo str_repeat('&nbsp;', $item['level'] * 5).$item['nazwa'].'<br />';
}

Niech mi ktoś powie, że to jest mega skomplikowane? Dzisiaj pojawił się jeden człowiek, który był po 2 kierunkach na Politechnice Łódzkiej. Po godzinie nic nie zrobił. Drugi - stwierdził, że pracował w Prado (taki framework) - więc zainstalował sobie WAMP na laptopie, zassał Prado i ... po 2 godzinach wyszedł bez "do widzenia".