Stránkovanie

Posledné dve kapitoly boli takmer čisto teoretické, tak aby sme vás neunudili k smrti, dáme si zase kus programovania. V tejto kapitole sa vrátime k našej galérii obrázkov a naučíme sa na nej ďaľšiu veľmi praktickú a používanú vec. Určili sme si, že naša galéria bude obsahovať 7 obrázkov a všetky tieto obrázky sme zobrazili na stránke (ich miniatúry). Čo ale v prípade, že by naša galéria obsahovala 20, 50 alebo 200 obrázkov? Zobrazovali by sme ich všetky naraz na jednej stránke? Asi nie, jednak by to bolo neprehľadné a na druhej strane by to dosť spomalilo načítanie stránky, kým by sa všetky miniatúry načítali.

 

Pri zobrazovaní podobných prvkov na stránke (obrázky, články, správy...), ktorých počet je rôzny a očakáva sa, že bude vyšší, sa používa tzv. stránkovanie (pagination). Je to v podstate rozdelenie prvkov na viac stránok, kde na každej stránke je zobrazený len predom určený maximálny počet prvkov. Takže povedzme, že maximum zobrazených fotiek/obrázkov na jednej stránke v našej galérii bude 12. Na prvej stránke sa zobrazia fotky s poradovým číslom 1-12, na druhej stránke 13-24, na tretej 25-36 atď. Určite sa s tým stretávate denne, ak si prezeráte nejaký z informačných portálov/denníkov/bulvárov, na ktorých je možné nájsť množstvo článkov. Pri výpise článkov sú väčšinou zoradené chronologicky, kde navrchu je najnovší článok. Ak sa dostanete na koniec zoznamu, nachádza sa tam väčšinou tlačidlo ďalšie články, ďalšia strana alebo šípka doprava, niekedy sa tam vyskytujú rovno čísla na konkrétne stránky (1, 2, 3, 4...). To isté môžete nájsť pri prezeraní galérií obrázkov na webe. Presne toto je stránkovanie.

 

Čo to stránkovanie predstavuje pre nás ako programátorov po technickej stránke? Pri vyriešení tohto problému nie je nutné vedieť žiadny nový príkaz ani funkciu ani nič iné, teoreticky by ste to mohli už zvládnuť. Je na to nutné však troška porozmýšlať a použiť aj nejaké logické výpočty. Poďme si rozobrať našu úlohu ako zadanie. Máme povedzme 30 obrázkov a chceme ich zobraziť pomocou stránkovania, kde na jednej stránke bude maximálne 12 obrázkov. Po navštívení našej stránky s fotogalériou by sa malo zobraziť prvých 12. Toto by sme ešte zvládli ako nič. Následne musí mať používateľ možnosť na niečo kliknúť (zrejme odkaz), čo mu zabezpečí zobrazenie obrázkov 13-24 alebo 25-30. Keďže chceme byť stále na tej istej stránke, odpoveď na zadanie zobraziť tú istú stránku, ale v rôznych stavoch – s rôznym obsahom, musí pre nás okamžite indikovať použitie parametra v URL. Takže naše odkazy musia mať nejakú hodnotu parametra, ktorý bude určovať, ktoré obrázky sa zobrazia.

 

Keďže sa to volá stránkovanie, hodnota parametra by nemalo byť nič iné, ako poradové číslo stránky. Takže, hodnota tohto parametra pri zobrazení stránky by mala byť braná ako prvá (hodnota 1). Odkazy na ďalšie stránky by mali niesť hodnotu parametra 2,3,4 atď. podľa potreby. Pri slovnom spojení podľa potreby by som sa pozastavil, je to prvý problém, ktorý treba tak troška logicky vyriešiť. Povedzme, že nevieme, či bude obrázkov 70 alebo 550. Otázka je, koľko čísiel/odkazov na jednotlivé stránky potrebujeme, aby mal používateľ možnosť zobraziť všetky orbázky? Áno, keďže je to opakujúca sa činnosť, použijeme na vypísanie odkazov cyklus. Kedy ale skončí? Budeme musieť pre ukončenie použiť nejakú logickú podmienku/logický postup, aby sa skončilo vtedy, keď sa na poslednej stránke zobrazí posledný obrázok, čiže nejako použiť číslo 12, ktoré určuje počet prvkov na jednej stránke, číslo 30, ktoré v tomto prípade definuje celkový počet obrázkov a poradové číslo stránky. Násobok dvanástky a poradového čísla stránky nám indikuje, koľko obrázkov už akokeby máme zahrnutých jendotlivými odkazmi.

 

