Imagine the scenario in which you have a bunch of items that need displaying in a view. Each item has an action button of some kind. We need to grab the id associated with that item so we can pass it back to the server. One approach to this problem is to handle the form submission with jQuery. In this article, I'll explain how we can solve this with jQuery data attributes. To begin with, let's set up our form. We'll use a simple view model with a collection of items to hold our data.
public class ItemViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
public class CompleteFormViewModel
{
public IEnumerable<ItemViewModel> Items { get; set; }
public int SelectedItemId { get; set; }
}
The form itself contains a hidden field for our selected item id. It uses a simple loop to generate the buttons. This is a great candidate for display templates, which I've covered in another post:
Keep your views clean with Display Templates
@using (Html.BeginForm("CompleteForm",
"ManageApplication", FormMethod.Post, new { name = "completeForm" }))
{
@Html.HiddenFor(m => m.SelectedItemId)
if (Model.Items != null)
{
<div id="ItemContainer">
@foreach (var item in Model.Items)
{
<div class="row">
<div class="col-sm-12">
<h4>@item.Name</h4>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<input type="button"
class="btn btn-primary btn-full-width" data-itemid="@item.Id" />
</div>
</div>
}
</div>
}
}
A couple of things to note here. We’ve got a single hidden field for our selected item id. We'll be passing that id to our controller action on form post. We’ve also wrapped our items in a div
with an id of ItemContainer
. This allows us to anchor our jQuery selector against an element with an id. It will be a bit quicker because it doesn't have to search the entire DOM to find the buttons.
All Hail the Mighty Data Attribute
Now that we have our form set up, we need some jQuery. We need to capture which button we're selecting and update our id field to that value.
(function($) {
$('#ItemContainer input[type=button]').on('click', function(){
var itemId = $(this).data('itemid');
$('#SelectedItemId').val(itemId);
$('form[name=completeForm]').submit();
});
})(jQuery);
We've wrapped our function in a closure so that we have a local copy of the global $ alias. This helps us avoid collisions with any other scripts that might be using it. Richard Bovell has written a great article on understanding closures:
Understand JavaScript Closures With Ease
We can now capture the selected id within our Controller Action method for processing. We’ll pass in a CompleteFormViewModel
on form post. The default model binder will then work its magic to bind our SelectedItemId
property. We could pass in any type we like here as long as it has an int property called SelectedItemId
. The default model binder will populate that value for us.
public class ManageApplicationController : Controller
{
public ActionResult CompleteForm(CompleteFormViewModel model)
{
}
}
View the original article