Formulari III: createElement i addEventListener

De Wikijoan
Dreceres ràpides: navegació, cerca

Contingut

Introducció

A classe s'ha explicat la unitat didàctica:

i també el següent exemple:

on s'explica el mètode addEventListener per tal d'afegir de forma dinàmica events als elements del DOM. Ara es tracta de fer un formulari senzill per tal de posar en pràctica aquest concepte. A més, també utilitzarem l'event createElement que ens permetrà de forma dinàmica afegir elements al nostre formulari.

Desenvolupament

El model de dades que associa a un contacte un sol telèfon i un sol mail és simple. Quan afegim un contacte al gmail, fixem-nos que podem associar varis telèfons i fins i tot varis mail. El mateix podem dir si som una empresa i estem portant la gestió dels clients amb un CRM (customer relationship management). Volem associar a les empreses diferents persones de contacte, diferents telèfons, diferents mails,... pensar que una empresa té un sol telefon, mail i persona de contacte és una visió molt simplista.

Anem a pensar en un petit formaulari on volem registrar un contacte que pot tenir un o varis mail. Entre contacte i mail s'estableix una relació 1:M en el model de dades (un contacte té varis mails), i això obliga que ha d'haver-hi una taula MAIL diferent de la taula CONTACTE. Per exemple, la base de dades simplificada quedaria:

CONTACTE (id_contacte (PK), nom)
MAIL (id_mail (PK), mail, id_contacte (FK))

Tasques a realitzar

Bàsicament ja se't proporciona un codi que funciona. Crea els arxius en el teu navegador web i comprova el bon funcionament. Els arxius són els següents:

registre1.htm

Validació del mail. L'event està definit en el formulari (onchange)

<!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" xml:lang="es">
<head>
<title>Formulari de contactes (amb varis mails)</title>
<script>
function EsMail(element){
	/*de moment, comprova que hi ha . i @*/
	var bIsValidMail;
	bIsValidMail = element.value.indexOf("@")>-1 && element.value.indexOf(".")>-1;
	if (!bIsValidMail){
		alert("no valid mail"); /*tr*/
		element.value="";
	}
	return bIsValidMail;
}

</script>
</head>
<body>
Validació del mail. L'event està definit en el formulari (onchange)<br />
<form name="frm_registre" action="registre1.htm">
	<fieldset name="fieldset1">
		<div id="nom">
			<label>Nom: </label> <input type="text" name="nom" />
		</div>
		<div id="mail1">
			<label>Mail: </label> <input type="text" name="mail1" onchange="EsMail(this)" />
		</div>
	</fieldset>
	<fieldset name="fieldset2">
		<input type="submit" value="Enviar">
	</fieldset>
</form>

</body>
</html>

registre2.htm

Validació del mail. L'event no està definit en el formulari, sinó que es crea de forma dinàmica utiliitzant el mètode addEventListener.

<!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" xml:lang="es">
<head>
<title>Formulari de contactes (amb varis mails)</title>
<script>
function nou_event1(element, event, funcio, param1) {
	if (element.addEventListener) { /*Mozilla*/
		element.addEventListener(event, function(){funcio(param1)}, false);
	} else { /*IE*/
		element.attachEvent("on"+event, function(){funcio(param1)});
	}
}

function EsMail(element){
	/*de moment, comprova que hi ha . i @*/
	var bIsValidMail;
	bIsValidMail = element.value.indexOf("@")>-1 && element.value.indexOf(".")>-1;
	if (!bIsValidMail){
		alert("no valid mail"); /*tr*/
		element.value="";
	}
	return bIsValidMail;
}

</script>
</head>
<body>
Validació del mail. L'event no està definit en el formulari, sinó que es crea de forma dinàmica utiliitzant el mètode addEventListener.<br />
<form name="frm_registre" action="registre2.htm">
	<fieldset name="fieldset1">
		<div id="nom">
			<label>Nom: </label> <input type="text" name="nom" />
		</div>
		<div id="mail1">
			<label>Mail: </label> <input type="text" name="mail1" />
		</div>
	</fieldset>
	<fieldset name="fieldset2">
		<input type="submit" value="Enviar">
	</fieldset>
</form>

</body>
</html>

<script>
    nou_event1(document.forms[0].mail1, 'change', EsMail, document.forms[0].mail1);
</script>

registre3.htm

Ara creem les diferents capes de mail quan apretem el signe +. Tanmateix, només el primer mail respon a l'event onchange i executa la funcio EsMail.

