I have a radio button group and a validation to ensure atleast one of the options are selected. But my validation does not work on the view but they are caught in Model.Valid in the controller. How do I get it to show on the view like other validation errors without having to add a message in the controller on Model.IsValid fail?
View:
<div class="form-group">
<label for="" class="control-label">Role</label>
<div>
#foreach (var availableGroup in availableGroups)
{
<div class="radio">
<label>
<input type="radio" name="Group" value="#availableGroup" #defaulted/>
#availableGroup
</label>
</div>
}
#Html.ValidationMessageFor(m => m.Group)
</div>
</div>
Model :
[Required(ErrorMessage = "Group must be selected")]
[Display(Name = "Group")]
public string Group { get; set; }
Do I have to use Jquery on button click and then verify manually? I have seen ModelState.AddModelError() which will still require me to submit the action method. Is there something I can change in the way I am binding the radio buttons?
EDIT 1 : The Html equivalent for one of the options as seen in developer tool is
<label>
<input type="radio" name="Group" value="Group 1">
Group 1
</label>
EDIT 2: I already have data annotations working and it works fine with the other required textboxes. It is only in the radio button list that I have the issue.
So this is how I solved the issue. I checked how the HTML code will be for a Html.CheckboxFor and tried to mimic it to obtain the result.
<div class="radio">
<label>
<input type="radio" name="Group" data-val="true" data-val-required="Group must be selected" value="#availableGroup" #defaulted/>
#availableGroup
</label>
</div>
I had to add the data-val and data-val-required Attribute to get it to work.
I Hope i got the solution to your problem,
Solution:
Add the following validation related jquery files to the view
<script type="text/javascript" src="#Url.Content("~/scripts/anyversion")"></script>
<script type="text/javascript" src="#Url.Content("~/scripts/jquery.validate.js")"></script>
<script type="text/javascript" src="#Url.Content("~/scripts/jquery.validate.unobtrusive.js")"></script>
or add like below , if you are using bundles
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryval")
Answer to question:
Do I have to use Jquery on button click and then verify manually?
No , By default Data annotation handles both the client and server validations.
Hope it will be helpful for you,kindly let me know your thoughts
Thanks
Karthik
Related
I've got a form similar to the below, the name attributes have been set with MVC model binding in mind.
At the moment I'm only able to select one radio between the two forms. I want to select a radio button for each form, i.e. one radio button selected per form at any given time. I can't find a way to do this whilst keeping my name attribute naming convention.
Any ideas, thanks.
<div class="form-group-1">
<input type="radio" name="Students[0].Answer1" value=""><br>
<input type="radio" name="Students[0].Answer2" value=""><br>
</div>
<div class="form-group-2">
<input type="radio" name="Students[1].Answer1" value=""><br>
<input type="radio" name="Students[1].Answer2" value=""><br>
</div>
I am passing the input data from the .cshtml page to the action method.
Here is my .cshtml page:
#model passingdata
<form asp-controller="Home" method="post" asp-action="About" >
<button class="btn-danger" type="submit" value="Submit"></button>
<div class="form-group">
<label>
<input asp-for="date" placeholder="Date" class="col-md-8" />
</label>
<label>
Select from these Four Classes
<input type="radio" name="class" asp-for="classselect1" id="classselect1" value="classselect1" class="col-md-4" /> <p> #Model.classname1</p>
<input type="radio" name="class" asp-for="classselect2" id="classselect2" value="classselect2" class="col-md-4" /> <p> #Model.classname2</p>
<input type="radio" name="class" asp-for="classselect3" id="classselect3" value="classselect3" class="col-md-4" /> <p> #Model.classname3</p>
<input type="radio" name="class" asp-for="classselect4" id="classselect4" value="classselect4" class="col-md-4" /> <p> #Model.classname4</p>
</label>
</div>
</form>
And here is my controller code which is invoked when i Click on the button.
[HttpPost]
public IActionResult About(passingdata p)
{
ViewData["Message"] = "Your application description page.";
Teacher.classselect1 = p.classselect1;
Teacher.classselect2 = p.classselect2;
Teacher.classselect3 = p.classselect3;
Teacher.classselect4 = p.classselect4;
Teacher.date = p.date;
return View();
}
The input data like date and bool value from the radiobutton is not passing through the object of the class which contain these variables.
Please help me in this.
If i remember correctly, the Name attribute of each radiobutton is how .net MVC will map the values to your model.
In this case, all of your names are "class", which essentially means you have 1 form field named class with 4 options.
I would recommend using the html helper classes, because they will automatically create the proper html for you. The answer to this post should help: When using .net MVC RadioButtonFor(), how do you group so only one selection can be made?
If you dont want to use the helper just remember that when you submit a form, the data that is posted is based on the name of each form field. .Net does some magic in the background to serialize your Model for you, but essentially you are just submitting data in the format "?prop1=val1&prop2=val2".
Update
I figure maybe I should clarify a little better why what you are doing is not working how you expect.
When you post or put data via a form, it passes the input fields (text box, radio button, checkbox, etc...) as either querystring params or are part of the body. Radio buttons work a little differently than other input type. For a radio button, there are multiple input elements, but only one of them is valid. That is handled by using the name attribute. In your case, all of the names are "class", which means that the only thing being passed to the server is a single "?class={val}" (val is the value of which ever radio button is selected).
If your passingdata model had a property called "class", it would be populated. If your goal is to populated all 4 of the classselect properties with different values, you would need the name of each radio button to be different. But if there was only one radio button with each name, then each property could only have 1 value. You would need multiple RadioButtons with the same name to have multiple values (only one of which is selectable for each property).
Hopefully that clarifies what is wrong and gets you in the right direction.
I am using MVC6 and have a checkbox input field in my form, but when the form is submitted the value for the checkbox always gets passed to the ViewModel as false:
Here is how the property is declared in my ViewModel:
[Display(Name = "Include Sales Tax")]
public bool IncludeSalesTax { get; set; }
Here is how the form looks in my MVC6 razor form:
<div class="form-group">
<div class="checkbox">
<label><input asp-for="IncludeSalesTax" type="checkbox" value="">#Html.DisplayNameFor(m => m.IncludeSalesTax)</label>
</div>
</div>
I figured the above would be the best way to follow Twitter Bootstrap standards and use the ASP.NET MVC6 asp-for tag for model binding.
When I submit the form the value for IncludeSalesTax is always false, even when checked. What am I doing wrong?
input type checkbox sends an "on" if it is set. Otherwise it is not sent.
It is important, that you set the value attribute to true. In this case it sends true or nothing, which is perfect to bind to a boolean.
<input type="checkbox" name="yourPropertyName" value="true" checked />
Pinki's answer above is good if the checkbox should default to checked.
If the checkbox should default to unchecked, a little in-line javascript sets the value to true or false upon clicking:
<input name="yourPropertyName" type="checkbox" value="false" onchange="this.value=this.checked">
After letting Visual Studio generate the form based on my ViewModel here is how it does it:
<div class="checkbox">
<input asp-for="isTaxable" />
<label asp-for="isTaxable"></label>
</div>
Additionally, I was missing the closing of my input tag. So it can also be done like this which is the bootstrap preferred way:
<label><input asp-for="isTaxable" type="checkbox" value=""/>#Html.DisplayNameFor(m => m.isTaxable)</label>
The razor view engine normally creates a checkbox and one hidden input using the same name.
You can simply use the html below to ensure you get your desired result:
<div class="form-group">
<div class="checkbox">
<input type="checkbox" value="true" name="IncludeSalesTax" />Include Sales Tax
<input type="hidden" value="false" name="IncludeSalesTax" />
</div>
</div>
I have two methods in my asp.net mvc controller which search the google maps Places API to perform an autocomplete action as the user types in text.
In the background I understand that the data-otf-autocomplete function uses JQUERY UI autocomplete in the background to call these methods on the form. I have to be honest and admit I don't fully understand the JQUERY UI piece as I have adapted it from another the OdetoCode sample from the AJAX lesson on Scott Allen's excellent Pluralsight course Building Applications with ASP.NET MVC4 (Great course btw). The original code from Scott's course linked to a local database to return JSON to complete an autocomplete function which I've adapted to connect to the Google MAPS Places API.
Right now I have two search boxes each linked to a different methods on the controller. One uses the locality search (best suited to approximate addresses, most rural addresses here in Ireland fall into that category) while another is suitable for exact street addresses.
Is it possible to wire these two up to a radio button control in my view so you have a single search box and depending on the radio button option selected (say locality/address) it automatically routes the request to the associated method controller
#model IPagedList<RestaurantListViewModel>
#{
ViewBag.Title = "Home Page";
}
<form method="get" action="#Url.Action("Index")"
data-otf-ajax="true" data-otf-target="#List">
<input type="search" name="searchTerm" data-otf-autocomplete="#Url.Action("Autocomplete_Address")" />
</form>
<form method="get" action="#Url.Action("Index")"
data-otf-ajax="true" data-otf-target="#List">
<input type="search" name="searchTerm" data-otf-autocomplete="#Url.Action("Autocomplete_Locality")" />
</form>
#Html.Partial("_Restaurants", Model)
Cant you just have the search box and 2 radio buttons beside it one for each search option.
<input type="radio" name="SearchType" value="local" checked>Locality
<input type="radio" name="SearchType" value="exact">Exact Address
You just need one form then, posting to a method in the controller, in the method check for the value of the radio button and run your logic based on this.
UPDATE
Razor View:
#using (Html.BeginForm("ControllerMethod", "YourController", null, FormMethod.Post))
{
<input type="radio" name="SearchType" value="local" checked>Locality
<input type="radio" name="SearchType" value="exact">Exact Address
}
ControllerMethod
[HttpPost]
public ActionResult ControllerMethod(FormCollection form)
{
var SearchType = form["SearchType"];
........
}
Fully working code using Stephen Muecke's suggestion
#model IPagedList<RestaurantListViewModel>
#{
ViewBag.Title = "Home Page";
}
<script type = "text/javascript" >
function ShowHideDiv() {
var chkAddress = document.getElementById("chkAddress");
var inputAddbox = document.getElementById("inputAddress");
inputAddbox.style.display = chkAddress.checked ? "block" : "none";
var chkLocality = document.getElementById("chkLocality");
var inputLocality = document.getElementById("inputLocality");
inputLocality.style.display = chkLocality.checked ? "block" : "none";
}
</script>
<form method="get" action="#Url.Action("Index")"
data-otf-ajax="true" data-otf-target="#restaurantList">
<div>
<input type="search" id="inputAddress" name="searchTerm" data-otf-autocomplete="#Url.Action("Autocomplete_Address")" checked/>
<input type="search" id="inputLocality" name="searchTerm" data-otf-autocomplete="#Url.Action("Autocomplete_Locality")" />
</div>
<label for="chkAddress">
<input type="radio" id="chkAddress" name="chkType" onclick="ShowHideDiv()" />
Search by Address
</label>
<label for="chkLocality">
<input type="radio" id="chkLocality" name="chkType" onclick="ShowHideDiv()" />
Search by Location
</label>
</form>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script language="javascript">
$(document).ready(function () {
$("#inputLocality").hide();
$("#chkAddress").prop('checked', true);
});
</script>
}
How does one set the label of a checkbox? I looked at some sites and they are using lambda expressions, but I can't understand them. I am new to asp.net MVC.
#{
bool chkVal = false;
}
<li>#Html.CheckBox("chksumma",chkVal,new {#value = "5"})</li>
<li>#Html.LabelFor(, "");
This is a really good way:
<div class="checkbox">
<label>#Html.CheckBoxFor(x => item.IsSelected) #Html.DisplayNameFor(x => item.IsSelected)</label>
</div>
It's what is recommended by bootstrap 3.
It works in a table.
You can click on the check box OR the label to select the box. (This is an important usability feature.)
The cursor is properly the "hand" instead of the arrow pointer.
EDIT
This is really easy to do in Bootstrap 4.
You just wrap your label and input inside form-check markup:
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="defaultCheck1">
<label class="form-check-label" for="defaultCheck1">Default checkbox</label>
</div>
If you are using a Model you could do:
<li>#Html.CheckBoxFor(f=> f.chksumma)</li>
<li>#Html.LabelFor(f=> f.chksumma)</li>
Then use the attributes TGH pointed out
otherwise if you don't have a model all you can do for labels is:
#Html.Label("LabelText")
which prints a standalone label
or and craft it if you want it to link with the item
<label for="chksumma">LAbelText</label>
If you really don't want to hand craft it you can write your own HTML helper as explained here
http://develoq.net/2011/how-to-create-custom-html-helpers-for-asp-net-mvc-3-and-razor-view-engine/
I'm assuming that you want the label to tick the checkbox when you click on it.
In this case, the for attribute of the HTML <label> field must point to the ID of the relevant input element.
If you're using a model, #Html.CheckBoxFor will generate a checkbox without an ID, so you will need to add an ID to the checkbox, then point your label to the same ID. The easiest way is to replicate the checkbox's name into its ID field using the #Html.NameFor helper method. Here's an example:
#Html.CheckBoxFor(x => x.Active, new {id=Html.NameFor(x => x.Active)})
<label for="#Html.NameFor(x => x.Active)">Active</label>
Generated HTML (without validation attributes):
<input id="[0].Active" name="[0].Active" type="checkbox" value="true" />
<input name="[0].Active" type="hidden" value="false" />
<label for="[0].Active">Active</label>
I worked on something similar and got around it by this snipped code
<div class="row">
<div class="col-xs-3">
<label>
#Html.CheckBoxFor(x => x.AdvanceSearch.IsExactPhrase)
#Html.LabelFor(x => x.AdvanceSearch.IsExactPhrase)
</label>
</div> ...
Hope it helps the others
You shouldn't need the <label> tag at all:
<div class="block mTop20">
#HtmlCheckboxFor(f => f.prop)
#Html.LabelFor(f=>f.prop,"This is the label text")
</div>