viernes, 29 de abril de 2011

[jQuery] Trabajo con ListBox y Combos

 

Introducción

Este artículo se pretende continuar lo empezado en:

[jQuery] Por donde comenzar

En esta ocasión trataremos un conjunto diferente de controles, estos muy usados en un desarrollo web.

En este caso particular trataremos controles de lista: ListBox y Combos. Notando cuan similares son a la hora de trabajarlos.

Selección de Ítems

En los ejemplos indicados como 1 y 2, se recuperan los ítems marcados por parte del usuario, pudiendo manipularlos y trabajar con la información.

 

        function btnEj1Seleccion_OnClick() {

            var list = new Array();

            $.each($('#Ej1Select :selected'), function() {
               
                var msg = 'texto: {0}, valor: {1} 
'.format($(this).text(), $(this).val());
                list.push(msg);

            });

            $('#Ej1Resultado').html(list.join(''));
            
        }

        function btnEj2Seleccion_OnClick() {
           
            var optionSelected = $('#Ej2Select :selected');

            var msg = 'texto: {0}, valor: {1}'.format(optionSelected.text(), optionSelected.val());

            $('#Ej2Resultado').html(msg);

        }

Los selectores usados en ambos casos son idénticos, solo lo diferencia la selección múltiple que puede brindar un ListBox, es por eso que aplica un loop por cada ítem marcado por el usuario.

En este código hay que marcar algunos puntos de interés:

La función $.each() recorre la selección de una lista de ítems y aplica una función por cada uno de ellos.

En este caso en concreto se recorre cada ítem seleccionado de la lista, o sea se obtiene cada <option> tomando de este el valor y el texto. Es importante notar que esta función tiene acceso a cada ítem por medio del this, pero se trata de un objeto javascript y no jquery, es por eso que se aplica nuevamente un selector $(this), para tener acceso a los métodos que permiten acceder recuperar la información.

Con respecto al selector, este accede al control por medio del sus id, por eso el uso del #, pero de este se filtra además los seleccionados usando el :selected.

Por fuera de la función se crea un array de javascript para ubicar cada dato marcado, se inserta el texto resultante de cada item por medio de push(), y al final se lo une por medio del join(), para lograr un solo string.

Seguramente se habrá notado además el uso del una función format() para reemplazar en el texto ciertas posiciones con un dato en concreto, bien esta función en si no es estándar de javascript, sino que se encuentra definida en utils.js, y básicamente aplicaría como un método de extensión para los tipos de datos string.

El trabajo con combos es idéntico a la lista, pero solo se toma un ítem accediendo de forma directa, no requiere ser recorrido sus ítems, por eso es algo más simple aplicar los selectores.

 

Agregar / Remover Ítems

La sección marcada para el Ejemplo 3, representa la operación de agregar y remover elementos en una lista.

        function btnEj3Agregar_OnClick() {

            var ej3Texto = $('#txtEj3Texto');
            var ej3Valor = $('#txtEj3Valor');

            var newItem = $('<option/>').text(ej3Texto.val()).val(ej3Valor.val());
            $("#Ej3Select").append(newItem);

        }
        
        function btnEj3AgregarDespuesSeleccion_OnClick() {

            var itemsSelected = $('#Ej3Select :selected');

            if (itemsSelected.length == 0) {
                alert('Debe seleccionar un item');
                return;
            }
                
            var ej3Texto = $('#txtEj3Texto');
            var ej3Valor = $('#txtEj3Valor');

            var newItem = $('<option/>').text(ej3Texto.val()).val(ej3Valor.val());
            newItem.insertAfter(itemsSelected[0]);

        }
        

        function btnEj3Seleccion_OnClick() {
        
            var list = new Array();

            $.each($('#Ej3Select :selected'), function() {

                var msg = 'texto: {0}, valor: {1} 
'.format($(this).text(), $(this).val());
                list.push(msg);

            });

            $('#Ej3Resultado').html(list.join(''));
            
        }

        function btnEj3RemoverSeleccion_OnClick() {

            $.each($('#Ej3Select :selected'), function() {

                $(this).remove();

            });
        }

El agregar una nueva opción requiere que el html de <opción> sea creado, es por eso que se define este en el selector, para luego disponer de método de text() y val() para asignar la información proveniente del input del usuario.

Una vez creado el nuevo ítem solo se hace un append() a la lista existente, también se podrían usar métodos como ser insertBefore() o insertAfter() para controlar la ubicación del nuevo elemento, pero esto requiere que se indique que elemento será tomado como objetivo. En el ejemplo al hacer uso de estos métodos se debe asegurar que al menos un ítem esta marcado para que funcione correctamente, si mas de uno se ha seleccionado solo se toma el primero.

