Está en la página 1de 14

Mostrar un formulario modal con ASP.

NET MVC y Ajax


Publicado 14/4/2009 14:11 por Eduard Toms i Avellana
Os gusta ASP.NET MVC? A mi personalmente me encanta aunque est un pocoverde, en el sentido que comparndolo con webforms hay varias cosas que debes hacerte tu mismo, el modelo de programacin es simple y elegante Gran parte del mrito lo tiene (adems del uso del patrn MVC evidentemente), jQuery genial librera de Javascript donde las haya. Hay mucha gente desarrollando en jQuery (al margen de que usen o no ASP.NET MVC) y dado lo bien que se entienden ASP.NET MVC y jQuery es muy fcil realizar tareas que antes eran un poco complejas. Yo me he encontrado con la necesidad de mostrar un pop-up (modal) en una aplicacin ASP.NET MVC. Un par de bsquedas por google me han llevado aSimpleModal, un genial plugin para jQuery que precisamente hace esto: mostrar formularios modales. En su pgina web hay varios ejemplos (en su caso l usa PHP). Os cuento como he integrado SimpleModal en mi aplicacin ASP.NET MVC por si a alguien le interesa Esta ha sido mi manera de hacerlo, no pretendo sentar ctedra porque hay muuuuuuucha gente que sabe ms que yo (especialmente de jQuery). En concreto la necesidad era mostrar un link, que al pulsarse desplegase un pop-up modal para que la gente pudiera darse de alta en la pgina. La pgina que muestra el enlace (en mi caso Index.aspx) tiene el siguiente cdigo ASP.NET: <%= Ajax.PopupLink ("Join the game", "Signup","Account", "popup") %> and start playing! <div id="popup" /> El mtodo PopupLink es un mtodo extensor de AjaxHelper: public static string PopupLink(this AjaxHelper helper, string linkText, string actionName, string controllerName, string popupId) { AjaxOptions options = new AjaxOptions() { UpdateTargetId = popupId, OnComplete = "show_popup", HttpMethod = "GET" }; string link = helper.ActionLink(linkText, actionName, controllerName, options); return link; } Ok no es un mtodo muy configurable, pero a mi me va bien :) Lo que hace es mostrar un enlace con el texto especificado y le establece unas opciones por defecto:

Que la llamada sea via Ajax usando GET, que se llame a una funcin javascript show_popup al terminar y que se actualice el elemento DOM especificado (en este caso el ltimo parmetro llamado popup). Los parmetros actionName y controllerName del mtodo sirven para especificar que accin de que controlador debe devolver la vista parcial que contiene el popup. En mi caso la accin Signup del controllador AccountController que est definida tal y como sigue: public ActionResult Signup() { if (Request.IsAjaxRequest()) { return PartialView("SignupPopup"); } else return RedirectToAction("Index", "Home"); } Como podeis ver me limito a devolver la vista parcial SignupPopup que es la que contiene el cdigo HTML del popup. Cuando el usuario haga click en el enlace Join the game se llamar via Ajax a la accin Signup que devolver la vista parcial SignupPopup, el cdigo de la cual se incrustar dentro del div popup. El cdigo de la vista parcial en mi caso es muy simple: <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> <div> <h1>Join the Game!</h1> <% using (Html.BeginForm("Signup", "Account", FormMethod.Post)) { %> <label for="nick">*Nick Name:</label> <input type="text" id="nick" name="nick" tabindex="1001" /> <br /> <label for="email">*Email:</label> <input type="text" id="email" name="email" tabindex="1002" /> <br /> <label>A email for validate your account will be sent at email address you specified.</label> <br /> <button type="submit" tabindex="1006">Send</button> <button type="reset" tabindex="1007">Cancel</button> <br/> <% } %> </div> Basicamente tenemos un formulario con dos campos: nick y email. Cuando hagamos un submit del formulario (via POST) se llamar a la accin Signup del controlador AccountController, accin que est definida como sigue: [AcceptVerbs(HttpVerbs.Post)] public ActionResult Signup(string nick, string email) { // Codigo para dar de alta el nuevo usuario... // Mostramos la vista de Bienvenida return View();

} No mucha cosa El controlador da de alta el usuario y finalmente muestra una vista de bienvenida. Finalmente en la pgina Index.aspx, debemos tener el mtodo javascript show_popup, que ser el encargado de mostrar el popup usando SimpleModal: <script type="text/javascript"> function show_popup() { $("#popup").modal(); } </script> El cdigo es muy simple: accedemos al elemento div con id=popup que hemos rellenado con el contenido de la vista parcial, y usamos el mtodo modal() que define SimpleModal para mostrar este div como un formulario modal y listos! Simple y sencillo en otro post mostrar como comunicar nuestro formulario via Ajax con nuestros controladores (p.ej. para poder validar datos en servidor sin necesidad de hacer submit del formulario).

