Un dels principals problemes en el disseny amb HTML és l'aïllament de les pàgines, que fa que no puguin passar-se informació. Bé, les pàgines sí que poden enviar dades, però no en poden recollir i processar. Amb JavaScript això té solució.

A la pràctica anterior hem vist com podem guardar dades a les Cookies i recuperar-les després. Aquesta és l'única opció que tenim, en JavaScript, per tenir dades persistents entre sessions. Això no funciona, és clar, si l'usuari ha desactivat les Cookies.

De vegades, però, el que necessitem és enviar unes dades des d'una pàgina i rebre-les a la següent, sense risc. En HTML tenim dos mètodes per enviar dades:

  - POST: s'envien els camps d'un formulari, normalment, per correu electrònic.
  - GET: s'envien les dades enganxades amb l'adreça, en format URL.

Aquest últim és fàcilment manipulable a partir de l'objecte location, que coneixem des de l'inici del curs. Es tractarà, doncs, d'analitzar l'adreça i extreure'n les dades.

Si, fins ara, havíem après com interactuar entre objectes d'una pàgina, entre finestres mares i filles, i entre marcs, amb aquesta pràctica tancarem el cercle: aprendrem a interactuar entre pàgines diferents, que poden estar situades, fins i tot, en servidors diferents.

  Conceptes JavaScript en aquest capítol
Funció escape() : codifica una cadena en format hexadecimal.
Funció unescape() : descodifica una cadena hexadecimal codificada amb escape().
Mètode substring() : retorna una subcadena a partir d'un punt d'inici i una longitud.
Funció isNaN() : avalua una expressió i retorna "cert" si no és un número (is not a number).
Funció parseFloat() : analitza una cadena i, si es pot, retorna un número.
Mètode replace() : aplicat a una cadena, canvia uns caràcters per uns altres.
Expressió Regular : plantilla que s'utilitza per cercar patrons en cadenes.

  1.- Passar un valor
En la declaració d'un formulari, si especifiquem el mètode GET, o no n'especifiquem cap, el botó "submit" passa l'adreça, el signe "?" i els parells "variable=valor". Sovint, però, l'únic que volem passar és un valor, que la pàgina receptora processarà i utilitzarà.

Tot i que podem utilitzar el mètode per defecte, tal com veurem al segon exemple, si les nostres necessitats són mínimes podem escriure un codi més senzill. En tot cas, el valor o els parells formaran part de l'adreça (location) que el navegador envia.

L'objecte location treballa amb URLs. Les adreces tenen aquesta estructura:

  protocol :// host : port / pathname ? search # hash

Cadascuna d'aquestes és una propietat de location. Fixem-nos en search. S'utilitza per passar paràmetres als programes (CGI) o pàgines: asp, php,,, i JavaScript !!! Només cal posar un interrogant (?) a l'adreça. La cadena que segueix és search.

Per tal d'enviar aquesta cadena, el navegador "escapa" els caràcters no ASCII. La funció que els rebrà ho ha de preveure per retornar-los (unescape) al seu format original. També ha de tenir en compte que search comença al "?", i l'haurà de descartar. Per això, utilitzem el mètode substring(), que retorna una subcadena, començant per la posició especificada el primer paràmetre i que té la longitud del segon o, si no l'especifiquem, fins al final.

Necessitem, doncs, fer dues feines: a la pàgina origen, una funció que construeixi la cadena i la posi a la propietat location.href; a la pàgina destí, una línia que llegeixi l'adreça, descodifiqui la zona search i l'assigni a una variable.

Pàgina origen: passar
<script language="javascript">

function passar( url, param ) {
  location.href = url + '?' + escape( param )
}
</script>
</head>
<body>
<form name="form1">
<input type="text" name="txt" value="">
<input type="button" name="enviar" onClick="
passar( 'pag2.htm', form1.txt.value )">
</form>

Pàgina destí (pag2.htm): llegir
<script language="javascript">

var param = unescape( location.search ).substring(1)
</script>
 
2.- Passar variables i els seus valors
A l'exemple anterior hem vist com passar un valor, però, i si el que volem és passar una llista de variables amb els seus valors? Doncs, en principi, la tècnica és la mateixa: enganxar a continuació del "?" i recollir-ho de la propietat location.search. Amb particularitats.