<!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" xml:lang="es">
<head>
<title>Formulari de contactes (amb varis mails)</title>
<script>
function nou_event1(element, event, funcio, param1) {
	if (element.addEventListener) { /*Mozilla*/
		element.addEventListener(event, function(){funcio(param1)}, false);
	} else { /*IE*/
		element.attachEvent("on"+event, function(){funcio(param1)});
	}
}

function EsMail(element){
	/*de moment, comprova que hi ha . i @*/
	var bIsValidMail;
	bIsValidMail = element.value.indexOf("@")>-1 && element.value.indexOf(".")>-1;
	if (!bIsValidMail){
		alert("no valid mail"); /*tr*/
		element.value="";
	}
	return bIsValidMail;
}

function new_line_mail(num_div){
alert(num_div);
	//he de crear la nova capa de mail, i l'he de ficar en el lloc adequat (el mail2 a sota del mail1, etc)
	oDiv=document.createElement("div");
	oDiv.setAttribute("id","mail" + num_div);
	var oNode=document.getElementById("mail" + parseInt(num_div-1) );
	oDiv.innerHTML = "<label>Mail: </label> <input type='text' name='mail" + num_div + "' /> <a href='#' onclick='new_line_mail(" + parseInt(num_div+1) + ")' style='text-decoration: none;'>+</a>";
	oNode.parentNode.appendChild(oDiv);
}

</script>
</head>
<body>
Ara creem les diferents capes de mail quan apretem el signe +. Tanmateix, només el primer mail respon a l'event onchange i executa la funcio EsMail.
<form name="frm_registre" action="registre3.htm">
	<fieldset name="fieldset1">
		<div id="nom">
			<label>Nom: </label> <input type="text" name="nom" />
		</div>
		<div id="mail1">
			<label>Mail: </label> <input type="text" name="mail1" /> <a href="#" onclick="new_line_mail(2)" style="text-decoration: none;">+</a>
		</div>
	</fieldset>
	<fieldset name="fieldset2">
		<input type="submit" value="Enviar">
	</fieldset>
</form>

</body>
</html>

<script>
    nou_event1(document.forms[0].mail1, 'change', EsMail, document.forms[0].mail1);
</script>

registre4.htm

Ara volem que tots els mails responguin a l'event onchange i executin la funcio EsMail.

<!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" xml:lang="es">
<head>
<title>Formulari de contactes (amb varis mails)</title>
<script>
function nou_event1(element, event, funcio, param1) {
	if (element.addEventListener) { /*Mozilla*/
		element.addEventListener(event, function(){funcio(param1)}, false);
	} else { /*IE*/
		element.attachEvent("on"+event, function(){funcio(param1)});
	}
}

function EsMail(element){
	/*de moment, comprova que hi ha . i @*/
	var bIsValidMail;
	bIsValidMail = element.value.indexOf("@")>-1 && element.value.indexOf(".")>-1;
	if (!bIsValidMail){
		alert("no valid mail"); /*tr*/
		//element.value="";
	}
	return bIsValidMail;
}

function new_line_mail(num_div){
	//he de crear la nova capa de mail, i l'he de ficar en el lloc adequat (el mail2 a sota del mail1, etc)
	oDiv=document.createElement("div");
	oDiv.setAttribute("id","mail" + num_div);
	var oNode=document.getElementById("mail" + parseInt(num_div-1) );
	oDiv.innerHTML = "<label>Mail: </label> <input type='text' name='mail" + num_div + "' /> <a href='#' onclick='new_line_mail(" + parseInt(num_div+1) + ")' style='text-decoration: none;'>+</a>";
	oNode.parentNode.appendChild(oDiv);
	//només cal afegir aquesta línia
	nou_event1(document.forms[0].elements[num_div+1], 'change', EsMail, document.forms[0].elements[num_div+1]);
}

</script>
</head>
<body>
Ara volem que tots els mails responguin a l'event onchange i executin la funcio EsMail.
<form name="frm_registre" action="registre4.htm">
	<fieldset name="fieldset1">
		<div id="nom">
			<label>Nom: </label> <input type="text" name="nom" />
		</div>
		<div id="mail1">
			<label>Mail: </label> <input type="text" name="mail1" /> <a href="#" onclick="new_line_mail(2)" style="text-decoration: none;">+</a>
		</div>
	</fieldset>
	<fieldset name="fieldset2">
		<input type="submit" value="Enviar">
	</fieldset>
</form>

</body>
</html>

<script>
    nou_event1(document.forms[0].mail1, 'change', EsMail, document.forms[0].mail1);
</script>

registre5.php

Ara l'extensió del fitxer és php i s'ha d'executar sobre un servidor web. El script recollirà les variables que envia el formulari, i les haurà d'introduir a la base de dades. El repte és que a priori no sabem quants mails tindrà el formulari, i per tant haurem d'utilitzar arrays.