Vistas & View Engines en ASP.NET MVC


NOV 29 Publicado por Marc Rubio

Partiendo de que la intencin de MVC es separar las responsabilidades de cada componente, me gustara explicar cual es la responsabilidad de las vistas y como utilizarlas en ASP.NET MVC. Lo que primero nos choca a los programadores que procedemos de los formularios web, es que han desaparecido los eventos y el famoso ciclo de vida, y eso se debe precisamente que ASP.NET MVC es mucho ms natural en los protocolos HTTP y HTML en su tratamiento.

Mvc vs WebForms Como se puede apreciar en la imagen los formularios web se basaban en los eventos para procesar una peticin, entrar en el ciclo de vida del documento, tratar el evento, pintar los controles y devolver el resultado.

Sin embargo las peticiones en MVC son mucho mas simples y respetuosas con el protocolo HTTP. La peticin la recibe el motor de rutas que mediante la URL decide cual es el controlador que la debe procesar, el Controlador puede consultar al modelo si es necesario y posteriormente devuelve un ActionResult que puede ser un fichero, datos en formato JSon, una vista, etc.

Vistas
Como ya he comentado la vista encapsula la lgica de presentacin y NO tiene que contener lgica de la aplicacin ni cdigo de recuperacin de datos. Las vistas no son ficheros fsicos ligados a una URL como en los formularios web. Cuando queramos consultar un formulario tenamos que poner su ruta fsicahttp://www.miaplicacion/personas.aspx En MVC es el controlador el que decide que vista servir y eso facilita que las url sean descriptivas y que los buscadores puedan indexar mejor las pginas de nuestra aplicacin SEO Friendly.

ViewBag:
Las vistas pueden recibir datos desde el controlador gracias al ViewBag que devuelve un diccionario de datos dinmicos. La gran diferencia con ViewData de las versiones anteriores de MVC, es que ViewBag aprovecha la opcin de c#4 para generar tipos dinmicamente y evita tener que hacer conversiones en la vista para obtener el tipo adecuado de los datos. En el Controlador: Definimos la propiedad que queremos pasar a la vista y el dato ViewBag.Message = "Welcome to ASP.NET MVC!"; 1 En la vista: desde la vista recuperamos el dato de una forma muy fcil. <h2>@ViewBag.Message</h2> 1 ViewData vs ViewBag: la gran diferencia es que ya no tenemos la necesidad de hacer conversiones de los datos para poder tratarlos correctamente 1 @*Tipo Fecha con tipos dinmicos*@</pre>
2 3 4 5
@*Tipo Fecha con ViewData*@</pre> <h1>@ViewBag.FechaVieBag.ToShortDateString()</h1> <pre>

6 7

<h1>@(((DateTime)ViewData["Fecha"]).ToShortDateString())</h1> <pre>

Tipos de Vistas de las que disponemos:


View Page: Vista principal. LayoutView: Pagina Maestra. ViewContentPage: Vista que utiliza una pgina Maestra predefinida. Partial View: Vista que se utiliza desde otra vista y no se puede llamar directamente. Como se utilizaban los user controls en los webForms. La vista parcial tiene acceso a su ViewData y al dela vista primaria, pero las actualizaciones de los datos de la vista parcial solo afectan a su viewData y no a la de la vista primaria.

View Engines
ASP.NET MVC utiliza view engines para generar las vistas y desde MVC3 disponemos de dos motores de vistas incluidos para utilizar directamente.

