Posts Tagged ‘jQuery’

innerHTML de un TR es distinto dependiendo de a quien le preguntes

Enero 14th, 2010

Quizas la peor pesadilla de un programador Web es hacer que el Javascript corra exactamente igual en todos los navegadores, eso porque cada navegador tienes su forma particular de interpretar ciertos scripts.

El Caso:¿Cual es el contenido de un TR?

Si tenemos una tabla como esta:

    <table id="DataContainer">
    <tr class="loadVoyageHandler">
    <input id="elid" name="elnombre" type="hidden" value="25" />
        <td>
        CONTENIDO
        </td>
        <td>
        CONTENIDO
        </td>
        <td>
        CONTENIDO
        </td>
    </tr>
</table>

Y con jQuery le preguntamos el contenido de ese TR:

alert($("tr.loadVoyageHandler").html());

La respuesta depende del navegador que utilice el usuario:
IE 8, FF3 y Opera 9 te responden:

     <input id="elid" name="elnombre" type="hidden" value="25" />
        <td>
        CONTENIDO
        </td>
        <td>
        CONTENIDO
        </td>
        <td>
        CONTENIDO
        </td>



Pero si le preguntamos a Chrome o Safari te responden:

<!--AQUI FALTA ALGO??-->
        <td>
        CONTENIDO
        </td>
        <td>
        CONTENIDO
        </td>
        <td>
        CONTENIDO
        </td>

¿Y donde quedo el campo oculto que estaba antes del primer TD?

Aparentemente para Chrome y Safari, nada que no este dentro de un TD es contenido de un TR.

Este es un caso muy especifico de los hiddens inputs. Lo mas probable es que el hidden sea puesto por fuera de la tabla, como sucede con una caja de texto si tratas de colocar dentro de una tabla pero por fuera de cualquier TD

Entradas Relacionadas:

jQuery plugin: Autocomplete con ASP.NET MVC

Octubre 3rd, 2009

Una de las cosas que mas gustan de ASP.NET MVC es la posibilidad de utilizar librerias como jQuery de manera muy facil, vamos a utilizar el plugin Autocomplete para jQuery diponible en http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/.

Antes que nada para poder utilizar el plugin debemos referenciar los archivos correspondientes en nuestro SiteMaster, en la declaración del head de la pagina colocamos:

    <%--jQuery Core --%>
    <script src="../../Scripts/jquery-1.3.2.min.js" type="text/javascript"></script>
    <%--end jQuery Core--%>
    <%--jQuery Autocomplete--%>
    <link href="../../Scripts/jquery.autocomplete.css" rel="stylesheet" type="text/css" />
    <script src="../../Scripts/jquery.autocomplete.js" type="text/javascript"></script>
    <%--end jQuery Autocomplete--%>

Ya que tenemos las referencias, vamos a crear el controlador que nos servirá como proveedor de datos:

public ActionResult Completer(string q)
        {
            if (q != "")
            {
                NWDataContext db = new NWDataContext();
                var suggest = from i in db.Customers
                                  .Where(e => e.ContactName.ToLower().StartsWith(q.ToLower()))
                                   select (i.ContactName + "|" + i.CustomerID);
                return Content(String.Join("\n", suggest.ToArray()));
            }
            return new EmptyResult();
        }

