Saltar al contenido

MVC 4 Editar formulario modal usando Bootstrap

Solución:

Debería utilizar vistas parciales. Utilizo el siguiente enfoque:

Utilice un modelo de vista para no pasar sus modelos de dominio a sus vistas:

public class EditPersonViewModel

    public int Id  get; set;    // this is only used to retrieve record from Db
    public string Name  get; set; 
    public string Age  get; set; 

En tus PersonController:

[HttpGet] // this action result returns the partial containing the modal
public ActionResult EditPerson(int id)
  
    var viewModel = new EditPersonViewModel();
    viewModel.Id = id;
    return PartialView("_EditPersonPartial", viewModel);


[HttpPost] // this action takes the viewModel from the modal
public ActionResult EditPerson(EditPersonViewModel viewModel)

    if (ModelState.IsValid)
    
        var toUpdate = personRepo.Find(viewModel.Id);
        toUpdate.Name = viewModel.Name;
        toUpdate.Age = viewModel.Age;
        personRepo.InsertOrUpdate(toUpdate);
        personRepo.Save();
        return View("Index");
    

A continuación, cree una vista parcial llamada _EditPersonPartial. Contiene el encabezado, el cuerpo y el pie de página modal. También contiene la forma Ajax. Está fuertemente tipado y toma nuestro modelo de vista.

@model Namespace.ViewModels.EditPersonViewModel

@using (Ajax.BeginForm("EditPerson", "Person", FormMethod.Post, new AjaxOptions InsertionMode = InsertionMode.Replace, HttpMethod = "POST", UpdateTargetId = "list-of-people" )) @Html.ValidationSummary() @Html.AntiForgeryToken()

Ahora, en algún lugar de su aplicación, diga otro _peoplePartial.cshtml parcial, etc.

@foreach(var person in Model.People)
// this is the modal definition

Prefiero evitar usar Ajax.BeginForm helper y hacer una llamada Ajax con JQuery. En mi experiencia, es más fácil mantener un código escrito así. Así que a continuación están los detalles:

Modelos

public class ManagePeopleModel

    public List People  get; set; 
    ... any other properties


public class PersonModel

    public int Id  get; set; 
    public string Name  get; set; 
    public int Age  get; set; 
    ... any other properties

Vista de padres

Esta vista contiene las siguientes cosas:

  • registros de personas para iterar
  • un div vacío que se completará con un modal cuando una persona necesite ser editada
  • algunos JavaScript manejan todas las llamadas ajax
@model ManagePeopleModel

Manage People

@using(var table = Html.Bootstrap().Begin(new Table())) foreach(var person in Model.People) @person.Id @Person.Name @person.Age @html.Bootstrap().Button().Text("Edit Person").Data(new @id = person.Id ).Class("btn-trigger-modal") @using (var m = Html.Bootstrap().Begin(new Modal().Id("modal-person"))) @section Scripts

Vista parcial

Esta vista contiene un modal que se completará con información sobre la persona.

@model PersonModel
@
    // get modal helper
    var modal = Html.Bootstrap().Misc().GetBuilderFor(new Modal());


@modal.Header("Edit Person")
@using (var f = Html.Bootstrap.Begin(new Form()))

    using (modal.BeginBody())
    
        @Html.HiddenFor(x => x.Id)
        @f.ControlGroup().TextBoxFor(x => x.Name)
        @f.ControlGroup().TextBoxFor(x => x.Age)
    
    using (modal.BeginFooter())
    
        // if needed, add here @Html.Bootstrap().ValidationSummary()
        @:@Html.Bootstrap().Button().Text("Save").Id("btn-person-submit")
        @Html.Bootstrap().Button().Text("Close").Data(new  dismiss = "modal" )
    

Acciones del controlador

public ActionResult GetPersonInfo(int id)

    var model = db.GetPerson(id); // get your person however you need
    return PartialView("[Partial View Name]", model)