Druhý problém, na ktorého riešenie sme už troška napovedali v predošlom odstavci je, určiť začiatok a koniec cyklu, ktorý vypisuje obrázky na konkrétnej stránke. To znamená, že ak nám príde hodnota parametra napríklad 2 (poradové číslo stránky), ako určíme začiatočné a koncové číslo obrázka (začiatok a koniec cyklu for), ktorý sa má zobraziť. Toto číslo je v podstate indexom poľa s obrázkami. Logicky, pre začiatok to bude číslo 12 násobené poradovým číslom stránky mínus 1 (12*(poradove-1)). Dúfam, že chápete to mínus 1, ak sme na prvej stránke, nemôže byť začiatočná fotka - index 12 ale 0. Koncová preto bude 12 násobené poradovým číslom stránky (12*1), pri indexe to bude ešte celé mínus 1, lebo rátame indexy poľa od nuly. Celú vedu stránkovania sme už v podstate vyriešili, stačilo si rozobrať problém slovne dopodrobna, čo to vlastne chceme a tým sme aj prišli na to, čo musíme zabezpečiť. Keďže už vieme, čo potrebujeme, skúsme si to zapísať do kódu, ktorý by mohol vyzerať nejako takto:

 

fotogaleria.php:

<?php

$pictures = array();

for($i = 0; $i < 30; $i++){
    $pictures[] = 'images/placeholder.jpg';
}

//zadefinovanie maximalneho poctu pre jednu stranku a nacitanie parametra (urcenie aktualnej stranky)
$countPerPage = 12;
if($_GET['page']){
    $page = $_GET['page'];
}else{
    $page = 1;
}

//vypocet od ktorej po ktoru fotku zobrazujeme galeriu
$start = ($page-1)*$countPerPage;
$end = $page*$countPerPage;

echo '<ul id="gallery">';
for($i = $start; $i < $end; $i++){

    if($pictures[$i]){
        echo '<li>';

            echo '<a class="left';
            if(($i+1)%3){
                echo ' photo-margin';
            }
            echo '" target="_blank" href="'.$pictures[$i].'">';

                echo '<img src="'.$pictures[$i].'">';
            echo '</a>';
        echo '</li>';
    }
}
echo '</ul>';

//cyklus, ktory nam vypise dostatocny pocet odkazov pre jednotlive stranky
$pageLink = 1;
$photosCount = count($pictures);

echo '<ul class="pagination">';
while($photosCount > 0){
    echo '<li><a href="fotogaleria.php?page='.$pageLink.'">'.$pageLink.'</a></li>';
    $photosCount = $photosCount - $countPerPage;
    $pageLink++;
}
echo '</ul>';

?>

 

Poďme si naše riešenie rozobrať. Na začiatku napĺňame tak ako predtým simulované pole obrázkov, tentoraz do čísla 30. Potom sme si zadefinovali premennú, ktorá bude určovať maximálny počet na jednej stránke (countPerPage). Následne sme si určili premennú, ktorá predstavuje aktuálne zobrazenú stránku. Všimnite si, že sa pýtame, či nám prišiel parameter. Ak áno (stav, kedy sa kliklo na odkaz so stránkou), vložíme si parameter ako hodnotu tejto premennej, ak nie (načítanie stránky z menu), nastavíme si to na hodnotu 1.

 