Primer de tot creem la base de dades que serà el destí del nostre formulari:

SET NAMES 'UTF8';

CREATE DATABASE jbalmes DEFAULT CHARACTER SET utf8;

CREATE USER alumne IDENTIFIED BY 'keiL2lai';
GRANT ALL ON jbalmes.* TO alumne@localhost identified by "keiL2lai";
flush privileges;

USE jbalmes;

DROP TABLE MAIL;
DROP TABLE CONTACTE;

CREATE TABLE CONTACTE(
id_contacte smallint primary key,
nom char(30) not null
);

CREATE TABLE MAIL(
id_mail smallint primary key,
mail char(40) not null,
id_contacte smallint
);

ALTER TABLE MAIL ADD FOREIGN KEY(id_contacte) REFERENCES CONTACTE(id_contacte) ON DELETE CASCADE;

Fitxer registre5.php:

<!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" xml:lang="es">
<head>
<title>Formulari de contactes (amb varis mails)</title>
<script>
function nou_event1(element, event, funcio, param1) {
	if (element.addEventListener) { /*Mozilla*/
		element.addEventListener(event, function(){funcio(param1)}, false);
	} else { /*IE*/
		element.attachEvent("on"+event, function(){funcio(param1)});
	}
}

function EsMail(element){
	/*de moment, comprova que hi ha . i @*/
	var bIsValidMail;
	bIsValidMail = element.value.indexOf("@")>-1 && element.value.indexOf(".")>-1;
	if (!bIsValidMail){
		alert("no valid mail"); /*tr*/
		//element.value="";
	}
	return bIsValidMail;
}

function new_line_mail(num_div){
	//he de crear la nova capa de mail, i l'he de ficar en el lloc adequat (el mail2 a sota del mail1, etc)
	oDiv=document.createElement("div");
	oDiv.setAttribute("id","mail" + num_div);
	var oNode=document.getElementById("mail" + parseInt(num_div-1) );
	oDiv.innerHTML = "<label>Mail: </label> <input type='text' name='mail" + num_div + "' /> <a href='#' onclick='new_line_mail(" + parseInt(num_div+1) + ")' style='text-decoration: none;'>+</a>";
	oNode.parentNode.appendChild(oDiv);
	//només cal afegir aquesta línia
	nou_event1(document.forms[0].elements[num_div+1], 'change', EsMail, document.forms[0].elements[num_div+1]);
}

</script>
</head>
<body>
<?php
$query_string = "";
if ($_POST) {
  $kv = array();
  foreach ($_POST as $key => $value) {
    $kv[] = "$key=$value";
  }
  $query_string = join("&", $kv);
}
echo $query_string;
?>
Ara volem que tots els mails responguin a l'event onchange i executin la funcio EsMail.
<form name="frm_registre" method="post" action="registre5.php">
	<fieldset name="fieldset1">
		<div id="nom">
			<label>Nom: </label> <input type="text" name="nom" />
		</div>
		<div id="mail1">
			<label>Mail: </label> <input type="text" name="mail1" /> <a href="#" onclick="new_line_mail(2)" style="text-decoration: none;">+</a>
		</div>
	</fieldset>
	<fieldset name="fieldset2">
		<input type="submit" value="Enviar">
	</fieldset>
</form>

</body>
</html>

<script>
    nou_event1(document.forms[0].mail1, 'change', EsMail, document.forms[0].mail1);
</script>

registre6.php

<!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" xml:lang="es">
<head>
<title>Formulari de contactes (amb varis mails)</title>
<script>
function nou_event1(element, event, funcio, param1) {
	if (element.addEventListener) { /*Mozilla*/
		element.addEventListener(event, function(){funcio(param1)}, false);
	} else { /*IE*/
		element.attachEvent("on"+event, function(){funcio(param1)});
	}
}

function EsMail(element){
	/*de moment, comprova que hi ha . i @*/
	var bIsValidMail;
	bIsValidMail = element.value.indexOf("@")>-1 && element.value.indexOf(".")>-1;
	if (!bIsValidMail){
		alert("no valid mail"); /*tr*/
		//element.value="";
	}
	return bIsValidMail;
}

function new_line_mail(num_div){
	//he de crear la nova capa de mail, i l'he de ficar en el lloc adequat (el mail2 a sota del mail1, etc)
	oDiv=document.createElement("div");
	oDiv.setAttribute("id","mail" + num_div);
	var oNode=document.getElementById("mail" + parseInt(num_div-1) );
	oDiv.innerHTML = "<label>Mail: </label> <input type='text' name='mail" + num_div + "' /> <a href='#' onclick='new_line_mail(" + parseInt(num_div+1) + ")' style='text-decoration: none;'>+</a>";
	oNode.parentNode.appendChild(oDiv);
	//només cal afegir aquesta línia
	nou_event1(document.forms[0].elements[num_div+1], 'change', EsMail, document.forms[0].elements[num_div+1]);
}