public ActionResult UpdatePersonInfo(PersonModel model)

    if(ModelState.IsValid)
    
        db.UpdatePerson(model); // update person however you need
        return Json(new  success = true );
    
    // else
    return PartialView("[Partial View Name]", model);

En respuesta a la respuesta de Dimitrys pero usando Ajax.BeginForm lo siguiente funciona al menos con MVC> 5 (4 no probados).

  1. escriba un modelo como se muestra en las otras respuestas,

  2. En la “vista principal” probablemente utilizará una tabla para mostrar los datos. El modelo debe ser un numerable. Supongo que el modelo tiene un id-propiedad. Sin embargo, debajo de la plantilla, un marcador de posición para el javascript modal y correspondiente

    
    @foreach (var item in Model)
    
        
    [email protected]"> @Html.Partial("dataRowView", item)

observe el “editor-éxito-id” en las filas de la tabla de datos.

  1. los dataRowView es un parcial que contiene la presentación del artículo de un modelo.

    @model ModelView
    @
        var item = Model;
    
    
    // some data
  2. Escriba la vista parcial a la que se llama haciendo clic en el botón de la fila (a través de JS $('.editor-container').click(function () ... ).

    @model Model
    
    @using (Ajax.BeginForm("MyEditAction", "Controller", FormMethod.Post,
                        new AjaxOptions
                        
                            InsertionMode = InsertionMode.Replace,
                            HttpMethod = "POST",
                            UpdateTargetId = "editor-success-" + @Model.Id,
                            OnSuccess = "success",
                            OnFailure = "failure",
                        ))
    
        @Html.ValidationSummary()
        @Html.AntiForgeryToken()
        @Html.HiddenFor(model => model.Id)
        
        
    
    

Aquí es donde ocurre la magia: en AjaxOptions, UpdateTargetId reemplazará la fila de datos después de la edición, onfailure y onsuccess controlarán el modal.

Esto es, el modal solo se cerrará cuando la edición fue exitosa y no ha habido errores; de lo contrario, el modal se mostrará después de la publicación ajax para mostrar mensajes de error, por ejemplo, el resumen de validación.

Pero, ¿cómo hacer que ajaxform sepa si hay un error? Esta es la parte del controlador, simplemente cambie response.statuscode como se muestra a continuación en el paso 5:

  1. el método de acción del controlador correspondiente para el modal de edición parcial

    [HttpGet]
    public async Task EditPartData(Guid? id)
    
        // Find the data row and return the edit form
        Model input = await db.Models.FindAsync(id);
        return PartialView("EditModel", input);
    
    
    [HttpPost, ValidateAntiForgeryToken]
    public async Task MyEditAction([Bind(Include =
       "Id,Fields,...")] ModelView input)
    
        if (TryValidateModel(input))
          
            // save changes, return new data row  
            // status code is something in 200-range
            db.Entry(input).State = EntityState.Modified;
            await db.SaveChangesAsync();
            return PartialView("dataRowView", (ModelView)input);
        
    
        // set the "error status code" that will redisplay the modal
        Response.StatusCode = 400;
        // and return the edit form, that will be displayed as a 
        // modal again - including the modelstate errors!
        return PartialView("EditModel", (Model)input);
    
    

De esta forma, si se produce un error al editar los datos del modelo en una ventana modal, el error se mostrará en el modal con métodos de resumen de validación de MVC; pero si los cambios se confirmaron correctamente, se mostrará la tabla de datos modificados y la ventana modal desaparecerá.

Nota: obtiene ajaxoptions funcionando, debe indicarle a la configuración de sus paquetes que se unan jquery.unobtrusive-ajax.js (puede ser instalado por NuGet):

        bundles.Add(new ScriptBundle("~/bundles/jqueryajax").Include(
                    "~/Scripts/jquery.unobtrusive-ajax.js"));

Sección de Reseñas y Valoraciones

Si te sientes a gusto, eres capaz de dejar una reseña acerca de qué le añadirías a este post.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 5)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *