[Alku]
Testaa CSS-oppaan navigoinnin toimivuutta!
   
 
Hae sivuiltani:
[Apua]

Dynaamiset valikot

Olen tehnyt dynaamisia valikoita staattisesti. Niitä voidaan tuottaa myös PHP:n dynaamisesti. Verrattuna JavaScript-koodauksella tuotettuihin valikoihin etuna on se, että valikot ovat olemassa, vaikka JavaScript-tuki oli pois päältä.

Dynaamisten valikoiden alku ja loppu kannattaa joko laittaa tavanomaisena HTML-koodina haettavaan tiedostoon tai kirjoituttaa koodia funktioiden avulla. Funktiot eivät ole tässä kohdassa tarpeellisia.

Valikkokohdat

Funktiota tarvitaan aina itse valikkokohtien kirjoittamiseen, jolloin valikkokohtien rakennetta voidaan myöhemmin muunnella. Valikkokohtien asiatieto tulee jakaa selkeästi määriteltäviin muuttujiin, esim. alla alivalikkokohdan tuottava funktio mItem():

function mItem(){

global $classD,$idD,$classD2,$classA,$idA,$title,$href,$mOver,$name;

print "<div class=\"".$classD."\" ".$idD." onmouseover=\"".$mOver."\"><div class=\"".$classD2."\"><a class=\"".$classA."\" id=\"".$idA."\" title=\"".$title."\" href=\"".$href."\">".$name."</a></div></div>";
}
Yksittäisten yleismuuttujien käyttäminen

Tässä koodissa on käytetty yksittäisiä yleismuuttujia. Muuttujia ei tarvitse laittaa argumenttilistaan sen paremmin funktiota määriteltäessä tai sitä kutsuttaessa. Kaikkia muuttujia ei tarvitse määritellä, mutta jos jonkin kohdan määrittelee, se koskee automaattisesti kaikkia jäljessä tulevia valikkokohtia mikäli samaa muuttujaa ei määritellä uudelleen. Funktiotiedoston loppuun voi laittaa joidenkin muuttujien oletusarvot ja funktio, jolla voi palauttaa oletusarvot, esim.:

$classD="noArrow";
$classD2="itemD";
$idD=""; /* Muuttujan arvo täytyy kirjoittaa muodossa $idD="id=\"idArvo"\";, sillä arvon tulee olla uniikki eikä tyhjä arvo kelpaa. Oletusarvoksi ei siten voi luoda tyhjää attribuuttia vaan oletusarvona on, että attribuuttia ei ole lainkaan. Muilla muuttujilla tuotetut id-attribuutit ovat sellaisia, että ne tuotetaan kaikille elementeille ja jokaisessa kohteessa täytyy antaa uniikki arvo. Tämä ongelma olisi vältettävissä käyttämällä lisäfunktiota (annan edempänä mallin sen toteuttamiseksi).*/
$classA="itemA";
$mOver="";

function setDefaults(){

global $classD,$idD,$classD2,$classA,$mOver;

$classD="noArrow";
$idD="";
$classD2="itemD";
$classA="itemA";
$mOver="";
}

Alla on esimerkki, jossa määritellään yksi alivalikkokohta. Koska esimerkissä on tavallisuudesta poikkeava luokkamääritys lopussa on oletusasetusten palautusfunktio:

$idA="uniikkiId";
$title="Jokin linkki";
$href="link1.php";
$classD2="jokinLuokka";
$name="Linkki 1";

smItem();setDefaults();

Tavallisesti määrittelen yhdeksästä muuttujien määrittelemistä arvosta neljä. Esimerkiksi

$idA="CSSCover";
$title="CSS-oppaan etusivu";
$href="
index1.php3";
$name="Aloitussivu";

mItem();
tuottaa funktion mItem() kanssa seuraavan lopullisen lähdekoodin:
<div class="noArrow" ><div class="itemD"><a class="itemA" id="CSSCover" title="CSS-oppaan etusivu" href=" index1.php3" onmouseover="">CSS-oppaan etusivu</a></div></div>

Sen asemasta että muuttuja listataan ennen funktiokutsua, muuttujat voitaisiin määritellä myös funktiokutsun sisään pilkuilla toisistaan erotettuna (mItem($idA="CSSCover",...)).