Potom nasleduje spomínaný výpočet začiatku a konca cyklu, ktorý nám zobrazujú premenné start a end. Potom nasleduje cyklus pre výpis obrázkov tak ako predtým, len sme začiatok a koniec cyklu aplikovali do jeho definície. Všimnite si, že celý výpis obrázka sme obalili do podmienky if($pictures[$i]). Spravili sme to preto, pretože v prípade tretej stránky ide cyklus od 24 do 36. My však máme obrázkov iba 30, takže by cyklus od 31 do 36 zobrazoval prázdne obrázky, pretože hodnotu prvku v poli neexistuje. Vložením tejto podmienky sa teda vykreslenie obrázka nevykoná a nič prázdne tam nebude.

 

Na konci sme si zadefinovali premennú, ktorá určuje poradové číslo stránky pre lištu stránkovania (odkazy na stránky) a premennú, ktorá nám predstavuje celkový počet obrázkov. Pre výpis stránok sme použili cyklus while (s podmienkou na začiatku), kde sa v podmienke pýtame, či máme je počet obrázkov, ktoré ešte treba vypísať, väčši ako nula. Toto číslo je na začiatku 30, takže prvý krok sa spustí, vypíše sa odkaz s parametrom 1. Celkový počet obrázkov, ktoré ešte treba vypísať sme si zmenšili o 12, takže je 18. Nasleduje druhý krok cyklu, číslo sa zmení na 6 a pribudne druhý odkaz s parametrom 2. V treťom kroku sa vypíše odkaz s parametrom 3 a hodnota premnnej photosCount je -6, takže štvrtý krok cyklu sa nespustí a my máme všetky potrebné odkazy. Ako je vidieť, odkazy sme vypísali do zoznamu.

 

Skúste si klikať na jednotlivé stránky a uvidíte, že to naozaj funguje. Šikovné však? Možno sa vám zdá tento príklad/problém príliš zložitý a poviete si, že no na to by som nikdy neprišiel. Ak je to tak, tak nezúfajte, tento príklad je naozaj asi najťažší zo všetkých, ktoré sme v tomto bakalárskom stupni riešili a vyžaduje si naozaj hlbšie zamyslenie a bádanie po riešení. Ako sme ale dávnejšie povedali, čím viac budeme rozmýšlať a riešiť takéto úlohy, tým sa to viac na nás bude lepiť.

 

Aby to nejako vyzeralo, aplikujme na to ešte nejaký dizajn. Na to si ale potrebujeme prebrať niektoré nové veci z jazyka CSS, takže si to preberieme v novej kapitole.

Máte nejakú otázku alebo Vám niečo nie je jasné? Napíšte nám na info@zacni-programovat.sk a poradíme!

Obsah súborov projektu po tejto prednáške

1 - footer.php

<div class="footer">
</div>

2 - fotogaleria.php

<!DOCTYPE html>

<html lang="sk">
<head>
<title>Vitajte na našej prvej skutočnej webstránke!</title>

<meta charset=“UTF-8“>
<meta name="description" content="Ponúkame vám lekcie jazykov HTML, CSS, PHP a mnoho ďalších užitočných rád pri programovaní">
<meta name="keywords" content="programovanie, html, css, php, webstranka, web, tvorba webu, web developer, ucenie programovania, ako programovat">

<link rel="stylesheet" type="text/css" href="global.css">
</head>

<body>
<?php $actual_page = "fotogaleria";?>
<div class="main">

<?php include "header.php";?>

<div class="content">

<?php include "menu.php";?>

<div class="main-content right">
<h1>Fotogaléria</h1>
<div class="line"></div>

<?php

$pictures = array();

for($i = 0; $i < 30; $i++){
$pictures[] = 'images/placeholder.jpg';
}

//zadefinovanie maximalneho poctu pre jednu stranku a nacitanie parametra (urcenie aktualnej stranky)
$countPerPage = 12;
if($_GET['page']){
$page = $_GET['page'];
}else{
$page = 1;
}