</script>
</head>
<body>
<?php

if ($_POST) {
	$num_elem = 0;
	$mails = array();
	foreach ($_POST as $key => $value) {
		if ($num_elem==0) { //nom
			$nom = $value;
		} else { //mails
			$mails[] = $value;
		}
	$num_elem++;
  }

	//echo $nom;
	//echo $mails[0];
	//echo $num_elem;

	$conn = mysqli_connect("localhost", "alumne", "keiL2lai");
	if (!$conn) {
		$log->error('Could not connect: ' . mysql_error());
		die('Could not connect: ' . mysql_error());
	}

	mysqli_select_db($conn, "jbalmes") or die('Could not select jbalmes database.');
	$sql = "select max(id_contacte) as max_id_contacte from CONTACTE";
	$result = mysqli_query($conn,$sql);
	$row = mysqli_fetch_assoc($result);
	if (!isset($row['max_id_contacte'])){
		$vid_contacte=1;
	} else {
		$vid_contacte=$row['max_id_contacte']+1;
	}


	$sqlstring = "INSERT INTO CONTACTE(id_contacte,nom) VALUES($vid_contacte,'$nom')";
	//echo $sqlstring;

	$result = mysqli_query($conn,$sqlstring);
	if (!$result) {
		 $message  = 'Invalid query: ' . mysql_error() . "\n";
		 die($message);
	}

	//ara inserim els mails
	$sql = "select max(id_mail) as max_id_mail from MAIL";
	$result = mysqli_query($conn,$sql);
	$row = mysqli_fetch_assoc($result);
	if (!isset($row['max_id_mail'])){
		$vid_mail=1;
	} else {
		$vid_mail=$row['max_id_mail']+1;
	}

	foreach ($mails as $value) {
		$sqlstring = "INSERT INTO MAIL(id_mail,mail,id_contacte) VALUES($vid_mail,'$value',$vid_contacte)";
		//echo $sqlstring;
		$result = mysqli_query($conn,$sqlstring);
		if (!$result) {
			 $message  = 'Invalid query: ' . mysql_error() . "\n";
			 die($message);
		}
		$vid_mail++;
	}

	mysqli_close($conn);
}


?>
Ara volem que tots els mails responguin a l'event onchange i executin la funcio EsMail.
<form name="frm_registre" method="post" action="registre6.php">
	<fieldset name="fieldset1">
		<div id="nom">
			<label>Nom: </label> <input type="text" name="nom" />
		</div>
		<div id="mail1">
			<label>Mail: </label> <input type="text" name="mail1" /> <a href="#" onclick="new_line_mail(2)" style="text-decoration: none;">+</a>
		</div>
	</fieldset>
	<fieldset name="fieldset2">
		<input type="submit" value="Enviar">
	</fieldset>
</form>

</body>
</html>

<script>
    nou_event1(document.forms[0].mail1, 'change', EsMail, document.forms[0].mail1);
</script>

SELECT que associa el contacte amb tots els seus mails:

select nom, mail from CONTACTE C, MAIL M where C.id_contacte=M.id_contacte;

Feina per l'alumne

L'alumne ha d'executar i estudiar el codi en el seu ordinador personal. Això implica en el fitxer registre.php tenir creada la base de dades i comprovar que efectivament s'insereixen les dades (afegir el resultat de la select en el fitxer LLEGEIX-ME).

Fés les següents millores:

1) Disseny. Fés un formulari ben dissenyat (CSS, icones adequades, etc)

2) Com s'ha comentat a classe, el signe + només ha d'aparèixer en la última caixa de text.

3) limita el número de mails possibles a 3.

4) De la mateixa manera que un contacte pot tenir varis mails, un contacte també pot tenir varis telèfons. Implementa la mateixa funcionalitat de mail a telefon. (Hauràs de craer una altra taula a la bd). A més, afegeix un nou camp a la taula MAIL i TELEFON per donar informació sobre el mail/telèfon: persona, feina, xarxa_social,...

Entrega

Els alumnes entregaran al Schoology tots els fitxers generats. S'empaquetaran tots aquests fitxers i es pujaran al Schoology dins del termini d'entrega de la pràctica.

Recorda la normativa per entregar les pràctiques al Schoology: ASIX-M10-UF2#Normativa_d.27entrega_de_les_pr.C3.A0ctiques_al_Schoology


creat per Joan Quintana Compte, gener 2019

Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
Institut Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines