Friday 9 November 2007

JSON, contenidos dinamicos en tu web

¿Has intentado utilizar AJAX pero te parece muy complicado o tal vez sus librerías las encuentras muy pesadas de cargar? JSON es su hermano pequeño, y aunque es anterior en el tiempo es más que suficiente para la mayoría de aplicaciones web y es mucho más sencillo de utilizar. Veamos un sencillo pero operativo ejemplo a continuación, que tú podrás cambiar a tu medida, y además por lo que he probado funciona perfectamente en IE (Internet Explorer 6) y en FF (FireFox 2).

No ha sido una tarea fácil conseguir que este código funcionara. Me he pasado horas y horas buscando documentación oficial de los objetos utilizados, he consultado en foros, etc... y por fin, después de copiar y pegar de aquí y de allá, parece que el esfuerzo se concretó en algo operativo y multiplataforma ;)

Nuestro ejemplo consta de 4 archivos:

  • index.htm. Es el documento HTML que verá el visitante en el navegador y el que irá haciendo las llamadas al servidor SIN NECESIDAD DE RECARGARSE LA PÁGINA.
  • json_1.php. Es el archivo PHP al que llamará index.htm cuando necesite nuevos datos.
  • funciones.php. Contiene dos funciones en PHP necesarias para preparar los datos que quiera enviar json_1.php a index.htm.
  • smile.gif. Es una imagen que utilizaremos de ejemplo, para comprobar que con JSON podemos trabajar dinámicamente en nuestras aplicaciones web con texto y con imágenes.
Antes de mostraros el código, deciros que como veréis, es muy claro qué debéis adaptar a vuestro caso, y que las posibilidades son ilimitadas utilizando estas pocas funciones. Lo que más problemas me dió fue -como sucede a menudo- que funcionase todo bien en IE y en FF. Cuando me iba en uno no me iba en el otro... en fin... parece que ahora ya sí. Bueno, al menos hasta que alguno de esos dos navegadores vuelva a cambiar ("mutar" ?).

Para hacer funcionar el ejemplo, debéis poner los 4 archivos en una misma carpeta de vuestro servidor y desde un navegador llamar al archivo index.htm. Así de sencillo. Ah, y bueno, para que lo tengáis más fácil, os dejo este enlace para que podáis descargaros un RAR con el ejemplo listo para probar ;)

También podéis ver el ejemplo funcionando. No os podéis quejar :)

index.htm
1  <html>
2  <head>
3       <title>.: JSON - ejemplo sencillo :.</title>
4       <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
5  </head>
6  
7  <body>
8  
9  <a href="javascript:remote_fill('json_1.php?color=rojo');">ROJO</a>
10  <a href="javascript:remote_fill('json_1.php?color=azul');">AZUL</a>
11  <br /><br /><br />
12  <span id='json_grafico'></span>
13  <span id='json_texto'></span>
14  
15  <script>
16  
17  // INTENTAR LA CREACION DE UNA CONEXION DIRECTA CON EL SERVIDOR MEDIANTE XMLHttpRequest
18  
19  function createRequest() {
20       try {
21            request = new XMLHttpRequest();
22       } catch (trymicrosoft) {
23            try {
24                 request = new ActiveXObject('Msxml2.XMLHTTP');
25            } catch (othermicrosoft) {
26                 try {
27                      request = new ActiveXObject('Microsoft.XMLHTTP');
28                 } catch (failed) {
29                      request = false;
30                 }
31            }
32       }
33       if (!request)
34       alert('Su navegador no permite crear uns instancia de XMLHttpRequest, ni de Msxml2.XMLHTTP, ni de Microsoft.XMLHTTP. Esta característica es indispensable para seguir trabajando en esta aplicación web.');
35  }
36  
37  var request = false;
38  createRequest();
39  
40  // FUNCIONES DE TRABAJO CON EL SERVIDOR
41  
42  function remote_fill(url_remote){
43       request = false;
44       createRequest();
45       if (!request){
46            alert('Su navegador no permite crear uns instancia de XMLHttpRequest, ni de Msxml2.XMLHTTP, ni de Microsoft.XMLHTTP. Esta característica es indispensable para seguir trabajando en esta aplicación web.');
47            return false;
48       }
49       request.onreadystatechange = handle_json;
50       request.open('GET', url_remote, true);
51       request.send(null);
52  }
53  
54  function handle_json() {
55       if (request.readyState == 4) {
56            if (request.status == 200) {
57                 var json_data = request.responseText;
58                 var the_object = eval( '(' + json_data + ')' );
59                 document.getElementById('json_grafico').innerHTML= the_object.grafico_pertinente;
60                 document.getElementById('json_texto').innerHTML= the_object.texto_pertinente;
61            } else {
62                 alert('Ha habido un problema con la URL ');
63            }
64       }
65  }
66  
67  remote_fill('json_1.php?color=blanco');
68  
69  </script>
70  
71  </body>
72  </html>