//vypocet od ktorej po ktoru fotku zobrazujeme galeriu
$start = ($page-1)*$countPerPage;
$end = $page*$countPerPage;

echo '<ul id="gallery">';
for($i = $start; $i < $end; $i++){

if($pictures[$i]){
echo '<li>';

echo '<a class="left';
if(($i+1)%3){
echo ' photo-margin';
}
echo '" target="_blank" href="'.$pictures[$i].'">';

echo '<img src="'.$pictures[$i].'">';
echo '</a>';
echo '</li>';
}
}
echo '</ul>';

//cyklus, ktory nam vypise dostatocny pocet odkazov pre jednotlive stranky
$pageLink = 1;
$photosCount = count($pictures);

echo '<ul class="pagination">';
while($photosCount > 0){
echo '<li><a href="fotogaleria.php?page='.$pageLink.'">'.$pageLink.'</a></li>';
$photosCount = $photosCount - $countPerPage;
$pageLink++;
}
echo '</ul>';

?>
</div>

<div class="clear"></div>
</div>

<?php include "footer.php";?>
</div>
</body>
</html>

3 - global.css

BODY{
margin: 0;
background-color: #dee8e7;
font-family: Arial;
}

H1{
color: #5b6b78;
margin-bottom: 10px;
}

.line{
height: 3px;
border-top: 1px dotted #5b6b78;
border-bottom: 1px dotted #5b6b78;
margin-bottom: 25px;
}

.main{
background-color: #f6f7f1;
width: 900px;
margin: auto;
margin-top: 20px;
margin-bottom: 20px;
}

.header{
border-bottom: 1px solid #7d8079;
height: 150px;
}

.header-inner1{
}

.header-inner2{
}

.content{
}

.footer{
border-top: 1px solid #7d8079;
height: 200px;
}

.half-width{
width: 50%;
}

.full-height{
height: 100%;
}

.left{
float: left;
}

.right{
float: right;
}

.clear{
clear: both;
}

/**********MENU***********/
.sidebar{
width: 200px;
height: 400px;
}

.sidebar UL{
list-style-type: none;
padding: 0;
margin: 0;
}

.sidebar UL LI{
}

.sidebar UL LI A{
display: block;
padding: 15px 0px 15px 35px;
border-bottom: 1px solid #7d8079;
color: #7d8079;
font-family: Arial;
text-decoration: none;
text-transform: uppercase;
}

.sidebar UL LI A.active{
color: #f5f7f4;
background-color: #f96b81;
}

.sidebar UL LI:HOVER A{
background-color: #5b6b78;
color: #d6e3e9;
}

.main-content{
width: calc(100% - 241px);
min-height: 700px;
border-left: 1px solid #7d8079;
padding-left: 20px;
padding-right: 20px;
}

/**********GALERIA***********/
#gallery{
list-style-type: none;
margin: 0;
padding: 0;
}

#gallery A{
display: block;
height: 133px;
margin-bottom: 10px;
}

#gallery IMG, #gallery A{
width: 213px;
}

.photo-margin{
margin-right: 10px;
}

/**********PERSONS***********/
.persons{
width: 100%;
table-layout: fixed;
font-family: Arial;
}

.persons, .persons TH, .persons TD{
border: 1px solid #D9E4E6;
}

.persons TH, .persons TD{
padding: 15px;
}

.persons TH{
background-color: #167F92;
color: #FFFFFF;
font-weight: normal;
text-transform: uppercase;
}

.persons TR:nth-child(odd){
background-color: #D9E4E6;
}

.persons TR{
color: #024457;
background-color: #FFFFFF;
}

.persons TD{
font-size: 14px;
}

.persons TR:HOVER{
color: #f5f7f4;
background-color: #f96b81;
cursor: pointer;
}

/**********PERSONS***********/
.contact_form{
padding: 20px;
border: 1px solid #ebebeb;
background-color: white;
font-family: Arial;
font-size: 14px;
color: #455560;
text-transform: uppercase;
text-align: center;
}

