En el post anterior (Mostrar un formulario modal con ASP.NET MVC y Ajax) comenté como había usado SimpleModal en una aplicación ASP.NET MVC para mostrar un formulario modal al usuario.
En este post voy a comentar como podemos comunicar nuestro formulario modal con nuestros controladores, para así poder validar (parcialmente o totalmente) el formulario desde servidor, sin necesidad de hacer un submit, usando Ajax.
En mi caso p.ej. a medida que el usuario va entrando un posible nickname, se le indica si dicho nickname ya está ocupado o no (aunqué en la versión final probablemente sea un boton “comprobar nick”, ya que una llamada Ajax cada vez que se entre un carácter en un textbox quizá es demasiado… pero eso no afecta al sentido del post). Para realizar las llamadas Ajax cada vez que el usuario pulse una tecla en el campo “nick” del formulario modal vamos a usar jQuery.
Lo primero que debemos cambiar respecto al post anterior es la forma en como abrimos el formulario modal: el método modal de SimpleModal, admite varios parámetros, uno de los cuales es una función de callback que SimpleModal llamará. A través de esta función vamos a registrar una función gestora del evento KeyPress usando jQuery. Recordáis la función show_popup() que teníamos en la vista Index.aspx? Su código ahora queda así:
function show_popup() {
$("#popup").modal( { onOpen: popup_open});
}
Hemos añadido el parámetro onOpen con el nombre de una función javascript que SimpleModal nos llamará cuando deba abrir el formulario modal.
Una particularidad de SimpleModal es que si usamos la función de callback onOpen, debemos encargarnos nosotros de abrir el formulario modal. Así el código de la función popup_open queda así:
function popup_open(dialog) {
dialog.overlay.show(1);
dialog.container.show(1);
dialog.data.show(1);
}
Debemos llamar al método show (un método estándar definido en jQuery) con los tres elementos que componen el formulario modal de SimpleModal: Overlay (que lo que hace es inhabilitar el resto de la pantalla), Container (que muestra el borde del formulario) y Data (que muestra el contenido del formulario).
Otra forma “más jQuery” de realizar lo mismo es encadenar las llamadas: Generalmente todos los métodos jQuery aceptan un parámetro callback con código a realizar cuando se termine el método. Así también podríamos escribir la función popup_open como:
function popup_open(dialog) {
dialog.overlay.show(1,function() {
dialog.container.show(1,function() {
dialog.data.show(1);
});
});
}
El siguiente paso es añadir el código para suscribirnos al evento onKeyPress del textbox cuyo id era “nick”. jQuery unifica todos los eventos de los distintos browsers en un conjunto de eventos propio, lo que permite más fácilmente desarrollar aplicaciones cross-browser. El método keypress de un objeto jQuery permite suscribir un callback al evento de pulsación de una tecla. Un objeto jQuery es un objeto javascript que se obtiene generalmente usando la función selector (comúnmente llamada $) de jQuery. Así la llamada:
$("#popup")
Me devuelve el objeto jQuery asociado al elemento DOM cuyo ID sea “popup”. Esto no es equivalente a document.getElementById(“popup”) que me devuelve el objeto DOM directamente… es mucho mejor, ya que sobre el objeto jQuery puedo usar todas las propiedades de jQuery (como el método show() que hemos visto antes o el método modal() que define SimpleModal)!
Así pues, para suscribirnos al keypress del textbox cuyo ID es “nick” usando jQuery, el código de popup_open queda:
function popup_open(dialog) {
dialog.overlay.show(1, function() {
dialog.container.show(1, function() {
dialog.data.show(1, function() {
$("#nick").keypress(function(e) { });
});
});
});
}
Ahora sólo nos rellenar la función anónima que pasamos como parámetro a la llamada a keypress con el código que realice una petición Ajax a un controlador para que compruebe si el nick que se ha entrado está libre o no. Para ello vamos a usar la función getJSON de jQuery, que lo que hace es realizar una petición Ajax a la URL especificada, esperar la respuesta en formato JSON, deserializar la respuesta en un objeto Javascript y ejecutar el método de callback que nosotros le indiquemos.
Así, pues usando getJSON el código de popup_open queda así:
function popup_open(dialog) {
dialog.overlay.show(1, function() {
dialog.container.show(1, function() {
dialog.data.show(1, function() {
$("#nick").keypress(function(e) {
if (e.which != 13 && e.which != 8
&& e.which != 0) {
var str = this.value +
String.fromCharCode(e.which);
var url = "/Account/Check";
$.getJSON(url, { nick: escape(str) },
function(data) {
if (data.existeix) {
$("#invalid_nick").show();
}
else {
$("#invalid_nick").hide();
}
});
}
});
});
});
});
}
Dentro de la función gestora del evento keypress:
- Miramos que la tecla pulsada NO sea enter, backspace o tabulador
- Llamamos a getJSON con la URL /Account/Check (parámetro 1), con el valor del textbox codificado como parámetro (parámetro 2) y la función de callback que queremos ejecutar cuando recibamos la respuesta del servidor (parámetro 3 que es un método anónimo).
- Dentro del método anónimo, miramos si el valor del campo “existeix” del objeto recibido como parámetro es true para mostrar u ocultar un objeto cuyo ID es “invalid_nick”.
¿Que nos queda por hacer? Pues por un lado modificar la vista parcial que es el formulario modal (en mi caso era SignupPopup.ascx), para añadir un <DIV> con un id “invalid_nick” con un mensaje que ponga “NICK INCORRECTO” (o algo así). P.ej:
<div id="invalid_nick" style="display:none">
NICK IS INVALID
</div>
Inicialmente lo tenemos oculto (evidentemente usaríamos CSS y alguna imágen para hacerlo más “bonito”), puesto que lo mostramos via jQuery.
Por último lo que nos queda es hacer la función correspondiente en el controlador. En mi caso el controlador es AccountController y la acción es “Check” (como se puede deducir de la URL /Account/Check):
public ActionResult Check(string nick)
{
return new JsonResult() {
Data = new {existeix = nick.Length % 2 == 0 }
};
}
Esta acción en lugar de devolver una vista, devuelve un objeto serializado en JSON, usando JsonResult. Básicamente cuando queráis devolver un objeto codificado en JSON usando ASP.NET MVC:
- Creais un JsonResult.
- A la propiedad Data la asignais el objeto a serializar.
Esta función devuelve un objeto con una propiedad “existeix” que vale true si el nick tiene un número par de carácteres.
¡Ya lo tenemos todo listo! Ahora si vais tecleando carácteres en el formulario, se ve como se muestra o se oculta la etiqueta “NICK IS INVALID”.
¿Fácil, verdad?
Saludos!
PD: Recordais lo que os dije, que cuando usabamos el callback onOpen de SimpleModal debíamos “abrir” manualmente el overlay, el container y la data y que eso nos daba capacidades interesantes? Este “interesantes” viene por la API de animación de jQuery. P.ej. si podríamos cambiar los show() por llamadas a fadeIn para que la aparición del formulario sea más espectacular:
function popup_open(dialog) {
dialog.overlay.fadeIn('slow', function() {
dialog.container.fadeIn('slow', function() {
dialog.data.fadeIn('slow', function() {
// A partir de aquí todo igual...
});
});
});
}
¡Y observad como se despliega suavemente el formulario! 😉