Archivo de la categoría 'JavaScript'


Llamar a métodos de una página ASP.NET desde JavaScript con jQuery

Sábado, 16 abr, 2011 @ 18:12 | Por Gustavo Cantero (The Wolf) | ASP.NET, jQuery

Cada vez es más frecuente ver aplicaciones que utilizan AJAX para obtener información de algún proceso del servidor y con ella actualizar la página. Con .NET esto se puede hacer fácilmente utilizando el ScriptManager para llamar a servicios web, pero muchas veces no queremos agregar tanta complejidad porque simplemente necesitamos llamar a un método que nos devuelva, por ejemplo, la hora de nuestro server.

Para hacer lo mencionado podemos crear un WebMethod en nuestra página y llamarlo utilizando jQuery (casi todos los sitios web actualmente utilizan jQuery para alguna tarea).

Vamos a explicar cómo hacerlo creando un ejemplo sencillo, en el cual vamos a tomar dos números ingresados por el usuario en campos de texto, los vamos a enviar al WebMethod donde vamos a sumarlo (esta tarea se va a realizar en el servidor) y luego devolveremos el resultado a la página.
En el código de nuestra página vamos a agregar el método pero teniendo en cuenta que debemos agregarle el atributo “WebMethod” como muestro a continuación:

using System;
using System.Web.Services;

namespace Ejemplo
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        [WebMethod]
        public static double Sumar(double Valor1, double Valor2)
        {
            return Valor1 + Valor2;
        }
    }
}

Pero para que este método pueda ser llamado desde una página también debemos agregar en el web.config la referencia al HttpModule que maneja estas llamadas:

<?xml version="1.0"?>

<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <httpModules>
      <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    </httpModules>
  </system.web>
</configuration>

Con esto ya terminamos de hacer todo lo necesario en .NET para que nuestros scripts puedan utilizar este método. Ahora debemos agregar la llamada desde nuestra página. Para hacerlo debemos agregar el archivo de JavaScript con la librería de jQuery a nuestra página. Podemos descargar esta librería y “apuntar” a este archivo o simplemente podemos hacer que nuestra página la descargue de los servidores de Microsoft, Google o jQuery (en el ejemplo hago esto último). En la página http://docs.jquery.com/Downloading_jQuery podemos ver las distintas opciones de descarga o utilización de los CDN (Content Delivery Network) que podemos utilizar.

Entonces, en nuestra página de ejemplo, agregamos el siguiente elemento de HTML para que obtenga la librería del CDN de Microsoft:

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.2.min.js" type="text/javascript"></script>

Ahora que tenemos la librería podemos llamar a nuestro método desde nuestra página de la siguiente manera:

$.ajax({
    //Tipo de llamada
    type: "POST",

    //Dirección del WebMethod, o sea, Página.aspx/Método
    url: "Default.aspx/Sumar",

    //Parámetros para pasarle al método
    data: '{Valor1: 22, Valor2: 33}', 

    //Tipo de contenido
    contentType: "application/json; charset=utf-8",

    //Tipo de datos
    dataType: "json",

    //Función a la cual llamar cuando se pudo llamar satisfactoriamente al método
    success: resultado,

    //Función a la cual llamar cuando se producen errores
    error: errores
});