.contact_form INPUT, .contact_form TEXTAREA, .contact_form LABEL{
display: block;
width: 100%;
}

.contact_form LABEL{
margin-bottom: 5px;
text-align: left;
}

.contact_form INPUT, .contact_form TEXTAREA{
height: 30px;
border: 1px solid #bababa;
margin-bottom: 30px;
}

.contact_form TEXTAREA{
min-height: 100px;
min-width: 100%;
max-width: 100%;
}

.contact_form INPUT[type="submit"]{
display: inline;
width: 200px;
height: 40px;
background-color: #7bc143;
border: 1px solid #6fae3c;
font-size: 16px;
color: #FFFFFF;
text-transform: uppercase;
}

.contact_form INPUT[type="submit"]:HOVER{
cursor: pointer;
background-color: #42aa44;
}

.success, .error{
border: 1px solid;
margin: 10px 0px;
padding:15px 10px 15px 10px;
}

.success {
color: #4F8A10;
background-color: #DFF2BF;
}

.error {
color: #D8000C;
background-color: #FFBABA;
}

4 - header.php

<div class="header">
<div class="header-inner1 full-height half-width left"></div>
<div class="header-inner2 full-height half-width left"></div>
</div>

5 - index.php

<!DOCTYPE html>

<html lang="sk">
<head>
<title>Vitajte na našej prvej skutočnej webstránke!</title>

<meta charset=“UTF-8“>
<meta name="description" content="Ponúkame vám lekcie jazykov HTML, CSS, PHP a mnoho ďalších užitočných rád pri programovaní">
<meta name="keywords" content="programovanie, html, css, php, webstranka, web, tvorba webu, web developer, ucenie programovania, ako programovat">

<link rel="stylesheet" type="text/css" href="global.css">
</head>

<body>
<?php $actual_page = "index";?>
<div class="main">

<?php include "header.php";?>

<div class="content">

<?php include "menu.php";?>

<div class="main-content right">
<h1>Domov</h1>
<div class="line"></div>
</div>

<div class="clear"></div>
</div>

<?php include "footer.php";?>
</div>
</body>
</html>

6 - kontakt.php

<!DOCTYPE html>

<html lang="sk">
<head>
<title>Vitajte na našej prvej skutočnej webstránke!</title>

<meta charset=“UTF-8“>
<meta name="description" content="Ponúkame vám lekcie jazykov HTML, CSS, PHP a mnoho ďalších užitočných rád pri programovaní">
<meta name="keywords" content="programovanie, html, css, php, webstranka, web, tvorba webu, web developer, ucenie programovania, ako programovat">

<link rel="stylesheet" type="text/css" href="global.css">
</head>

<body>
<?php $actual_page = "kontakt";?>
<div class="main">

<?php include "header.php";?>

<div class="content">

<?php include "menu.php";?>

<div class="main-content right">
<h1>Kontakt</h1>
<div class="line"></div>

<?php
if($_SERVER['REQUEST_METHOD'] == 'POST' && $_POST['contact_form']){
if(!preg_match('#^[a-zA-Z0-9]{5,10}$#', $_POST['name']) || !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){
echo '<p class="error">Zadajte prosim korektne udaje</p>';

//naplnenie formulara
$name = $_POST['name'];
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];
}else{
//odoslanie emailu
echo '<p class="success">Vasa sprava bola uspesne odoslana.</p>';

$name = '';
$email = '';
$subject = '';
$message = '';
}

}

?>

<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post" class="contact_form">
<label for="email">Meno a priezvisko</label>
<input type="text" name="name" id="name" value="<?php echo $name;?>"><br><br>

<label for="email">Email</label>
<input type="text" name="email" id="email" value="<?php echo $email;?>"><br><br>

<label for="subject">Predmet</label>
<input type="text" name="subject" id="subject" value="<?php echo $subject;?>"><br><br>

