Turinys

"Protingas" sąrašas

Problema

Kuriame HTML formą. Reikia gauti keletą pavadinimas+reikšmė įrašų. Jų skaičius nežinomas - gali būti 1000, gali nebūti išvis. Nesinori copy-paste'inti tūkstantį įrašo laukelių ir nenaudojamais elementais užkišti visą ekraną.

Kaip?

JavaScript + DOM + XML, juk XXI amžius! Sukursime simbolinį laukelių skaičių ir įdėsime mygtukus (nuorodas) laukeliui pridėti, ištrinti ir atstatyti į pradinę padėtį, a la Undo.

URL su pavyzdžiu ieškoti apačioje.

Sprendimas

Reikės trijų bylų:

Užsikrovus puslapiui (sarashas.php) JavaScript'as atidaro sarashas.xml ir iš tos bylos sukuria reikiamą skaičių sąrašo elementų su jų reikšmėmis (atstatyti_sarasha ()). Elementus galima pridėti (prideti_elementa ()) arba ištrinti (trinti_elementa ()). Submit'inant formą kviečiama funkcija siusti_sarasha (), kuri iš esamo sąrašo pagamina XML. Pastarasis dedamas į paslėpto formos elemento sarasho_containeris reikšmę ir forma išsiunčiama. Vėliau su ja tvarkosi PHP skriptas :-)

sarashas.php

Pradėkim nuo markup'o - sarashas.php:

<?
 
// Išsaugome sąrašo XML (jeigu gavome)
if ($_REQUEST['sarasho_containeris']) {
	$sarashas = $_REQUEST['sarasho_containeris'];
 
	$f = fopen ('sarashas.xml', 'w');
	fputs ($f, $sarashas);
	fclose ($f);
 
}
 
?>
<!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" lang="lt" xml:lang="lt">
 
<head>
	<title>"Protingo" sąrašo pavyzdys</title>
	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
 
	<meta http-equiv="cache-control" content="no-cache" />
	<meta http-equiv="pragma" content="no-cache" />
 
	<style type="text/css" media="all"><!--/*--><![CDATA[/*><!--*/
 
	body {
		font-family: Verdana, sans-serif;
		font-size: small;
	}
 
	a {
		text-decoration: none;
	}
 
	pre {
		background-color: #eeeeee;
		border: 1px solid;
	}
 
	/*]]>*/--></style>
 
	<script type="text/javascript" src="sarashas.js"></script>
</head>
 
<body onload="atstatyti_sarasha ()">
 
<h1>"Protingo" sąrašo pavyzdys</h1>
 
	<h2>Sąrašas</h2>
 
	<div id="container">
 
		<!-- Nuoroda, pridedanti sąrašo elementą -->
		<a href="javascript:prideti_elementa ()" title="Pridėti elementą">[+]</a>
		<a href="javascript:atstatyti_sarasha ()" title="Atstatyti sąrašą">[*]</a>
 
		<!-- Forma, vedanti čia pat -->
		<form action="<?=$_SERVER['PHP_SELF']?>" method="post" onsubmit="return siusti_sarasha ()">
 
			<!-- Čia bus pats sąrašas - sukurtas su DOM ir JavaScript -->
			<div id="sarashas">Sąrašas tuščias.</div>
 
			<!-- Sąrašą reikės kaip nors perduoti, įdėsime čia -->
			<input type="hidden" id="sarasho_containeris" name="sarasho_containeris" value="" />
 
			<!-- Mygtukas sąrašo išsiuntimui -->
			<input type="submit" value="[išsiųsti]" />
 
		</form>
 
	</div>
 
	<hr />
 
	<h2>$_REQUEST['sarasho_containeris']</h2>
 
	<pre>
 
<?
 
// Truputį pakeičiame XML'ą, kad vaizdžiau atrodytų :-)
$sarashas = str_replace ("<elementai>", "<elementai>\n", $sarashas);
$sarashas = str_replace ("<elementas>", "\t<elementas>\n", $sarashas);
$sarashas = str_replace ("<pavadinimas>", "\t\t<pavadinimas>", $sarashas);
$sarashas = str_replace ("</pavadinimas>", "</pavadinimas>\n", $sarashas);
$sarashas = str_replace ("<reikshme>", "\t\t<reikshme>", $sarashas);
$sarashas = str_replace ("</reikshme>", "</reikshme>\n", $sarashas);
$sarashas = str_replace ("</elementas>", "\t</elementas>\n", $sarashas);
 
