Friday, March 21, 2014

Complex Master-Detail Form using Knockout.js and ASP.NET MVC

Recently I was tasked with implementing the following scenario. In short, Customer has a list of contacts

I already have developed the customer Add/Update screen with around 20 or something customer related input fields. New task was to plug a table inside this screen to display existing contacts and also with the ability to add new ones.

Just to give you an idea on how the UI looks like. Refer the following image.

Customer Contacts UI
Seems simple enough. And when I click on "Add Customer" and that small pencil icon, following UIs pops up.

Tuesday, March 4, 2014

ASP.NET MVC - Adding "data-" attributes in Html.BeginForm()

When working with a data capture form in ASP.NET MVC Imagine this situation.

  • You need to use Knockout (or something else) for data binding (and other magic).
  • You need to use @using (Html.BeginForm()){} 
So the goal is to get this markup rendering in the browser using Html.BeginForm(method with the "data-" tags.

<form action="/invoices/upload" data-bind="submit: saveData" enctype="multipart/form-data" id="invoiceUploadForm" method="post">

For that the server side markup should be something like any of these.

  • Using a dictionary

@using (Html.BeginForm("Upload", "Invoices", FormMethod.Post, 
                        new Dictionary<string, object> { 
                            { "enctype", "multipart/form-data" }, 
                            { "data-bind", "submit: saveData"}, 
                            { "id", "invoiceUploadForm"} 
                        }))
{
   <!-- HTML -->
} 

  • Trick here is to use the underscore ( _ ) so that it will get rendered as a hyphen ( - ) in the browser

@using (Html.BeginForm("Upload", "Invoices", FormMethod.Post, 
                        new { 
                               enctype = "multipart/form-data", 
                               data_bind = "submit: saveData",
                               id = "invoiceUploadForm" 
                            }))
{
   <!-- HTML -->
}