json_1.php
1  <?php
2       
if (!isset($_GET['color'])) return false;
3       include_once(
"funciones.php");
4       
5       
$ret = array();
6       switch (
$_GET['color']){
7            case 
"rojo":
8                 
$ret['grafico_pertinente'] = "<img src='smile.gif' style='border:1px #ff0000 solid' />";
9                 
$ret['texto_pertinente'] = " borde rojo";
10                 break;
11            case 
"azul":
12                 
$ret['grafico_pertinente'] = "<img src='smile.gif' style='border:1px #0000ff solid' />";
13                 
$ret['texto_pertinente'] = " borde azul";
14                 break;
15            default:
16                 
$ret['grafico_pertinente'] = "<img src='smile.gif' style='border:0px #ff0000 solid' />";
17                 
$ret['texto_pertinente'] = " escoge un color para el borde, y el servidor devolverá la respuesta";
18                 break;
19       }
20       
21       echo 
php_json_encode($ret);
22  
23  
?>


funciones.php
1  <?php
2  
3  
// funciones JSON
4  
function json_encode_string($in_str){
5       
//$charset = "UTF-8";
6       
$charset "ISO-8859-1";
7       
mb_internal_encoding($charset);
8       
$convmap = array(0x800xFFFF00xFFFF);
9       
$str "";
10       for(
$i=mb_strlen($in_str)-1$i>=0$i--){
11            
$mb_char mb_substr($in_str$i1);
12            if(
mb_ereg("&#(\\d+);"mb_encode_numericentity($mb_char$convmap$charset), $match))
13                 
$str sprintf("\\u%04x"$match[1]) . $str;
14            else
15                 
$str $mb_char $str;
16       }
17       return 
$str;
18  }
19  
20  function 
php_json_encode($arr){
21       
$json_str "";
22       if(
is_array($arr)){
23            
$pure_array true;
24            
$array_length count($arr);
25            for(
$i=0;$i<$array_length;$i++){
26                 if(! isset(
$arr[$i])){
27                      
$pure_array false;
28                      break;
29                 }
30            }
31            if(
$pure_array){
32                 
$json_str ="[";
33                 
$temp = array();
34                 for(
$i=0;$i<$array_length;$i++)
35                 
$temp[] = sprintf("%s"php_json_encode($arr[$i]));
36                 
$json_str .= implode(",",$temp);
37                 
$json_str .="]";
38            }else{
39                 
$json_str ="{";
40                 
$temp = array();
41                 foreach(
$arr as $key => $value)
42                 
$temp[] = sprintf("\"%s\":%s"$keyphp_json_encode($value));
43                 
$json_str .= implode(",",$temp);
44                 
$json_str .="}";
45            }
46       }else{
47            if(
is_string($arr)){
48                 
$json_str "\""json_encode_string($arr) . "\"";
49            }elseif(
is_numeric($arr)){
50                 
$json_str $arr;
51            }else{
52                 
$json_str "\""json_encode_string($arr) . "\"";
53            }
54       }
55       return 
$json_str;
56  }
57  
58  
?> 

2 comments:

  1. hola, Gracias por este post, estoy intentando implementarlo en mi web y ampliarlo para adaptarlo a mis necesidades, ya que el ajax me resulta complicado, y tan solo necesito hacer alguno envíos al servidor sin esa incomoda recarga (y parpadeo en el IE)

    me da un pequeño problema, me sale un warning del php sobre el include_once

    es necesario el uso del archivo json_1.php ??

    no se puede poner ese mismo código en funciones.php ??

    ReplyDelete
  2. @Héctor: gracias a ti por leer el post y probar el ejemplo... siempre reconforta saber que a alguien le sirvió tu trabajo ;)

    Para ayudarte con tu problema, necesitaría que me pusieras aquí el mensaje de error completo. Copia y pégamelo aquí :))

    En cuanto a tus ultimas preguntas:

    1) el archivo json_1.php es el más necesario, puesto es el que se llama desde el archivo HTML (al menos en el ejemplo)

    2) en todo caso, el archivo funciones.php sí puedes integrarlo en json_1.php copiando sus funciones dentro del mismo (si quieres detrás del "return.."), y así te evitarías el include_once. Pero no le veo mucho la utilidad. En mi caso, por ejemplo, suelo tener varios archivos json_X.php que son llamados para consultas diferentes, y todos llaman siembre al mismo funciones.php ;)

    3) Pero claro, "cada maestrillo tiene su librillo", jejeje... así que el asunto se puede organizar de muchas maneras diferentes a conveniencia de cada caso.

    Espero tu mensaje de error... a ver si puedo ayudarte.
    SERGI

    ReplyDelete