Tuesday, November 8, 2011

ASP.Net MVC Submit Collection Of Models

If you are using ASP.Net MVC for your presentation layer there are situations where you want to submit collection of view models. As an example lets say you have view models like this,

Person

  • Id : int
  • Name : string
  • Addresses : Ilist

Address

  • Id : Int
  • Line1 : string
  • City : string
  • Type : string
The Person view model has a collection of addresses. 

Then you need to have an edit view for the person to edit all the details of the person view model. In the edit view there will be code like this to display current addresses to the user to edit/ add new or delete .

@model YourNameSpace.Models.Person
@using (Html.BeginForm("Edit", "Person", FormMethod.Post, new { enctype = "multipart/form-data", id = "personEditForm" }))
{
///.................
               @foreach (var address in Model.Addresses)
                   {
                        @Html.HiddenFor(m,address.Id);
                        @Html.EditorForl(m, address.Line1);
                           //............
                   }
//....................................
}
This will generate HTML for the address Id  and address Line1 like this,

…..


…..


……



Because there are several inputs with same name we can't submit all values in the form For that the names should be like "Addresses[0].Line1" as below.
…..


…..


……



Of course you can achieve this by creating an editor template for address. But you will be in trouble when you delete some address in the middle of the sequence. And also if you have more properties like address for the person view model it will abuse your template folder.
This is the solution which I created with help of jQuery. I have written a jQuery function to reset all the names of those collection properties . To get the collection name I have added a wrapper div for each address . Before reset the names the HTML is like this,
…..
…..
……

And then I added this jQuery to onClick event to reset names before submit,
$("#submitButton").click(fuction(){
 $('.collection').each(function (index, domEle) {
           var property=$(this).attr('propertyName');
             $(this).children('div').each(function (index, domEle) {
                 $('input,select',$(this)).each(function (){
                    var oldName;
                
                    var name= $(this).attr('name')+'';
                    var i=  name.indexOf(']');
                    if(i>0){
                         oldName= name.substr(i+2);
                     }else {
                         oldName=  $(this).attr('name');
                         
                     }
                     $(this).attr('name',property+'['+index+'].'+  oldName);
                     $(this).next('span').attr('name',property+'['+index+'].'+  oldName);// need to change the names of validations messages too.
                     $(this).next('span').attr('data-valmsg-for',property+'['+index+'].'+  oldName);
                });
             });
     });   
});



After reeting the names the HTML will be like this,
…..
…..
……

Sunday, October 23, 2011

ASP.Net MVC Client Validation For Dynamically Added Form

This is how I have implemented the client side validation with MVC3 client side validation with JQuery validation plugin. The requirement was to create a model dialog with a form which is loaded via an Ajax request to the server.

  1. Enable client validation in web.config
We need to enable client side validation in web.config application settings section like thism


 
 <appSettings>
          <add key="ClientValidationEnabled" value="true"/>
        <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
 </appSettings>
    


    2 The form
 In your form you need to have a FormContext otherwise it will not generate validation attributes.  If the FormContext is null we need to create a new FormContext  like this in your view.
 
@{using (Html.BeginForm("Create", "Person", FormMethod.Post)
  {
      if (this.ViewContext.FormContext == null)
      {
          this.ViewContext.FormContext = new FormContext();
      }
    // .....
  }


    3 Phrase validation attributes 
 Then after the ajax request we need to phrase validation attributes using JQuery like this,<br />
 
$.get("@Url.Action("Create", "Person")", null, function (data) {
         $('#yourDivId').html(data);
         $("form").removeData("validator");
         $("form").removeData("unobtrusiveValidation");
        $.validator.unobtrusive.parse("form");          
   });

Saturday, October 22, 2011

Creating Categorized/Grouped Autocomplete Menu with JQuery

JQuery has given you a nice extendable library to create auto complete. But what if you want to customize it to have something like Facebook search autocomplete menu.  Here I have gathered several features of JQuery to make this customization. Here is my JQuery with ASP.net MVC3 but you can use whatever the backend which you can return a array of Json objects like this,
Here is my Search action in SearchController








And here is my JQuery code,