El remover un ítem es muy simple, solo se recorre la selección y se aplica el remove(), al igual que en la selección, el this representa cada ítem en el loop, aquí también es necesario aplicar nuevamente el selector para tener acceso a los método de jquery implementa.

Trabajar con combos es idéntico a las listas, solo que se opera con un solo ítem a la vez, el ejemplo 4 implementa justamente estas acciones en un combo:

function btnEj4Agregar_OnClick() {

    var ej4Texto = $('#txtEj4Texto');
    var ej4Valor = $('#txtEj4Valor');

    var newItem = $('<option/>').text(ej4Texto.val()).val(ej4Valor.val());
    $("#Ej4Select").append(newItem);

}

function btnEj4Seleccion_OnClick() {

    var optionSelected = $('#Ej4Select :selected');

    var msg = 'texto: {0}, valor: {1}'.format(optionSelected.text(), optionSelected.val());

    $('#Ej4Resultado').html(msg);

}

function btnEj4RemoverSeleccion_OnClick() {

    $('#Ej4Select :selected').remove()

}

Algo que quizás no he marcado en los otros ejemplos es que al utilizar algo como esto

var optionSelected = $('#Ej4Select :selected');

se debe comprender que se esta asignado a la variable la selección del objeto completo, es por eso que luego se puede acceder a la funcionalidad provista por jquery.

 

Asignar Selección

En algún momento seguramente se requiera marcar un valor de la lista o combo sin que el usuario realice la acción, sino que será por medio de código, por suerte jquery hace esto muy simple, implementándose de igual forma no importa de que lista se trate.

En los ejemplos 5 y 6, se puede apreciar la implementación:

function btnEj5SeleccionarPorValor_OnClick() {

    var valor = $('#txtEj5').val();
    
    $('#Ej5Select').val(valor);

}

function btnEj6SeleccionarPorValor_OnClick() {

    var valor = $('#txtEj6').val();

    $('#Ej6Select').val(valor);

}

Si se escribe un valor correcto en el TextBox, solo hará falta asignar el val() al selector del control y eso es todo.

Listas ASP.NET

Hasta ahora hemos estado trabajando en los ejemplos con controles html, pero se debió a que operar con estos o con el control de lista o combo del asp.net es idéntico.

En el ejemplo 7 se podrá apreciar justamente este punto:

 

        function btnEj7Agregar_OnClick() {

            var ej7Texto = $('#txtEj7Texto');
            var ej7Valor = $('#txtEj7Valor');

            var newItem = $('<option/>').text(ej7Texto.val()).val(ej7Valor.val());
            $('#<%=Ej7Select.ClientID%>').append(newItem);

        }

        function btnEj7Seleccion_OnClick() {

            var list = new Array();

            $.each($('#<%=Ej7Select.ClientID%> :selected'), function() {

                var msg = 'texto: {0}, valor: {1} 
'.format($(this).text(), $(this).val());
                list.push(msg);

            });

            $('#Ej7Resultado').html(list.join(''));

        }
        
        function btnEj7RemoverSeleccion_OnClick() {

            $.each($('#<%=Ej7Select.ClientID%> :selected'), function() {

                $(this).remove();

            });
        }

Aplicar selectores a un control de asp.net solo requiere el uso de la propiedad ClientID, si es que se usa el id del control para acceder al mismo, esto se aplica por si asp.net renombra esta propiedad al realizar el render del html que envía al cliente.

 

Código de Ejemplo

 

domingo, 17 de abril de 2011

[jQuery] Por donde comenzar

 

Introducción

jQuery es una de las librerías muy mencionada en los ultimo tiempo para el desarrollo de aplicaciones web.

Usar javascript de forma estándar puede ser algo bastante tedioso ya que no es una sintaxis del todo amigable para el trabajo diario, o al menos para quien esta acostumbrado a programa en un lenguaje amenos como ser C# o VB.NET.

Es por eso que surge jQuery, para solventar este problema, siendo el mas conocido entre los frameworks de javascript, (esta se gano su lugar en los témplate para la creación de proyectos como son los utilizados en aplicaciones con ASP.NET MVC), y el que dio impulso a la utilización de este tipo de frameworks,  vale aclarar además que también existen otro como ser: Prototype, MooTools, etc

Este articulo en particular se sumara a los miles que existen publicados para aportar un punto de inicio para quienes aun no conocen la magia de esta librería.

Aquí no se pretende explicar cada unos de los aspectos de jQuery, porque solo el tema se selectores es enorme y muy variado, sino que iremos a casos concretos, y analizaremos particularidades en el uso de la librería.

jQuery es muy amplio, con mucha flexibilidad, cuando la usen verán que no hay una sola forma de hacer las cosas, a veces se pueden aplicar un selector con distintas combinaciones y todas estarán correctas.