<label for="message">Správa</label>
<textarea name="message" id="message" placeholder="Zadajte text spravy..."><?php echo $message;?></textarea><br><br>

<input type="submit" name="contact_form" value="Odoslat">
</form>
</div>

<div class="clear"></div>
</div>

<?php include "footer.php";?>
</div>
</body>
</html>

7 - menu.php

<div class="sidebar left">
<ul>
<li><a class="<?php if($actual_page == "index"){echo 'active';}?>" href="index.php">Domov</a></li>
<li><a class="<?php if($actual_page == "o-nas"){echo 'active';}?>" href="o-nas.php">O nás</a></li>
<li><a class="<?php if($actual_page == "fotogaleria"){echo 'active';}?>" href="fotogaleria.php">Fotogaléria</a></li>
<li><a class="<?php if($actual_page == "kontakt"){echo 'active';}?>" href="kontakt.php">Kontakt</a></li>
</ul>
</div>

8 - o-nas.php

<!DOCTYPE html>

<html lang="sk">
<head>
<title>Vitajte na našej prvej skutočnej webstránke!</title>

<meta charset=“UTF-8“>
<meta name="description" content="Ponúkame vám lekcie jazykov HTML, CSS, PHP a mnoho ďalších užitočných rád pri programovaní">
<meta name="keywords" content="programovanie, html, css, php, webstranka, web, tvorba webu, web developer, ucenie programovania, ako programovat">

<link rel="stylesheet" type="text/css" href="global.css">
</head>

<body>
<?php $actual_page = "o-nas";?>
<div class="main">

<?php include "header.php";?>

<div class="content">

<?php include "menu.php";?>

<div class="main-content right">
<h1>O nás</h1>
<div class="line"></div>

<?php
$person_1 = array('Raťafák', 'Plachta', 'plachtos@mail.sk','0903 123 123');
$person_2 = array('Od kuka', 'do kuka', 'kuko@mail.sk','0903 123 123');
$person_3 = array('Joey', 'Tribbiani', 'ako.sa.mas@mail.sk','0903 123 123');
$person_4 = array('Charlie', 'Harper', 'hooker@mail.sk','0903 123 123');
$person_5 = array('Chruno', 'Moysey', 'abstinent@mail.sk','0903 123 123');

$pole = array($person_1, $person_2, $person_3, $person_4, $person_5);

$pole[5] = array('Jardo', 'Jágr', 'legenda@mail.sk','0903 123 123');

echo '<table class="persons">';
echo '<tr>';
echo '<th>Meno</th>';
echo '<th>Priezvisko</th>';
echo '<th>Email</th>';
echo '<th>Telefónne číslo</th>';
echo '</tr>';

for($i=0; $i<count($pole); $i++){
echo '<tr>';

for($j=0; $j<count($pole[$i]); $j++){
echo '<td>'.$pole[$i][$j].'</td>';
}

echo '</tr>';
}

echo '</table>';

?>
</div>

<div class="clear"></div>
</div>

<?php include "footer.php";?>
</div>
</body>
</html>

Ťažko sa vám učí samému?

Máte problémy s niektorými časťami alebo sa neviete učiť sám? Využite našu možnosť individuálnej asistencie:

  • samostatný prístup
  • vysvetlenie nejasností prebraného učiva
  • úlohy a cvičenia navyše
  • všetko z pohodlia domova cez mail a skype

Pre viac info kliknite tu

Kľúčové slová prednášky

: strankovaniestrankypaginationpaginatorstrankovanie fotogaleriestrankovanie clankovclanky strankyfotky stranky

IT ftip

Programátor na vojenskom cvičení. Na ostrých streľbách páli do terča ako divý, ale od terčov hlásia, že ani jeden zásah. Tak programátor strči palec do hlavne, vypáli a rana mu pochopiteľne urve palec. Kričí k cieľom: "Hej, odo mňa to ide dobre, chyba musí byť niekde u vás!"