// Spausdiname
$sarashas = htmlentities ($sarashas, ENT_QUOTES, 'UTF-8');
print $sarashas;
 
?></pre>
 
	<hr />
 
	<h2>sarashas.xml</h2>
 
	<pre>
 
<?
 
// Atidarome XML bylą, skaitome
$f = fopen ('sarashas.xml', 'r');
$sarashas = fgets ($f, 65535);
fclose ($f);
 
// Vėl pakeičiame XML'ą
$sarashas = str_replace ("<elementai>", "<elementai>\n", $sarashas);
$sarashas = str_replace ("<elementas>", "\t<elementas>\n", $sarashas);
$sarashas = str_replace ("<pavadinimas>", "\t\t<pavadinimas>", $sarashas);
$sarashas = str_replace ("</pavadinimas>", "</pavadinimas>\n", $sarashas);
$sarashas = str_replace ("<reikshme>", "\t\t<reikshme>", $sarashas);
$sarashas = str_replace ("</reikshme>", "</reikshme>\n", $sarashas);
$sarashas = str_replace ("</elementas>", "\t</elementas>\n", $sarashas);
 
// Spausdiname
$sarashas = htmlentities ($sarashas, ENT_QUOTES, 'UTF-8');
print $sarashas;
 
?></pre>
 
</body>
 
</html>

sarashas.js

sarashas.js - JavaScript funkcijos, kviečiamos iš (X)HTML markup'o:

// KONFIGŪRACIJA
 
// Objekto ID, kuriame bus laikomi elementai a.k.a sąrašo container'is
var elementu_sarashas = "sarashas";
// Įprasta ("default") pavadinimo laukelio reikšmė
var def_pavadinimas = "";
// Įprasta ("default") reikšmės laukelio reikšmė
var def_reikshme = "";
 