Es por eso que es necesario recurrir a la fuente y consultar la documentación provista por la propia librería en su sitio web: jQuery

Para empezar veremos dos puntos básicos que afectan a la interacciones de asp.net y javascript, luego continuaremos con el análisis de dos controles simples para entrar en tema.

 

1 – Acceder a los controles de asp.net

Algo que debe conocerse cuando se trabaja con controles desde javascript es como hacer referencia a estos.

Por ejemplo, si en el html de una pagina se define:

<input id="Text1" type="text" />

desde javascript podría seleccionar el control usando:

var text1 = document.getElementById('Text1');

de esta forma se seleccionado el control cuando se trata de uno del tipo html, pero que sucede si ahora se tiene un control de asp.net, aquí ya no somos quienes controlamos el render del control, por lo tanto el ID asignado al mismo puede variar.

Muy bien, ahora si realizamos unas pruebas y ponemos un asp:TextBox en una página

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

al acceder desde el browser se vera como

<input name="TextBox1" type="text" id="TextBox1" />

ups, pero que sucedió aquí el id no se modifico, seguro pensaran que estoy mintiendo, pues bien, lo que sucede es que en algunas situaciones asp.net no cambie el id del control, porque en este caso no lo requiere, el verdadero problema se presente cuando este control esta contenido dentro de ciertos contenedores, como ser: un User Control, la Master Page, o controles que repiten un témplate, como ser el ListView, GridView, Repeater, etc

Entonces que sucede ahora si se crear un User Control (WebUserControl1.ascx) con el textbox dentro del mismo y se lo ubica en una pagina, al acceder al código del browser se obtendrá

<input name="WebUserControl11$TextBox1" type="text" id="WebUserControl11_TextBox1" />

Ahora si se comprueba como asp.net modifica el id asignado al control en tiempo de diseño, asp.net necesito ponerle un prefijo con el nombre del User Control para que este sea único, ya que en la pagina puede usarse mas de un mismo user control, sino redefine el id puede haber colisiones en los nombres.

Como se haría para seleccionar este control sino se conoce previamente el id que será generado, pues bien, se dispone en asp.net de la propiedad ClientID, siendo usada de la siguiente forma:

var userControlText1 = document.getElementById('<%=TextBox1.ClientID%>');

al inspeccionar el código resultante en el browser se obtendrá

var userControlText1 = document.getElementById('WebUserControl11_TextBox1');

el tag <%=  %> permite ubicar allí el valor de la propiedad ClientID.

Si bien esto que comento parece un dato menos, es bastante importante cuando se comienzan a dar los primeros paso en javascript mezclado con controles del asp.net

 

2 – Acceder a controles asp.net desde un archivo .js

Continuando con el tip del punto anterior, avanzaremos en un tema que por ahí pueda generar dificultades a la hora de ordenar el código.

En algunas oportunidades uno requiera hacer uso de archivos .js para llevar allí el código javascript y trabajarlo de forma separada al html que esta en el aspx, pero es aquí donde empiezan los problemas.

Resulta que si se hace uso del tag <% %>, este solo puede ser aplicado dentro de la página donde se hace el render por parte de asp.net, o sea solo funciona dentro del aspx

El archivo .js es referenciado por el aspx, pero este no se incluye en el proceso de render, por lo tanto el ClientID nunca será reemplazado.

Pero hay una solución a este punto, la cual consiste en dejar la definición del tag <% %> dentro del aspx, pero que la misma solo asigne a una variable javascript el nombre del control, luego sera usada en el .js para así poder tomar el control y trabajarlo.

En la carpeta “Ejemplo2” esta la implementación del código de ejemplo, se observara la declaración de las líneas

<script type="text/javascript">

    var TextBox1 = '<%=TextBox1.ClientID%>';

</script>

en donde se asigna en la pagina aspx el nombre como string, para luego dentro del .js usar

function ObtenerValor() {

    var text1 = document.getElementById(TextBox1);
    alert(text1.value);

}

Es necesario apreciar como cambio la selección al usar el getElementById(), usando ahora el nombre de la variable.

El único problema que se presenta es que por cada control que se quiera usar dentro de .js será necesario crear una variable en la pagina que incluya el ID que asp.net asigna.

 

3 – Obtener y asignar el valor de un Texbox

Seguramente se preguntaran “cuando comenzamos”, es cierto hasta aquí se presentaron temas mas relacionados con javascript, que al propio jquery, pero eran necesario tenerlos presente ya que estos también afectan al desarrollo.

Bien, comencemos con algo simple.

Seleccionemos el valor de un TextBox, copiando el contenido a otro:

[HTML]

