Create a <T> list from the view and POST with the form in the MVC

Background
I am working on a client website project and I used MVC to create the site. My EF works with SQLDB to store data.

My WebApp is equipped with a back office area for managing / adding / updating Item , etc.

A specific page allows the user to add a new Item to the database by entering data and clicking "Save" in the form.

Item has some properties that all add DB to a new line.

Item also contains List<Appointment> declared against it (I will serialize them and save them in the corresponding column).

The objects are as follows (I have reduced some properties for brevity):

 public class Item { public int Id { get; set; } public string Name { get; set; } public List<Appointment> Appointments { get; set; } // Plus some other properties } public class Appointment { public string Day { get; set; } public string From { get; set; } public string To { get; set; } } 

I set out the ViewModel to use, and I do all of these usual good practice things. It looks like this:

 public class AddItemViewModel { [Required(ErrorMessage = "Please enter an item name")] [Display(Name="Item Name")] public string Name { get; set; } [Display(Name="Appointments")] public List<Appointment> Appointments { get; set; } ... // Other properties in here ... } 

I use the Razor viewer.

Everything works fine for me using the @Html.EditorFor(x => x.Property) ; for all (but one - to tell you at one moment) about the properties of the root object ( Item ).

I can publish the ViewModel to the controller and save the new Item , and all this jazz - so everything is fine there.

Problem
I have a List<Appointment> declared in my ViewModel.

How can I let the user add a new Appointment to this List<Appointment> from within the page?

I want to assign them to the Item object that will be created when Publishing the ViewModel - I will do this in my controller / services, etc.

How can i achieve this?

Desired view
I need the user to be able to add an Appointment from within the page - right down to what they really like.

I would like the list on the page to list the β€œcreated” Appointment ( ul or something similar, etc.).

Under this list, I need some text fields that relate to the Day , From and To properties for the Appointment β€” using the Add button, which adds it to the list (and removes the text fields, ideally).

As a bonus, I would also like to have a "& times;" button next to each item - esque "delete" to remove it from the List<Appointment> and view.

Here is an example (drawn by MSPaint - ftw old school tools!) Of what I can imagine how it looks:

My desired design design

Things i tried
I was digging far away, but so far nothing has been saved.

  • I looked at a lot of solutions related to adding objects to JavaScript on the page - what works. The only problem is I can’t pick them up in the object that is sent to the controller.

  • I also pointed directly to using Ajax to create an Appointment object and paste it into the page, but that didn't seem to catch up either.

Your experience, knowledge and wisdom are greatly appreciated.

+5
source share
1 answer
  • To be able to add new input controls to the user interface dynamically by clicking the "Add" button, you can

[code below is above, but more similar to pseudocode]

a) use jQuery / js to clone a hidden div that you previously rendered in a view that contains all the relevant destination controls.

eg. it will be a pre-rendered div that will serve as a template

 <div style="display:none;" id="appointment-template"> <input type=text> </div> 

And then the jQuery clone function when you click Add will look like

 var addNewAppointmentRowFromTemplate = function(){ $("#appointments-list-container").append($("#appointment-template").clone()); } 

OR

b) Get a partial view from the server and add it to the form (again using jQuery $ .get / js xhr)

  $.get( "controller/templatDivActionMethodUrl", function( data ) { $("#appointments-list-container").append( data ); }); 
  1. To be able to send a model with a list in the element that is accepted in the ItemMethod parameter, you can

a) Dynamically create a json object using jquery / javascript, which has the same structure as the server-side model (repairability will be a problem when changing the model).

  var appointmentsJson = []; //foreach loop is a pseudo code, can be replaced with $.each() foreach (var appointment in $("#appointments-list-container").children()){ appointmentsJson.push(new {'day' : $(appointment).children("#day").val(),'from' : $(appointment).children("#from").val(),'to' : $(appointment).children("#to").val()}) ;} //and then post this json to actionMethod $.post("serverController/Actionmethod",{appointments: appointmentsJson}); 

OR

b) Use the ModelBinder function that comes with ASP.Net MVC. There is a good amount of documentation / tutorials on this subject, starting point: https://docs.asp.net/en/latest/mvc/models/model-binding.html

+1
source

All Articles