jueves, 26 de marzo de 2009

Función recursiva en Javascript.


Hoy he estado en el trabajo rompiéndome los "cascos" haciendo un proceso web que consta de una tabla que muestra unos valores y que en cada una de las filas de la misma tiene un botón para eliminar la fila...
El caso es que por OBLIGACIÓN en el trabajo se usa ASP .NET, y aunque no soy un detractor radical del mismo, he de decir que me gustan más otros lenguajes web como PHP o Rails.
Bien, tengo que decir que soy novato en el mundo del .NET e intenté empezar con Ajax y tuve que instalar unas cosillas y más cosas... (Esto es otra historia).

En fin, que he empezado a introducir en el trabajo Scriptaculous con .NET y es sencillamente ESPECTACULAR! Así que la carencia de librerías Ajax para .NET en mi trabajo lo estoy supliendo con javascript y scriptaculous como os contaré en post posteriores...
Voy al grano, que me enrollo como una persiana, (lo primero es reconocerlo).

Total que después de generar una llamada Ajax para eliminar de la base de datos el valor seleccionado en la tabla y en ese preciso momento llegó mi problema, ¿cómo hago desaparecer la fila que acabo de borrar de la base de datos sin recargar la página?
La primera idea es utilizar el botón que pulso, pero con la llamada Ajax y las sucesivas funciones que utilizo, no podía pasar el valor, o al menos no sé como hacerlo. Aunque lo que si que podía llegarle a la función que borrase la fila es el valor seleccionado. Así pues debería conseguir coger el objeto tabla y recorrerlo hasta encontrar el valor que acabo de borrar y eliminar la línea.

Buscar en vez de crear...

Esto significa que hay que utilizar Document Object Model (DOM) y crear una función recursiva, así que por ahorrar trabajo y tiempo pensé: "Seguro que en internet alguien lo ha hecho con anterioridad".
Le pregunté al señor Google sobre las funciones recursivas y el resultado era siempre la misma función, cosa que confirma una de mis absurdas teorías que dice: "Una persona publica la función original y 200000000 de bloggers la copian". La función COPIADA es la siguiente...



function factorial(numero) {
   if (numero > 0) {
      return numero * (factorial(numero - 1));
   } else {
      return 1;
   }
}


La podemos encontrar en varios idiomas y colores, así que al final me la he tenido que currar y cuando ha funcionado he pensado... dejaré que se la copien 200000000 bloggers y que la usen otros tantos desarrolladores que lo necesiten, si es que alguien llega a leer este post.

Tanto lío para una función tan corta.

Al final la función no es gran cosa pero permite encontrar una fila, pasándole como parámetros el objeto tabla y el texto que debe encontrar.
El funcionamiento de la función es el siguiente, se le pasa la tabla y el texto en la variable orden y se llama recursivamente hasta encontrar el valor que buscamos.



function buscaLinea(tabla,orden){

    //iniciamos el valor que devolveremos a ""
    objeto = "";
    //recorremos los hijos del objeto que se le pasa a la función
    for (var i=0; i< tabla.childNodes.length; i++){

        //llamada recursiva donde pasamos el nodo hijo y el texto.
        var objeto = buscaLinea(tabla.childNodes[i],orden);

        //Comparamos el valor del hijo con el texto
        if (tabla.childNodes[i].nodeValue != orden){
            //No lo hemos encontrado :o(
            //Pero comprobamos que se haya encontrado con anterioridad
            //y si es así devolvemos el objeto encontrado.
            if (objeto!="")
            {
                return objeto;
            }
        }
        else
        {
            //EUREKA! lo hemos encontrado.
            //Ahora objeto valdrá el objeto #text que contiene el texto
            var objeto = tabla.childNodes[i];
            //y devolvemos el nodo <TR> (que es la fila de la tabla)
            return objeto.parentNode.parentNode;
        }
    }
    //Este return se realiza en el caso de que no hayamos encontrado el objeto y tampoco con anterioridad
    return "";
}


Esta función la he probado con Internet Explorer y Firefox y ha funcionado.
Espero que os sirva.