<form id="form1" runat="server">
    <table>
        <tr>
            <td>
                <input id="txtInfo" type="text" />
            </td>
            <td> 
                <input id="btnMostrar" type="button" value="button" onclick="Mostrar_OnClick();"/>
            </td>
            
        </tr>
        <tr>
            <td colspan="2"> 
                <input id="txtInfoCopia" type="text" />
            </td>
        </tr>
    </table>
</form>

[JavaScript]

function Mostrar_OnClick() {

    var info = $('#txtInfo').val();

    $('#txtInfoCopia').val(info);
    
}
 

como se observa jquery lo hizo bien simple.

Es preciso conocer que cuando uno selecciona un control y lo hace por el atributo “id” debe anteponer el “#”, este es uno de los tanto selectores tiene jquery que iremos viendo.

Para que esto funcione es necesario contar con la librería, en este caso se encuentra en la línea

<script src="../script/jquery-1.5.2.min.js" type="text/javascript"></script>

por lo general se sitúa en la propia pagina, pero también es común verlo en la Master Page para que todas incluyan la librería, y no se tenga que declarar en cada una particularmente.

Y que sucede si se tratan de controles de asp.net, bien es igual de simple, pero conociendo lo que vimos en el punto: “1 – Acceder a los controles de asp.net”, se obtendría la misma funcionalidad usando:

[JavaScript]

function MostrarASPNET_OnClick() {

    var info = $('#<%=txtInfoASPNET.ClientID%>').val();

    $('#<%=txtInfoCopiaASPNET.ClientID%>').val(info);

}

Avancemos un poco inicializando los textbox, para hacerlo individualmente se podría aplicar algo como esto:

[JavaScript]

function LimpiarASPNET_OnClick() {

    $('#<%=txtInfoASPNET.ClientID%>').val('');

    $('#<%=txtInfoCopiaASPNET.ClientID%>').val('');

}

es idéntico a lo que ya se viene viendo solo que no se le pasa valor

Y si se quiere limpiar el contenido de todos los textbox, se deberá asignar uno a uno?, no es necesario, hay técnicas mucho mas simples:

[JavaScript]

function LimpiarTodos_OnClick() {

    $(':text').val('');

}

aquí se puede ver otro selector distinto proporcionado por jQuery, en este caso se trata de un selector por tipo text el cual aplicara el valor a todos los controles que encuentre del tipo textbox.

Ahora bien, lo lindo que tiene esta librería es que no hay una sola forma de hacer esto, si se revisa la documentación: :text Selector, menciona que usar $('[type=text]') o $('*:text') y también $('input:text') son equivalentes, pero por simplicidad en la escritura se aplica :text

Nota: los ejemplos de esta sección se encuentra en el “Ejemplo 3” del código publicado.

4 – Trabajar con controles Label

Asignar un valor a un label difiere un poco de como se haría a un TextBox.

En el ejemplo de la carpeta “Ejemplo 4” se encontrara una muestra de como trabajar con este otro control.

en la pagina se agrego un label html

<label id="lblInfoCopia" />

y uno de asp.net

<asp:Label ID="lblInfoCopiaASPNET" runat="server"></asp:Label>

accederlo de forma individual no representa mayor problema, salvo por el hecho de cambiar el val() por el html() para tomar o asignar un valor.

Pero el seleccionar todos los labels de la pagina no es tan directo, ya que se renderiza diferentes en html estos controles, si se analiza el código generado en el browser se notara que el label de html sigue siendo un label, pero el de asp.net no lo es, ya que es transformado a un tag <span> cuando se convierte

Es por esto que debe seleccionarse distinto cada control.

[JavaScript]

function Mostrar_OnClick() {

    var info = $('#txtInfo').val();

    $('#lblInfoCopia').html(info);

}

function MostrarASPNET_OnClick() {

    var info = $('#<%=txtInfoASPNET.ClientID%>').val();

    $('#<%=lblInfoCopiaASPNET.ClientID%>').html(info);

}

function LimpiarASPNET_OnClick() {

    $('#<%=txtInfoASPNET.ClientID%>').val('');

    $('#<%=lblInfoCopiaASPNET.ClientID%>').html('');

}

function LimpiarTodos_OnClick() {

    $(':text').val('');
    $('label').html('');
    $('span').html('');
}

 

 

Conclusión

Hasta aquí hemos tenido una introducción general a las particularidades del uso de javascript cuando se tratan controles asp.net.

También hemos visto como tratar dos controles muy usados en las paginas como son los textbox y labels.

En próximos artículos veremos mas controles ya sean html o asp.net, como adjuntar evento y recorrer el resultado de una selección para trabajar con cada uno de sus ítems

 

Código Ejemplo