ASPX: Es el motor de vistas de ASP.NET con tipos personalizados ViewPage, ViewMasterPage y ViewUserControl que heredan de los tipos de pginas existentes .aspx, .ascx, .master. Razor: Motor de vistas ms cercano para los programadores de C# o VB Otros: Spark NDjango NVelocity

Convenciones
Hay un par de convenciones que nos afectan al trabajar con las vistas y nos ahorran interminables ficheros de configuracin.

Return View(): no tenemos que especificar explcitamente que vista estamos devolviendo, porque si no lo hacemos utilizar el nombre de la accin para encontrar la vista. Este ejemplo retorna la vista Create.
// GET: /Peliculas/Create public ActionResult Create()

1 2

3 4 5

{ return View(); }

Estructura Vista controlador: Los controladores se tendrn que llamar MyNombreController y las vistas estarn en una carpeta llamada MyNombre dentro de la carpeta Views. De esta manera el controlador encontrar la vista sin problemas.

En esta imagen las extensiones de los ficheros son .cshtml porque he utilizado el motor de vista Razor en C#, si utilizara VB seria .vbhtml y si utilizara el motor de vista ASPX sera (.aspx, .ascx, .Master)

ASP.NET MVC: Ajax Dialog Form Using jQuery UI


En uno de mis ltimos proyectos que tena que mostrar algo de informacin, acceder al usuario para editarlo utilizando una ventana de dilogo, publicaremos la informacin actualizada y vuelva a cargar por el usuario utilizando Ajax. Que necesitaba para llevar a cabo las operaciones con nombres de varios modelos por lo que se propuso crear un cdigo genrico que podra ser reutilizado una y otra vez. A continuacin se muestra una imagen de lo que estoy tratando de lograr.

El proyecto utiliz para el post de abajo se puede descargar aqu . En primer lugar, el modelo. Para este ejemplo, vamos a utilizar un modelo sencillo que contiene un poco de informacin sobre el perfil de un usuario.

1 2 3 4 5 6 7 8 9

pblico de clase Perfil { [Obligatorio] pblica string Name { conseguir ; establecer ;} [Obligatorio] [StringLength (10, MinimumLength = 3)] [Display (Name = "Apodo" )] pblica string NickName { conseguir ; establecer ;}

10 11 12 13 14 15 16

[Obligatorio] pblica string Email { conseguir ; establecer ;} [Obligatorio] pblica int Edad { conseguir ; establecer ;} }

En segundo lugar, tenemos que crear tres mtodos de accin. Uno se utiliza para mostrar la informacin del perfil, otra para mostrar el formulario para editar el perfil, y por ltimo otro que se utilizar para guardar el objeto perfil editado. Los dos primeros siempre debe devolver un PartialView como cada uno de estos mtodos de accin ser llamada usando Ajax, y su resultado ser cargado en elementos div, la primera en un div se utiliza para mostrar el perfil guardado y el segundo en el cuadro de dilogo de edicin. El tercer mtodo de accin devolver un PartialView si el ModelState es vlido por lo que los errores se pueden mostrar al usuario y un resultado Json indicando el saque fue un xito si todo iba bien. (Tenga en cuenta que en este ejemplo slo estoy almacenando la informacin de perfil en la sesin, pero obviamente esto sera almacenada en una base de datos u otro almacn de datos.)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

pblico Perfil ActionResult () { Perfil Perfil = nuevo perfil (); / / Recuperar el perfil perviously guardado si (Session [ "perfil" ]! = NULL ) profile = Session [ "perfil" ] como perfil; volver PartialView (perfil); } pblica ActionResult EditProfile () { Perfil Perfil = nuevo perfil (); / / Recuperar el perfil perviously guardado si (Session [ "perfil" ]! = NULL ) profile = Session [ "perfil" ] como perfil; volver PartialView (perfil); } [HttpPost] pblica EditProfile ActionResult (Perfil Perfil) { / / Si el ModelState es vlido luego regresar / / A pasa PartialView en el objeto de perfil

24 25 26 27 28 29 30 31 32 33 34 35 36 37

/ / Con los errores ModelState si (! ModelState.IsValid) volver PartialView ( "EditProfile" , perfil); / / Almacenar el objeto Perfil y regreso / / Json un resultado que indica el Perfil / / Se ha guardado Session [ "perfil" ] = perfil; volver Json ( nuevo {success = verdad }); }

