Naser Dostdar Naser Dostdar - 3 months ago 17
jQuery Question

How to validate hiddenfor fields in asp.net mvc razor views?

I have a jQuery

selectable
widget in my razor view which displayed as an
<ol>
and updated from a comma separated string in SQL Server table just like below:

<ol class="ui-selectable" style="width:auto" id="selectable1">

@{
var color = Model.AvailableColors.Split(',');
foreach (var clr in color)
{
<li class="btn red-mint" style="margin: 10px 0">@clr</li>
}
}
</ol>


The above as mentioned displays set of colors like (Red, Green, Purple and etc) list which is of-course
selectable
and the user can only pick one from the list at a time.

I passed the selected list item value in a hidden field which is then passed to controller action method with below script.

<script type="text/javascript">
$(document).ready(function () {
$("#selectable1").selectable({
selected: function (event, ci) {
$(ci.selected).siblings().removeClass("ui-selected");
$("#selectedcolor").val($("#selectable1>li.ui-selected").html());
}
});

});
</script>


In my form I've a
HiddenFor
razor attribute to pass selected list item value to the controller as below:

@Html.HiddenFor(m => m.AvailableColors, new { @id = "selectedcolor" })


Now here is something that I am stuck and couldn't find a solution searching over internet. I want that if no item selected the validation should occur and the validation message for the
AvailableColors
should appear but I have no idea how to do it. Any help please?

EDIT: Here is the controller action method that I am passing data to:
// GET: /Store/AddToCart/5

public ActionResult AddToCart(int id,int SelectedQuantity, string SelectedSizes, string AvailableColors)
{
// Retrieve the album from the database
var addedProduct = dbContext.Products
.Single(product => product.ProductID == id);

// Add it to the shopping cart
var cart = ShoppingCart.GetCart(this.HttpContext);

cart.AddToCart(addedProduct, SelectedQuantity, AvailableColors,SelectedSizes);

// Go back to the main store page for more shopping
return RedirectToAction("Index");
}

Answer

You might consider adding a new property to store the selected item text(string) in your view model and decorate it with [Required] data annotation.

public class AddToCartViewModel
{
  public int ProductId { set;get;}

  [Required]
  public int SelectedQuantity { set;get;}

  [Required]
  pubilc string SelectedColor { set;get;}

  // Add other properties as needed.
}

and have this hidden form in your form

@using (Html.BeginForm("AddToCart","ShoppingCart"))
{
    @Html.HiddenFor(f => f.SelectedColor)
    @Html.ValidationMessageFor(f=>f.SelectedColor)
    <input type="submit" class="btn btn-default" value="Submit" />
}

When you submit the form ModelState.IsValid will be false and if you return the model back to view, you will see the error message for SelectedColor

[HttpPost]
public ActionResult AddToCart(AddToCartViewModel model)
{
  if(ModelState.IsValid)
  {
    //continue saving and return something
  }
  return View(model);
}

If you have client side unobtrusive validation, It won't work with hidden field by default. One workaround you can do is to keep the field as an input, but set the visibility to hidden. Then the client side validation will also show the validation error message.

@using (Html.BeginForm("AddToCart","ShoppingCart"))
{
     @Html.TextBoxFor(f => f.SelectedColors, new {style="visibility:hidden;"})
     @Html.ValidationMessageFor(f=>f.SelectedColor)
     <input type="submit" class="btn btn-default" value="Submit" />
}
Comments