// KONFIGŪRACIJA
 
 
/*
Funkcija sąrašo atstatymui iš pradinio perduoto XML
Gauna: void
Gražina: void
*/
function atstatyti_sarasha ()
{
	// Triname esamas reikšmes
	el (elementu_sarashas).innerHTML = "";
 
	// Siųsime XML
	if (window.XMLHttpRequest) { // Mozilla, Safari, ...
		http_request = new XMLHttpRequest ();
	} else if (window.ActiveXObject) { // IE
		http_request = new ActiveXObject ("Microsoft.XMLHTTP");
	}
 
	http_request.open ("GET", "sarashas.xml", false);
	http_request.send (null);
 
	xml = http_request.responseXML;
 
	// Einame per elementus
	for (x = 0; x < xml.getElementsByTagName ("elementas").length; ++x) {
 
		// Gauname elemento objektą
		elementas = xml.getElementsByTagName ("elementas").item (x);
 
		// Gauname pavadinimą ir reikšmę
		if (elementas.getElementsByTagName ("pavadinimas").item (0).firstChild) {
			el_pavadinimas = elementas.getElementsByTagName ("pavadinimas").item (0).firstChild.nodeValue;
		} else {
			el_pavadinimas = "";
		}
		if (elementas.getElementsByTagName ("reikshme").item (0).firstChild) {
			el_reikshme = elementas.getElementsByTagName ("reikshme").item (0).firstChild.nodeValue;
		} else {
			el_reikshme = "";
		}
 
		// Pridedame elementą
		prideti_elementa (el_pavadinimas, el_reikshme);
	}
}
 
 
/*
Funkcija elemento pridėjimui
Gauna: elemento pavadinimą arba 0, elemento reikšmę arba 0
Grąžina: void
*/
function prideti_elementa (elemento_pavadinimas, elemento_reikshme)
{
	// Jeigu sąrašas tuščias, reikėtų ištrinti tekstą
	if (el (elementu_sarashas).innerHTML == "Sąrašas tuščias.") {
		el (elementu_sarashas).innerHTML = "";
	}
 
	// Sukuriame elemento ID
	elemento_id = "elementas_" + (el (elementu_sarashas).childNodes.length+1);
 
	// Kuriame pavadinimo laukelį
	var el_pavadinimas = document.createElement ("input");
	el_pavadinimas.type = "text";
	if (elemento_pavadinimas) {
		el_pavadinimas.value = elemento_pavadinimas;
	} else {
		el_pavadinimas.value = def_pavadinimas;
	}
	el_pavadinimas.size = 30;
 
	// Kuriame reikšmės laukelį
	var el_reikshme = document.createElement ("input");
	el_reikshme.type = "text";
	if (elemento_reikshme) {
		el_reikshme.value = elemento_reikshme;
	} else {
		el_reikshme.value = def_reikshme;
	}
	el_reikshme.size = 30;
 
	// Kuriame trynimo nuorodą
	var el_trynimo_nuoroda = document.createElement ("a");
	el_trynimo_nuoroda.href = "javascript:trinti_elementa ('"+elemento_id+"')";
	el_trynimo_nuoroda.id = elemento_id;
	el_trynimo_nuoroda.title = "Trinti elementą";
	el_trynimo_nuoroda.innerHTML = "[x]";
 
	// Kuriame div'ą, į kurį talpinsime prieš tai sukurtus elementus
	var el_elementas = document.createElement ("div");
	el_elementas.appendChild (el_pavadinimas);
	el_elementas.appendChild (el_reikshme);
	el_elementas.appendChild (el_trynimo_nuoroda);
 
	// Pridedame div'ą prie viso sąrašo
	el (elementu_sarashas).appendChild (el_elementas);
}
 
 
/*
Funkcija elemento trynimui
Gauna: elemento objektą (this)
Grąžina: void
*/
function trinti_elementa (trinamas_elementas)
{
	// Triname "parent" div'ą
	el (elementu_sarashas).removeChild (el (trinamas_elementas).parentNode);
 
	// Jeigu sąrašas tuščias, reikėtų pridėti tekstą
	if (el (elementu_sarashas).innerHTML == "") {
		el (elementu_sarashas).innerHTML = "Sąrašas tuščias.";
	}
}
 
 
/*
Funkcija sąrašo siuntimui
Gauna: void
Grąžina: void
*/
function siusti_sarasha ()
{
	var el_pavadinimas;
	var el_reikshme;
	var xml;
 
	// Galima tiesiog kur nors perduoti el (elementu_sarashas).innerHTML
	// Alia XML yra įdomiau! ;-)
 
	// Kuriame naują XML dokumentą
	if (document.implementation && document.implementation.createDocument) { // Mozilla, Firefox...
		xml = document.implementation.createDocument ("", "", null);
	} else if (window.ActiveXObject) { // MSIE...
		xml = new ActiveXObject ("MSXML2.DOMDocument");
	}
 
	// Sukuriame "<elementai>"
	el_elementai = xml.createElement ("elementai");
 
	// Einame per visus vardas:reikšmė div'us
	for (x = 0; x < el (elementu_sarashas).childNodes.length; ++x) {
 
		// Pirmas "input" - pavadinimas, antras "input" - reikšmė
		pavadinimas = el (elementu_sarashas).childNodes.item (x).childNodes.item (0).value;
		reikshme = el (elementu_sarashas).childNodes.item (x).childNodes.item (1).value;
 
		// Sukuriame "elementas"
		el_elementas = xml.createElement ("elementas");
 
		// Sukuriame "pavadinimas" ir "reikshme"
		el_pavadinimas = xml.createElement ("pavadinimas");
		el_pavadinimas.appendChild (xml.createTextNode (pavadinimas));
		el_reikshme = xml.createElement ("reikshme");
		el_reikshme.appendChild (xml.createTextNode (reikshme));
 
		// Pridedame prie "elementas"
		el_elementas.appendChild (el_pavadinimas);
		el_elementas.appendChild (el_reikshme);
 
		// "elementas" pridedame prie "elementai"
		el_elementai.appendChild (el_elementas);
	}
 
	// Pridedame elementų sąrašą prie XML
	xml.appendChild (el_elementai);
 
	// Pasidarome string'ą
	if (xml.xml) { // MSIE...
		xml_string = xml.xml;
	} else { // Firefox, Mozilla...
		xml_string = new XMLSerializer().serializeToString(xml);
	}
 
	// Įrašome į tą paslėptą field'ą
	el ("sarasho_containeris").value = xml_string;
}
 
 
/*
document.getElementByID analogas
Gauna: objekto ID
Grąžina: objektą
*/
function el (id)
{
	return document.getElementById (id);
}

Kita

Veikiantis pavyzdys - http://stuff.pypt.lt/protingas_sarashas/. Pavyzdyje JavaScript'as parsiunčia ne sarashas.xml, o grazhinti_xml.php tam, kad byla neužsikešuotų.