Lo siguiente que necesitamos para crear las dos visiones parciales que corresponden a los dos primeros mtodos de accin que hemos creado anteriormente. En este ejemplo, la vista parcial de la accin EditProfile es prcticamente slo la vista stock creada por el frameowork MVC, excepto que he eliminado el elemento de entrada para enviar el formulario que vamos a utilizar los botones del cuadro de dilogo jQuery UI para enviarlo. El segundo punto de vista parcial, el que muestra el objeto de perfil guardado de nuevo en este ejemplo es la opinin stock con algunos elementos aadidos.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

@ usando DialogFormExample.MvcHelpers @ Modelo DialogFormExample.Models.Profile <fieldset> <legend> Contacto </ legend> <Div clase = "-campo de la pantalla" > Nombre: @ Html.DisplayFor (modelo => model.Name) </ Div> <Div clase = "-campo de la pantalla" > Apodo: @ Html.DisplayFor (modelo => model.NickName) </ Div> <Div clase = "-campo de la pantalla" > Email: @ Html.DisplayFor (modelo => model.Email) </ Div> <Div clase = "-campo de la pantalla" > Edad: @ Html.DisplayFor (modelo => model.Age) </ Div>

20 21 22 23 24 25 26 27

<Div clase = "right" > @ Html.DialogFormLink ( "Edit" , Url.Action ( "EditProfile" ), "Editar Perf </ Div> </ Fieldset>

La primera porcin de la vista parcial slo muestra los elementos de formulario necesarios para la edicin del modelo. Esto es slo la edicin de valores ver modificado ligeramente. El nuevo cdigo empieza por la lnea 25. Aqu he creado un mtodo de extensin para HtmlHelper llamado DialogFormLink que va a crear una etiqueta de ancla cargado con toda la informacin necesaria para hacer el trabajo de forma de dilogo. Aqu est el cdigo para el mtodo de extensin. Usted puede leer los comentarios de obtener una comprensin de los parmetros que requiere. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

/ / / <summary> / / / Crea un enlace que abrir un formulario de dilogo jQuery UI. / / / </ Summary> / / / <param Name="htmlHelper"> </ param> / / / <param Name="linkText"> El texto interno del elemento de anclaje </ param> / / / <param Name="dialogContentUrl"> La url que devolver el contenido que se carg / / / <param Name="dialogTitle"> El ttulo que se mostrar en la ventana de dilogo / / / <param Name="updateTargetId"> El id de la div que debe ser actualizado despu / / / <param Name="updateUrl"> La url que devolver el contenido que se carga en el / / / <returns> </ Returns> pblica esttica DialogFormLink MvcHtmlString ( este HtmlHelper htmlHelper, cadena string dialogId, cadena dialogTitle, cadena UpdateTargetId, cadena updateURL) { TagBuilder builder = nueva TagBuilder ( "a" ); builder.SetInnerText (linkText); builder.Attributes.Add ( "href" , dialogContentUrl); builder.Attributes.Add ( "data-dialog-ttulo" , dialogTitle); builder.Attributes.Add ( "data-update-target-id" , UpdateTargetId); builder.Attributes.Add ( "data-update-url" , updateURL); / / Aadir una clase css llamado DialogLink que ser / / Se utiliza para identificar la etiqueta de anclaje y para cablear / / La funcin jQuery builder.AddCssClass ( "DialogLink" ); volver nueva MvcHtmlString (builder.ToString ()); }

El mtodo de extensin superior que construye nuestra etiqueta de ancla utiliza los atributos de datos HTML5 para almacenar informacin como el ttulo de la ventana de

dilogo, la url que devolver el contenido de la ventana de dilogo, el id de la div se actualice despus de enviar el formulario y la url que actualizar la div objetivo. Ahora tenemos que aadir el div contenedor para almacenar la informacin de perfil en la vista de ndice.

1 2 3 4 5 6 7 8 9

@ { ViewBag.Title = "Pgina de inicio"; } < h2 > @ ViewBag.Message </ h2 > < div de id = "ProfileContainer" > @ {Html.RenderAction ("Perfil");} </ div >

Por ltimo, he hecho una lista de las secuencias de comandos y los archivos CSS que deben estar vinculados a continuacin en la pgina _layout para que todo funcione correctamente.

1 2 3 4 5 6 7 8 9 10 11 12 13

< cabeza > < meta charset = "utf-8" /> < ttulo > @ ViewBag.Title </ titulo > < vnculo href = "@ Url.Content (" ~ / Content / Site.css ")" rel = "stylesheet < vnculo href = "@ Url.Content (" ~ / Content / themes / base / jquery.ui.all. < guin src = "@ Url.Content (" ~ / Scripts/jquery-1.5.1.min.js ")" tipo = "tex < guin src = "@ Url.Content (" ~ / Scripts/modernizr-1.7.min.js ")" tipo = "te < guin src = "@ Url.Content (" ~ / Scripts/jquery-ui-1.8.11.min.js ")" tipo = <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="tex < guin src = "@ Url.Content (" ~ / scripts / jquery.validate.min.js ")" tipo = <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type= < guin src = "@ Url.Content (" ~ / scripts / DialogForm.js ")" tipo = "text / </ cabeza >

La ltima referencia de script anterior es un guin que escrib llamado DialogForm.js. Esta secuencia de comandos (que se muestra ms abajo) har que todo funcione.

1 2 3 4 5

$ ( funcin () { / / No permitir almacenamiento en memoria cach de formularios . $ AjaxSetup ({cache: true });

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

/ / Alambre el evento de clic de los enlaces de dilogo actuales o futuros $ ('. DialogLink '). vive (' click ', function () { var elemento = $ (this); / / var var var Recuperar los valores de los atributos de datos HTML5 del enlace dialogTitle = element.attr (' data-dilogo-ttulo '); UpdateTargetId = ' # '+ element.attr (' data-update-target-id '); updateURL = element.attr ('data-update-url ');

/ / Generar un identificador nico para el div de dilogo var dialogId = ' uniqueName- '+ Math.floor (Math.random () * 1000) dialogDiv var = "<div id = ' "+ dialogId + ""> </ div> " ; / / Cargar el formulario en el div de dilogo Carga $ (dialogDiv). ( Este . href, la funcin () { $ ( este ). dilogo ({ modal: verdad , tamao variable: false , Ttulo: dialogTitle, botones: { "Guardar" : la funcin () { / / Enviar manualmente el formulario var form = $ ('form ', this); . $ (Forma) submit (); }, "Cancelar": {dilogo $ (this) ('. Function () close ');} } }); / / Habilitar la validacin del lado del cliente . Validator.unobtrusive.parse $ (this); / / Configuracin de la lgica submit ajax wireUpForm (esto, UpdateTargetId, updateURL); }); return false; }); }); funcin wireUpForm (dilogo, UpdateTargetId, updateURL) { $ (' forma ', de dilogo). submit (function () { / / No presente si la forma / / No pasa la validacin del lado del cliente if ($ (this). vlido ()) return false; / Pasado la validacin del lado / Cliente, enviar el formulario / / Utilizando el formulario jQuery.ajax $. Ajax ({ url: this.action, Tipo: this.method, datos:. $ (this) serializar (), xito: function (resultado) { / / Comprobar si la entrada se ha publicado con xito if (result.success) { / / Cerrar el cuadro de dilogo

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

. $ (Dilogo) dilogo (' close '); / $ } ms / .

/ Actualizar los datos actualizados de la div objetivo (UpdateTargetId) load (updateURL).; { / Actualizar el cuadro de dilogo para mostrar errores del mo $ (Dilogo) html (resultado);

/ / Habilitar la validacin del lado del cliente . $ Validator.unobtrusive.parse (dilogo); / / Configuracin de la lgica submit ajax wireUpForm (dilogo, UpdateTargetId, updateURL); } } }); devolver false ; }); }

Conclusin
S que era mucho para tomar en pero despus de hacer la instalacin una vez, todo lo que tiene que hacer es hacer una llamada a Html.DialogFormLink y todo ser cuidado para usted. Espero que esto ayude!

También podría gustarte