A continuación les dejo el HTML completo de nuestra página de ejemplo, donde toma los dos números, los envía a nuestro método y luego pone el resultado en otro campo de texto:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.2.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $('#btnSumar').click(function () {
                var num1 = $('#num1').val(); //Obtenemos el primer número
                var num2 = $('#num2').val(); //Obtenemos el segundo número
                $.ajax({
                    type: "POST",
                    url: "Default.aspx/Sumar",
                    data: '{Valor1: ' + num1 + ', Valor2: ' + num2 + '}',
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: resultado,
                    error: errores
                });
            });
        });
        function resultado(msg) {
            //msg.d tiene el resultado devuelto por el método
            $('#num3').val(msg.d);
        }
        function errores(msg) {
            //msg.responseText tiene el mensaje de error enviado por el servidor
            alert('Error: ' + msg.responseText);
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <br />
        <br />
        <br />
        <input type="text" id="num1" />
        +
        <input type="text" id="num2" />
        <input type="button" value="=" id="btnSumar" />
        <input type="text" id="num3" disabled />
    </div>
    </form>
</body>
</html>

Como verán utilizar WebMethods de ASP.NET desde jQuery es muy sencillo y útil, y puede servirnos en muchas tareas, por ejemplo, en formularios de envío de mail para no tener que recargar la página, para crear campos con “autocomplete”, para obtener información actualizada por otros usuarios sin necesidad de refrescar la página (como hace Facebook), etc.

También les dejo un proyecto con el ejemplo anterior funcionando:

Espero que les sea de utilidad.

Suerte!

VN:F [1.7.3_972]
Rating: 6.7/10 (16 votos cast)

Migrar de Google Maps v2 a Google Maps v3

Lunes, 21 feb, 2011 @ 10:39 | Por Gustavo Cantero (The Wolf) | GIS/Geolocalización, JavaScript

Quien haya desarrollado alguna aplicación web que contenga mapas utilizando la versión 2 de la API de Google Maps y haya querido migrar a la versión 3 (ya que es la versión oficial, funciona mucho mejor en dispositivos móviles y la anterior ya ha quedado oficialmente descartada), se habrá dado cuenta que no es tan sencillo como cambiar el JS a utilizar y listo, sino que cambiaron muchas cosas, por ejemplo, ahora las clases no comienzan con la letra G (como GMap) sino que utilizan el namespace google.maps (como google.maps.Map).

Este artículo tiene la idea de ser una guía básica para migrar de la versión 2 a la 3 de esta API, mostrando dónde cambiaron las cosas que comúnmente utilizamos. Para esto dividí el artículo en tareas donde muestro cómo hacerlas con ambas versiones para que sea más fácil de encontrar lo que estamos buscando.

Librería JS

Para comenzar tendremos que utilizar el JS de la nueva versión, por lo cual, donde antes apuntábamos a

http://maps.google.com/maps?file=api&v=2&key=API_KEY

ahora debemos apuntarlo a

http://maps.google.com/maps/api/js?sensor=false

Nótese que ahora no necesitamos utilizar el API_KEY, por lo tanto, ya no es necesario registrar la URL del sitio donde vamos a utilizar los mapas. También hay un nuevo parámetro llamado “sensor”, el cual establece si se debe obtener la ubicación de un usuario a través de un sensor. Para más información sobre este parámetro pueden consultar la Especificación del parámetro sensor.

Creación del mapa

Lo siguiente a modificar es la creación del mapa. Por ejemplo, en la versión 2 creábamos un mapa en el div “miMapa” de esta manera:

var mapa = new GMap2(document.getElementById('miMapa'));

ahora deberemos crearlo de esta manera:

var mapa = new google.maps.Map(document.getElementById('miMapa'));

Me gustaría comentar que en la nueva versión se puede establecer como segundo parámetro del constructor la mayoría de las opciones que veremos a continuación, permitiendo de esta manera crear el mapa de la manera que necesitamos de una vez. Para ver las distintas opciones disponibles consultar la Especificación del objeto MapOptions.

Ubicación (coordenadas) y zoom del mapa

Para centrar el mapa y hacerle zoom antes hacíamos esto:

var miPosicion = new GLatLng(latitud, longitud);
mapa.setCenter(miPosicion, nivelDeZoom);

Ahora debemos hacerlo de esta manera:

var miPosicion = new google.maps.LatLng(latitud, longitud);
mapa.setCenter(miPosicion);
mapa.setZoom(nivelDeZoom);

Si se prefiere, se pueden establecer cambiando las opciones del mapa, de esta manera:

var miPosicion = new google.maps.LatLng(latitud, longitud);
mapa.setOptions({
    center: miPosicion,
    zoom: nivelDeZoom
});

Tipo de mapa

Un punto a tener en cuenta con la nueva versión de la API es que antes, por defecto, nos mostraba el mapa del tipo “normal”, o sea, las calles sin imágenes satelitales, pero ahora si no le establecemos un tipo de mapa no nos muestra nada.
Entonces, antes para establecer el tipo de mapa (por ejemplo, satelital) hacíamos esto:

mapa.setMapType(G_SATELLITE_MAP);

Pero ahora es así:

mapa.setMapTypeId(google.maps.MapTypeId.SATELLITE);

Este valor también se puede establecer al momento de crear el mapa con la opción “mapTypeId”.
Para ver los distintos tipos de mapas posibles para la versión 3 pueden consultar la clase MapTypeId, y para los de la versión 2 pueden consultar la clase GMapType.

Controles de navegación

Antes para agregar un control de navegación, por ejemplo el control “chico”, debíamos hacer:

mapa.addControl(new GSmallMapControl());

Ahora, en cambio debemos hacerlo así:

mapa.setOptions({
    navigationControl: true,
    navigationControlOptions: { style: google.maps.NavigationControlStyle.SMALL}
});

Para ver que otros tipos de controles de navegación hay pueden consultar las constantes que hay en la clase NavigationControlStyle.

Agregar marcadores

Para crear marcadores con una imagen personalizada hasta ahora hacíamos:

var icono = new GIcon(G_DEFAULT_ICON);
icono.image = 'Images/MiImagen.png';
var marcador = new GMarker(new GLatLng(latitud, longitud), {
    icon: icono,
    title: 'Este es mi marcador'
});
mapa.addOverlay(marcador);

En cambio ahora debemos hacer:

var marcador = new google.maps.Marker({
    position: new google.maps.LatLng(latitud, longitud),
    map: mapa,
    icon: 'Images/MiImagen.png',
    title: 'Este es mi marcador'
});

Quitar marcadores

Para sacar un marcador, por ejemplo el creado en el paso anterior, en la versión 2 hacíamos:

mapa.removeOverlay(marcador);

En cambio en la versión 3 hacemos:

marcador.setMap(null);

Algo a tener en cuenta es que en la versión anterior para eliminar todo los marcadores (y demás objetos) del mapa podíamos utilizar la siguiente línea:

mapa.clearOverlays();

Pero en la versión 3 tenemos que guardar la referencia de cada marcador (por ejemplo, en un vector) para luego llamar al “setMap(null)” de cada uno.

InfoWindow en un mapa

Para abrir una “viñeta” con información dentro de un mapa hacíamos:

var posicion = new GLatLng(latitud, longitud);
mapa.openInfoWindowHtml(posicion, 'Esta es mi viñeta');

En cambio ahora es:

var infoWin = new google.maps.InfoWindow({
  content: 'Esta es mi viñeta',
  position: google.maps.LatLng(latitud, longitud)
});

InfoWindow en un marcador

También podíamos abrir “viñetas” sobre un marcador de la siguiente manera:

marcador.openInfoWindowHtml('Esta es mi viñeta');

Pero ahora se hace de esta otra manera:

var infoWin = new google.maps.InfoWindow({
    content: 'Esta es mi viñeta'
});
infoWin.open(mapa, marcador);

Controles personalizados sobre el mapa

Hay veces que necesitamos crear nuestros propios controles y agregarlos sobre el mapa. Para esto la versión 2 de Google Maps nos permitía hacerlo creando una clase que debía heredar de GControl. Por ejemplo, para agregar un DIV llamado “miControl” en la esquina superior izquierda del mapa podíamos hacer esto:

function miControl() { }
miControl.prototype = new GControl();
miControl.prototype.initialize = function (map) {
    var div = document.getElementById('miControl');
    ctlMap.getContainer().appendChild(div);
    return div;
}
miControl.prototype.getDefaultPosition = function () {
    return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(1, 1));
}