Edellä olleen koodin ongelmana on se, että se luo paljon tyhjiä onmouseover attribuutteja. Ne saa pois monimutkaisemmalla koodauksella, mikä ei kuitenkaan ole mitenkään välttämätöntä. Em. attribuuttien ja joidenkin id attribuuttien suhteen voisi tarkistaa, ovatko muuttujat tyhjiä. Jos ne olisivat tyhjiä ei luotaisi attribuutteja lainkaan. Muussa tapauksessa tuotettaisiin attribuutti ja sen arvo. Alla koodi tämän toteuttamiseksi:

checkIfEmpty(){
global $mOver,$idD;
    
    if (empty($idD)){ } /* Funktion määrittely voi olla tyhjä. */
    
    else {
        print " id=\"".$idD."\"";
    }
    
    if (empty($mOver)){ }
    
    else {
        print " onmouseover=\"".$mOver."\"";
    }   
}

function mItem(){
...
    print "<div class=\"".$classD."\"";
    checkIfEmpty();
    print "> class=\"".$classD2."...";

Taulukkomuuttujien käyttäminen

Yksittäisten muuttujien käyttäminen ei yhdessä suhteessa edusta yleisesti suositeltavaa ohjelmointitapaa. Muuttujien tiedot "vuotavat" yhdestä kohteesta seuraaviin kohteisiin. Yksittäisten muuttujien sijaan voitaisiin luoda yksi taulukkomuuttuja (esim. esim. $aItem) ja sille yksittäisiä tavanomaisia muuttujia vastaavat alimuuttujat seuraavaan tapaan:

function mItem(){

global $aItem;

... ".$aItem["classD"]." ... ".$aItem["href"]." ... ".$aItem["name"]"...

Alimuuttujien arvot voitaisiin määrittää seuraavalla tavalla => operaattoria käyttäen:

mItem($aItem = array("classD" => "noArrow", ..., "href" => " index1.php3", "name" => "Aloitussivu", ... ));

Nyt yksittäisten muuttujien arvot eivät vuoda, mutta ne täytyy aina määritellä taulukkomuuttujan sisällä uusiksi. On toki mahdollista, että tarkistetaan onko attribuutin arvo tyhjä (se on tyhjä, jos muuttujaa ei ole määritelty). Jos arvo havaitaan tyhjäksi, annetaan esimääritelty oletusarvo. Mielestäni järkevämpää on ei-tyhjille oletusarvoille oma taulukkomuuttuja, esim.:

$aItemDefaults = array("classD" => "noArrow", "classD2" => "itemD", "classA" => "itemA", "href" => "#");

Nämä oletusarvot voidaan yhdistetään funktion array_merge() avulla taulukkomuuttujan $aItem kanssa. Alla esimerkkitoteutus:

mItem(array_merge($aItemDefaults,$aItem = array(
"idD" => "GenericItem",
"idA" => "GenericA",
"classD" => $arrow,
"title" => "Yleistä",
"mOver" => "hideThlMenus(); MM_showHideLayers('indexPages','','hide','allSites','','hide','Generic','','show'...);"
)));

Jos arvot ovat erilaisia, jälkimmäisen yhdistetyn taulukkomuuttujat voittavat. Yllä olleessa tapauksessa "classD" => $arrow voittaa oletusasetuksen "classD" => "noArrow".

Koodia tarvitaan kaikissa edellä esittämissäni taulukkomuuttujien käyttötavoissa hieman enemmän kuin yksittäisiä muuttujia käytettäessä. Olen tosin nähnyt tiivistettyjä JavaScript taulukkomuuttujia, joissa yksittäiset arvot laitetaan pilkkujen väliin (esim. ,,,,noArrow,,,). Uskoisin, että myös PHP:n kanssa päästäisiin samankaltaiseen ratkaisuun. Ongelma on siinä, että on vaikea muista mikä arvo tulee kunkin pilkun väliin. Siksi en suosittelen niin tiiviin koodin käyttämistä. Mielestäni kaikista helpoin tapa ei-ammattilaisille on yksittäisten muuttujien käyttäminen. Monimutkaisten taulukkomuuttujien käyttö on ammattilaisia varten.

Säilytinlohkot

Alivalikoiden säilytinelementille kannattaa ainakin laittaa muuttuja, joka nimeää sen yksilöllisesti id-attribuutin avulla. Alla olevassa esimerkkitapauksessa olen käyttänyt yksittäisiä muuttujia (myös taulukkomuuttujia voitaisiin käyttää):

function smTop(){

global $id,...;

print "<div id=\"".$id."\" class=\"pageGroup\"...
}

Siihen liittyvä funktiokutsu on esim.:

...
$id = "MainPages";

...

smTop();

Näillä ratkaisuilla saadaan automaattisesti luotuja valikkokohtia, mutta valikkolohkon ja koko valikon luomisen suhteen automatisointi on vain osittaista.

Esitysasut

Itselläni lähes kaikki ulkoasuun liittyvät seikat määritellään ulkopuolisista CSS-tiedostoista käsin. Merkittävin poikkeus on se, että olen määritellyt joidenkin elementtien korkeus määritellään PHP:n ja style attribuuttien avulla. Valikon laatija määrittelee alivalikon sisällön korkeuden muuttujan $iHeightMI (nimi tulee sanoista integer Height Menu Items = kokonaisluku Korkeus Valikko Kohtien). Tämä sisältökorkeus määrittää varjojen korkeuden (korkeusarvot saattavat olla itselläni hieman erilaisia):

function smTop(){

global ...,$iHeightMI;

print "<div id=\"".$id."\" class=\"pageGroup\" style=\"height:".($iHeightMI+10)."px;\">
...
}

function smBottom(){

global $iHeightMI;

print "</div><div class=\"shadowBase\" style=\"height:".($iHeightMI+122)."px;\"><div class=\"shadow\" style=\"height:".($iHeightMI+18)."px;\"> </div></div></div>";
}

Ratkaisuni heikkous on edelleen siinä, että sivujen laatijan täytyy käsin määritell muuttujan $iHeightMI. Mikäli kukin alivalikko olisi yksi taulukkomuuttuja, arvon voisi saada laskemalla kuinka monta valikkokohtaan kuuluu alivalikkoon ja kertomalla tuo luku valikkokohdan korkeudella (joka itselläni on 15px). Ratkaisussani on monia muitakin esitysasullisia piirteitä, jotka voisi automatisoida.

Kaikkien valikoiden asemoinnit määritellään tiedoston ../Css/dynamicMenus.css[S] alussa. Siinä määritellään myös yleiset esitysasulliset piirteet. CSS:ää on helppo editoida siten, että saa joko pysty- tai vaakatasoisen päävalikon.

Koska itselläni dynaamiset valikot toimivat myös staattisina linkkitaulukkoina, valikoiden sijoittuminen taulukkosoluihin ja taulukkoriveille täytyy määritellä ei-automaattisesti. Mikäli valikoita ei tarvita staattisina linkkitaulukkoina, kaikki valikkolohkoihin liittyvät rakenteet voidaan tuottaa PHP-funktioiden avulla.

Tein yhden valikon pohjatiedoston[S], johon haetaan funktioiden määrittelytiedosto tekstitiedostona[S]. Jos et tarvitse valikoiden ympärillä taulukkosoluja poista kaikki taulukkoelementteihin (TABLE, TR ja TD) liittyvä lähdekoodi.

Käyttämällä CSS:ää ja PHP:tä valikoiden perusrakenne, ulkoasumäärittelyt, JavaScript-koodaus ja valikoiden sisältö voidaan lähes kokonaan erottaa toisistaan.

Jos ratkaisuani kehitettäisiin edelleen, se voitaisiin muuntaa tietokantapohjaiseksi, jolloin tuotettujen valikkokohtien attribuuttien arvot haetaan tiekannoista *.inc tiedostojen sijasta. Jos jokainen valikko on oma taulu, voidaan hakea koko taulun sisältö esim. while-silmukan ja list() avulla seuraavaan tapaan:

<?php
result = mysql($conn, "SELECT classD, idD, mOver,... FROM menutableMain");

while (list($idA, $name,...) = mysql_fetch_row($result)) {

print ...
}
?>

Erityiset väliotsikot ja tyhjät valikkokohdat on kuitenkin syytä unohtaa sillä ne keskeyttäisivät silmukat. tai ne tulisi rakentaa samalla kaavalla kuin linkilliset valikkokohdat.

On myös mahdollista luoda lomake, jonka avulla päivitys voi toteutua minkä tahansa Web-selaimen avulla. Lomakkeen jotkut kentät tulisi määritellä pakollisiksi ja jotkut valinnaisiksi. Näihin ortoni - ainakaan toistaiseksi - ei riitä. Ja vaikka minulla olisikin riittävät ordot, en kertoisi näillä sivuilla tietokantojen käyttöä.

Jos dynaamiset valikot tuntuvat latautuvan verkossa liian hitaasti, valikon voi koota valmiiksi kun tekee jonkin *.php -tiedoston, johon hakee valikon tarvitsemat osat. Kasattu valikkotiedosto tulee tallentaa alkuperäisellä nimellä johonkin toiseen hakemistoon, josta sen voi lähettää verkkoon.

[Alku]