El primer que cal saber és com es codifica una cadena GET amb diversos paràmetres i, si ens hem fixat en les adreces dels cercadors, segur que ja ho sabem:

    (adreça) ? variable1=valor1 & variable2=valor2 & ...
    (Hem posat espais en blanc per llegir-ho millor, però no hi han d'anar).

La funció que crearà l'adreça haurà de recollir - d'un formulari, un vincle o un altre lloc - uns valors per afegir a la cadena. Les variables de cada parell, en canvi, les escriurà com a literals. S'utilitzen com a referència "pactada", que el programa o pàgina receptors utilitzaran.

També hem de tenir en compte que el que passem és una URL. En conseqüència, hi haurà molts caràcters que no podrem utilitzar, com ara espais en blanc o accents. Afortunadament, tenim dues funcions que ho faciliten, escape() i unescape(), que s'encarreguen de codificar i descodificar una cadena a format hexadecimal, compatible amb URL.

El que farem és crear una cadena a partir de l'adreça de la pàgina. Primer li afegim '?'. Després, fem un vector a base de partir la cadena de noms amb el mètode split() i, amb un bucle, afegim a la cadena el nom de cada variable, el seu valor i el signe '&'. Finalment, esborrem l'últim signe de la cadena carreguem la pàgina amb la cadena.

Per tal d'assignar el valor de les variables hem utilitzat la funció eval(), que avalua una expressió, i, per assegurar que no hi ha caràcters estranys, hem passat el resultat per escape(). A partir d'ara, podem utilitzar la funció des de JavaScript o HTML.

Pàgina origen: passar
<script language="javascript">

function pasParams( pag, noms ) {
  pag += '?'
  vect = noms.split( ',' )
  for ( i=0; i<vect.length; i++ ) {
    pag += vect[i] + '=' + escape( eval( vect[i] ) ) + '&'
  }
  pag = pag.substring( 0, pag.length-1 )
  location.href = pag
}
var v1 = "Això és un text"
var v2 = 166.386
</script>
</head>

<body>
<a href="javascript:
pasParams( 'pag2.htm', 'v1, v2' )"><b>Enviar</b></a>
...


A la pàgina destí també hi haurà una mica de codi, que haurem de posar a la capçalera, de manera que puguem processar i utilitzar les dades rebudes des de l'inici.

En primer lloc, eliminem el signe d'interrogació de la cadena search, com a l'exemple anterior. Després, fem un Array a base de partir els paràmetres pel signe '&'. A continuació, fem un bucle sobre aquest Array, partim cada element pel signe '=' i assignem a cada variable el seu valor:

Per tal d'assegurar que cada variable rebrà valors del tipus que espera, hem fet un condicional: si el valor no és numèric - isNaN( parseFloat( aVar[1] ) ) - hem d'afegir-hi cometes, si ho és, no cal. És un sistema arriscat: si volem passar paràmetres literals que contenen números (p.ex. de telèfon o DNI), s'interpretarien com a numèrics. En aquests casos ho hauríem de preveure i escriure les línies de correcció de casos concrets.

Pàgina destí (pag2.htm): llegir
<script language="javascript">

var param = location.search.substring(1)
aParams = param.split( '&' )
for ( i=0; i<aParams.length; i++ ) {
  aVar = aParams[i].split("=")
  if ( isNaN( parseFloat( aVar[1] ) ) ) eval( aVar[0] + '="' + unescape( aVar[1] ) + '";' )
  else eval( aVar[0] + '=' + aVar[1] + ';' )
}
</script>
 
3.- Enviar un formulari a la pròpia pàgina
Es tracta d'una variació de l'exemple anterior. En aquest cas, les pàgines origen i destí són la mateixa. Aquesta és una tècnica utilitzada moltes vegades, i en podem veure un exemple al cercador intern d'aquest curs.

L'únic que ens cal és tenir una mica d'ordre a l'hora de dissenyar els scripts:

1.- Si cal, declarem les variables a l'inici. Depèn de si passem només un valor o parells.
2.- Comprovem si, amb l'adreça, es reben paràmetres. Si és així, els assignem.
3.- Com que sabem quants i quins paràmetres es reben, l'assignació serà més senzilla.

En aquest exemple utilitzem el mètode GET, establim com a acció (action) la pròpia pàgina i posem un botó "submit" que l'envia. Així haurem vist tres models. Val a dir que, tots tres ("button" més funció, vincle més funció i GET) són vàlids, i l'elecció és qüestió de gustos.

L'avantatge d'aquest mètode és, per una banda, que podem usar "submit" en lloc de "button" (no cal definir l'event onClick) i, per l'altra, que ens estalviem una funció.

El mètode GET envia parelles camp=valor. Les variables, doncs, tenen el nom dels camps del formulari. Els valors s'envien en un format diferent: en lloc d'espais s'utilitza el signe '+'. Això va molt bé als CGIs, però, en el nostre cas, és un problema. El solucionem utilitzant el mètode de l'objecte String replace(), que permet canviar uns caràcters per uns altres. El primer paràmetre ha de ser una expressió regular. Què?

Una expressió regular és una mena de plantilla que s'utilitza per cercar patrons en cadenes. Té una zona per definir el patró i una pels modificadors: / patró / modificadors. En el nostre cas volem que es substitueixin tots els signes "+" per espais blancs. el patró serà \+ (usem l'antibarra per indicar que és un caràcter, no un operador) i el modificador, "global":

    / \ + / g   vol dir: el caràcter "+", globalment.

L'altre modificador habitual és /i, que vol dir que s'ignorin majúscules i minúscules. Es poden escriure tots dos junts, /gi. En aquest exemple, però, no cal. Conèixer i aprendre totes les possibilitats de les expressions regulars és una tasca llarga i feixuga i, en tot cas, no forma part dels objectius d'aquest curs.

Finalment, el codi que controla la recepció i assignació de paràmetres es basa en l'exemple anterior, però és més senzill - i menys universal - perquè sabem el què s'espera.

<html>
<head>
<title>Exemple</title>
<script language="javascript">

var txt1 = '', txt2 = ''
var param = location.search.substring(1)
if (param>''){
  aParams = param.split( '&' )
  for ( i=0; i<2; i++ ) {
    aVar = aParams[i].split("=")
    eval( aVar[0] + '="' + unescape( aVar[1].replace( /\+/g, ' ' ) ) + '";' )
  }
}
</script>
</head>

<body bgcolor="#EEEECC">
<h3>Enviar paràmetres a la pròpia pàgina</h3>
<form name="form1" method="GET" action="m8p2_3.htm">
Camp 1: <input type="text" name="txt1" value=""><br>
Camp 2: <input type="text" name="txt2" value=""> &nbsp; &nbsp; &nbsp;
<input type="submit" value="Enviar">
</form><hr>
<h3>Els valors rebuts són:</h3>
<script language="javascript">

document.writeln( 'Camp 1: ' + txt1 + '<br>Camp 2: ' + txt2 )
</script>
</html>