mapa.addControl(new miControl());

Pero ahora, con la versión 3 de la API, podemos hacerlo de una manera mucho más sencilla: simplemente agregando nuestro DIV a la pila de controles del mapa:

var div = document.getElementById('miControl');
mapa.controls[google.maps.ControlPosition.TOP_LEFT].push(div);

Ejemplo

Con estas pocas líneas voy a mostrar cómo hacer un mapa que se ubique en Bariloche mostrando el relieve de la región:

new google.maps.Map(document.getElementById('miMapa'), {
    center: new google.maps.LatLng(-41.156686, -71.302299),
    zoom: 10,
    mapTypeId: google.maps.MapTypeId.TERRAIN
};

Conclusión

La nueva versión de la API de Google Maps cambia muchas cosas y migrar los scripts de una versión a otra lleva tiempo, pero la nueva versión trae muchas mejoras y una vez migrado notaremos que la sintaxis es más cómoda en la nueva versión.
La referencia de la versión 2 de la API la pueden encontrar aquí y la de la versión 3 aquí. Cabe mencionar que la propia versión 3 está en continua evolución y ya va, a la fecha, por la versión 3.4. Para ver el historial de los cambios lo pueden hacer desde esta dirección: Javascript Maps API v3 Changelog.

Espero que esta nota les sea de utilidad y los invito a dejar sus comentarios.

¡Suerte!


VN:F [1.7.3_972]
Rating: 9.6/10 (12 votos cast)

Microsoft Ajax Minifier 4.0

Miércoles, 17 feb, 2010 @ 10:35 | Por Gustavo Cantero (The Wolf) | AJAX, ASP.NET, JavaScript

ASP.NETUna de las tareas que podemos realizar para reducir el tiempo de descarga inicial de nuestras aplicaciones es la eliminación de comentarios, espacios, puntos y coma y demás caracteres, y renombrar los objetos y variables utilizando nombres más cortos en nuestros archivos de JavaScript, pero realizar esta tarea manualmente esta pesada, repetitiva y propensa a errores, por lo tanto se utilizan herramientas que lo hacen automáticamente. Una de estas herramientas es el Microsoft Ajax Minifier, el cual, en su nueva versión 4.0 que salió ayer, también tiene soporte para archivos CSS, o sea, también elimina espacios, comentarios y caracteres innecesarios de los archivos de estilos.

El Microsoft Ajax Minifier 4.0 lo pueden descargar del siguiente enlace: http://aspnet.codeplex.com/releases/view/40584.

VN:F [1.7.3_972]
Rating: 5.0/10 (1 voto cast)

Llamar a funciones de JavaScript desde Silverlight y a métodos de Silverlight desde JavaScript

Domingo, 04 ene, 2009 @ 20:26 | Por Gustavo Cantero (The Wolf) | JavaScript, Silverlight

Ejecutar JavaScript desde Silverlight

Al desarrollar con Silverlight muchas veces necesitamos que nuestro control interactúe con el resto de la página, por ejemplo, con un botón de HTML o con un DIV, colocando dentro algún texto. Para poder lograr esto el framework de .NET que posee el Silverlight nos ofrece la clase HtmlPage, la cual se encuentra en el namespace System.Windows.Browser. Esta clase posee varias propiedades y métodos estáticos para interactuar con el navegador del cliente, por ejemplo, la propiedad BrowserInformation nos brinda información del navegador, pudiendo saber su versión a través de la siguiente propiedad: HtmlPage.BrowserInformation.BrowserVersion, o la plataforma sobre la cual está corriendo con esta otra: HtmlPage.BrowserInformation.Platform.
Para poder interactuar con la página que contiene a nuestro control en el cliente podemos utilizar la propiedad HtmlPage.Window, la cual posee una instancia del objeto window del navegador, pudiendo, por ejemplo, crear un “alert” con la siguiente línea:

HtmlPage.Window.Alert("Hola mundo!");

crear un diálogo de confirmación con esta otra:

bool bolOK = HtmlPage.Window.Confirm("¿Está seguro de hacer eso?");

o simplemente navegar a otra página:

HtmlPage.Window.Navigate("http://www.silverlight.net");

Pero si lo que necesitamos es llamar a una función creada en JavaScript, podemos utilizar el método Invoke, el cual toma como primer parámetro el nombre de la función a ejecutar, y los subsiguientes parámetros se los pasa a la función. El valor devuelto por el método es el retornado por la función ejecutada (si es que devuelve algún valor). Como ejemplo vamos a ejecutar la llamada a la función “alert” pero a través del método invoke:

HtmlPage.Window.Invoke("alert", "Hola mundo!");

Cabe mencionar que para que nuestra aplicación pueda interactuar con la página necesitamos agregar el parámetro HtmlAccess="Enabled" en la creación del objeto de Silverlight.

Ejecutar métodos de Silverlight desde JavaScript

También puede darse el caso que necesitemos llamar a algún método de nuestro control al ejecutarse algún evento de la página, por ejemplo, al pulsarse un botón de HTML, para lo cual necesitamos registrar nuestro objeto para que pueda ser accedido a través de JavaScript y el método (o todos los miembros) de la clase también como accesibles.
Comencemos por el primer paso: para registrar nuestro objeto, por ejemplo, el control, simplemente necesitamos ejecutar el método RegisterScriptableObject, pasándole como primer parámetro el nombre de la propiedad de JavaScript a través de la cual será accedido, y como segundo parámetro la instancia del mismo, por ejemplo:

HtmlPage.RegisterScriptableObject("Page", this);

El siguiente paso es registrar a la clase completa para que pueda ser accedida a través de JavaScript con el atributo ScriptableType, o registrar sólo los métodos que se necesitan usar, a través del atributo ScriptableMember.
A continuación muestro como ejemplo una aplicación Silverlight que posee marcado como accesible desde JavaScript un método que cambia el texto un botón del mismo.

public partial class Page : UserControl
{
    public Page()
    {
        InitializeComponent();
        HtmlPage.RegisterScriptableObject("Page", this);
    }
    [ScriptableMember]
    public void ChangeButtonText(string Text)
    {
        TextBlock objTB = new TextBlock();
        objTB.Text = Text;
        Button1.Content = objTB;
    }
}

Y la página que utiliza este método:

<body style="height: 100%; margin: 0; background-color: Blue">
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" />
    <input type="button" onclick="$get('Xaml1').Content.Page.ChangeButtonText('Html')"
        value="Prueba" />
    <div>
        <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/SilverlightApplication5.xap"
MinimumVersion="2.0.31005.0" Width="500" Height="300" Windowless="true" HtmlAccess="Enabled" />
    </div>
    </form>
</body>

Por último, dejo un ejemplo creado con Visual Studio® 2008 donde se muestra un botón en una aplicación de Silverlight que cambia el texto de un botón de HTML, y un botón de HTML que cambia el texto de un botón de Silverlight.
Proyecto de ejemplo de llamadas entre JavaScript y Silverlight
Espero que este artículo les sea de utilidad.

VN:F [1.7.3_972]
Rating: 8.5/10 (18 votos cast)