Esta ActionResult recibe como parámetro un string q, que sera enviado por el Autocomplete Plugin al momento que el usuario empiece a llenar el TexBox. Verificamos si la q no esta vacia (”" – solo por si acaso), instan ciamos nuestro proveedor de datos o repositorio, en mi caso es un DataContext de LINQtoSQL, y realizo la busque en la tabla Customers donde el contact name empiece con q.

NOTA: pase todo a Lower para evitarme un posible dolor de cabeza con el case sensitive.

Al final retorno un arreglo con este formato para cada elemento:
Ana Trujillo|ANATR
Antonio Moreno|ANTON
Ann Devon|EASTC
Aria Cruz|FAMIA
André Fonseca|GOURL
Annette Roulet|LAMAI
Alexander Feuer|MORGK
Alejandra Camino|ROMEY
Art Braunschweiger|SPLIR
Anabela Domingues|TRADH

Ustedes no necesariamente deben utilizar este tipo de estructura, también pueden utilizar JSON si lo desean.

Con este método nos basta para realizar muchas cosas, vamos a implementar 5 variantes de este autocomplete:

  • Autocomplete Simple.
  • Autocomplete Multiples Selecciones.
  • Autocomplete Incluyendo el ID del elemento elegido en un campo Oculto.
  • Autocomplete Forzando la seleccion de uno de los sugeridos.
  • Autocomplete Con Imagenes (Fancy).

AutoComplete Simple

AutoComplete Simple - jQuery Plugin

AutoComplete Simple - jQuery Plugin


Lo que corresponde de HTML, generar el texbox con la ayuda de los helpers de MVC.

<span>Autocomplete Simple</span>
    <hr />
    <% =Html.TextBox("Clientes") %>

Y setear el Autocomplete dentro de un SCRIPT TAG.

<script type="text/javascript">
        $(function() {
 
 
            $('#Clientes').autocomplete(' <% =Url.Action("Completer","Home") %>', {
                width: 300,
                formatItem: formatItemNoID,
                formatResult: formatResult
            });
    });
    </script>

$(’#Clientes’).autocomplete setea el comportamiento del input con ID Clientes, para que sea autocompletado.
El primar parametro del autocomplete es la url, que como ven utilice el helper de MVC para que me genere un link hacia el ActionResult “Completer” del Controlador “Home”, la q es adjuntada como queryString al URL que le proporcionen, al final seran links de este tipo:
http://localhost/Home/Completer?q=a&limit=10&timestamp=1254590546937, el limit es la cantidad de resultados que serán sugeridos al usuario por defecto 10 elementos.
El segundo parámetro es una colección de opciones con figurables que trae el plugin, no entrare en detalle ya que todas las opciones son bastante digeribles a la primera, pero si les dejo una url donde pueden ver todas las opciones disponibles: http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions.

Lo que si voy a explicar son las funciones para parsear el resultado del autocomplete:

            function formatItem(row) {
                return row[0] + " (<strong>id: " + row[1] + "</strong>)";
            }
            function formatItemWIMG(row) {
                return "<img src='../../Content/img/es.jpg'/> " + row[0];
            }
            function formatItemNoID(row) {
                return row[0];
            }
            function formatResult(row) {
                return row[0].replace(/(<.+?>)/gi, '');
            }

Lo que realizan estas funciones es dar forma a la lista de sugerencias del autocomplete, ya sea que queremos ver imágenes, formatear el texto, en general la forma en que se ve la lista.

Autocomplete Multiples Selecciones
Acá la diferencia es que se pueden seleccionar mas de un elemento, separados por comas.

Multiples Selecciones - jQuery Plugin

Multiples Selecciones - jQuery Plugin


<span>Autocomplete Multiples Selecciones</span><br />
    <hr />
    <% =Html.TextArea("ClientesMultiples") %>
    <br />
    <br />

$('#ClientesMultiples').autocomplete(' <% =Url.Action("Completer","Home") %>', {
                width: 300,
                multiple: true,
                formatItem: formatItemNoID,
                formatResult: formatResult
            });

La diferencia esta al configurar el autocomplete, ahora la opción multiple es TRUE.

Autocomplete Incluyendo el ID del elemento elegido en un campo Oculto
Algunas veces lo que necesitamos es el ID del cliente, así que ahora cuando configuramos el autocomplete utilizamos el evento .result (se ejecuta cuando el usuario selecciona algún elemento de la lista sugerida).

Autocomplete con ID - jQuery Plugin

Autocomplete con ID - jQuery Plugin

Ahora cuando el usuario selecciona Ana, ademas de completar la palabra en el primer texbox, el ID de Ana sera colocado en la casilla de la derecha.

Setear el ID del elemento selecionado

Setear el ID del elemento selecionado


<span>Incluyendo el ID en un campo Oculto</span>
    <hr />
    <% =Html.TextBox("ClienteName") %> <% =Html.TextBox("hiddenID", null, new { style = "width:50px", disabled = "disabled" })%>
    <br />
    <br />


$('#ClienteName').autocomplete(' <% =Url.Action("Completer","Home") %>', {
                width: 300,
                formatItem: formatItem,
                formatResult: formatResult
            });
            $('#ClienteName').result(function(event, data, formated) {
                $('#hiddenID').val(data[1]);
            });

En esta sección le agregue el evento result, y acá le indico que cuando el usuario seleccione algún elemento, envié el id seleccionado al campo oculto.

Porque data[1]?
data representa el elemento seleccionado, al parsearlo data[0] venrdia siendo el nombre del cliente y data[1] el ID del mismo. Recuerden que en el controlador devuelvo un array de esta forma:
Nombre del Cliente | ID
Que en este contexto es:
Data [0] | Data[1]

Autocomplete Forzando la seleccion de uno de los sugeridos
SI lo que queremos es que el usuario no nos este inventando nombres de clientes, podemos setear el autocomplete para que solo acepte elementos existentes dentro de los sugeridos, si el usuario escribe cualquier otra cosa que no hace match con algún nombre de cliente existente, se resetea el texbox.
En lo personal no me agreda mucho esta opcion, me parece algo agresivo con el usuario limpiar todo lo que ha escrito sin enviarle algún mensaje de lo que esta pasando.

Para lograr este efecto simplemente colocamos la opcion mustMatch: true.

$('#ClientesForced').autocomplete(' <% =Url.Action("Completer","Home") %>', {
                width: 300,
                mustMatch: true,
                formatItem: formatItem,
                formatResult: formatResult
            });

Autocomplete Con Imagenes (Fancy)
Ya como últimos punto, si queremos lograr algo mas llamativo imaginen que tuviésemos a disposición una imagen del rostro de los clientes, entonces podemos desplegar en las sugerencias junto con el nombre una imagen del cliente.

AutoComplete con imgs - jQuery Plugin

AutoComplete con imgs - jQuery Plugin


<span>Autocomplete Con Imagenes</span><br />
    <hr />
    <% =Html.TextBox("ClienteFace") %>


$('#ClienteFace').autocomplete(' <% =Url.Action("Completer","Home") %>', {
                width: 300,
                formatItem: formatItemWIMG,
                formatResult: formatResult
            });


Acá lo único distinto es la función que utilizamos para darle formato a los elementos formatItemWIMG.

Pueden descargar el proyecto de ejemplo aqui

Entradas Relacionadas:

Como realzar llamadas asincronas (AJAX) con jQuery

Agosto 20th, 2009

Una de las cosas que jQuery hace ver muy fácil, es el realizar llamadas asíncronas (en otras palabras AJAX), veamos un ejemplo basico de como hacerlo, hay varios metodos (.get, .getJSON .ajax, …), para este ejemplo utilizare $.ajax().

 
$.ajax({
          type: "GET",  //HTTP GET
          url: "/Mov/Check",  // URL del recurso que queremos acceder
          data: { input: $("#id").val() }, //valor que le pasamos al URL
          dataType: "json", // tipo de dato que esperamos recibir
          success: function(message) {
          //hacemos algo con el resultado
                        }
                        }
                       );

Bueno con esto ya seteamos un AJAX Call, ahora vamos al detalle:
El metodo .ajax(), acepta varios parámetros, yo solo utilice algunos:

type: "GET", //HTTP GET
Aquí le especificamos que tipo de verbo HTTP queremos aplicarle al request, le decimos que GET, porque solo vamos a consultar datos del server, no vamos a guardar nada, si el caso fuera persistir o guardar algún dato le aplicamos POST.

url: "/Mov/Check", // URL del recurso que queremos acceder
Si vamos a realizar un ajax call, entonces necesitamos especificar el URL del server que vamos a acceder, en este caso /Mo/Check.

data: { input: $("#id").val() }, //valor que le pasamos al URL
Aquí especificamos el parámetro que el controlador esta esperando, este parametro sera incluido en el URL como querystring de la siguiente manera:/Mov/Check?data=value.

dataType: "json", // tipo de dato que esperamos recibir
Establecemos el tipo de datos que estamos esperando nos devuelva el server, en este caso JSON.

success: function(message)
Quizas la mas importante, ya que esto es lo que se ejecuta cuando el servidor nos regrese el resultado, succes (cuando la respuesta regrese satisfactoriamente) hacemos algo con el resultado representado por la variable message.

Y listo, de esta manera se realiza un ajax call en jQuery, a este codigo faltaria encadenarlo con otro evento para que se ejecute por ejemplo en el evento blur de una caja de texto.

Entradas Relacionadas: