Using an EditorTemplate with RenderPartial - asp.net-mvc

Is there an accepted way to render an EditorTemplate using RenderPartial?
I put a lot of work into an EditorTemplate that would use JQuery UI autocomplete to let the user choose from a list of companies. (It uses an HTML helper to ensure the right JS libraries and CSS rules are included in the "right" places in the generated web page.)
While building another page for that same application, I found I wanted to use that template again, outside the model I built the EditorTemplate for.
This code accomplishes the task, but in a way I can only consider a hack.
#using(Html.BeginForm()) {
ViewData.TemplateInfo.HtmlFieldPrefix = "CompanyName";
Html.RenderPartial("~/Views/Shared/EditorTemplates/Company.cshtml", string.Empty);
<input type="submit" value='Filter' />
}
Because I'm not using EditorFor, there is no "name" parameter, so the rendered input field is just the HtmlFieldPrefix of "CompanyName". The autocomplete works, and I can submit the form and filter the data. But this solution feels sloppy and fragile. Anyone have a better idea?

I've moved re-usable "controls" like that to a helper in app_code, and make the editor template a small wrapper, to call the helper.
My editorTemplate for DateTime looks like this:
#model DateTime?
#using System.Globalization
#{
var name = MvcHtmlString.Create(ViewData.TemplateInfo.GetFullHtmlFieldName(""));
var id = MvcHtmlString.Create(ViewData.TemplateInfo.GetFullHtmlFieldId(""));
var value = Model.HasValue && Model.Value > DateTime.MinValue ? string.Format("{0:d}", Model) : "";
}
<span class="edit">
#Editor.DateTime(id, name, value)
</span>
And I have and Editor.cshtml in app_code that contains:
#helper DateTime(IHtmlString id, IHtmlString name, string value) {
<input type="text" class="editor-date" id="#id" name="#name" value="#value" />
if (HttpContext.Current.Items["editor-date"] == null) {
HttpContext.Current.Items["editor-date"] = new object();
<script type="text/javascript">
$(function () {
$(".editor-date").datepicker({ dateFormat: 'd/m/yy' });
});
</script>
}
}
So I can use my date-editor from EditorFor, or any other way, while including the script to start it only once, and have all code to change on one place.

Related

How to extend html.textboxfor to remove the name attribute?

I want to extend the helper to make it like this:
#html.TextBoxFor(x=>x.CustomerId).ReadOnly()
and output the input element without the name attribute, so that it will not be posted to the server.
This should do the trick:
public static class MyInputExtensions
{
public static MvcHtmlString NameLessTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
var textBox = htmlHelper.TextBoxFor(expression);
string pattern = #"name=""([^""]*)""";
string fixedHtml = Regex.Replace(textBox.ToHtmlString(), pattern, "");
return new MvcHtmlString(fixedHtml);
}
}
Usage:
#Html.NameLessTextBoxFor(x=> x.CustomerId)
You can't do it.
(at least without some ugly workarounds with processing string value returned from helper)
Html helpers were written to help you generate form fields for your model with intention that they will sent data to server. For strongly-typed helper (like Html.TextBoxFor(x => x.CustomerId)) the name is taken from passed expression and for not strongly-typed helpers (like Html.TextBoxFor("CustomerId", Model.CustomerId)) there is a check that throws exception when name is null or empty.
If you want to generate input without "name" attribute then simply do not use html helper methods.
For example, if you want to change you html helper usage to generate same output but without "name" attribute then:
instead of this:
#Html.TextBoxFor(x => x.BetAmount)
write this:
<input type="text" value="#Model.BetAmount" />
instead of this:
#Html.TextBoxFor(x => x.BetAmount, new { #class = "red", placeholder = "Type Stuff", data_maximum_value = Model.MaximumBetAmount })
write this:
<input type="text" value="#Model.BetAmount" class="red" placeholder="Type Stuff" data_maximum_value="#Model.MaximumBetAmount" />
instead of this (you use overload with "format" argument):
#Html.TextBoxFor(x => x.BetAmount, "{0:0}", new { #class = "blue" })
write this:
<input type="text" value="#Html.FormatValue(Model.BetAmount,"{0:0}")" class="red" />
because Html.TextBoxFor uses Html.FormatValue when you pass "format" argument.
This is not exactly the same what html helper do because html helpers first tries to get data from ModelState for validation purpose (it's a common gotcha). But for 99% of times this is probably good enough
I recommend checking actual source code of ASP.NET MVC if you want to know what helper methods are actually doing. It's not black magic.

ASP.NET MVC 2: Better way to handle multiple buttons in each HTML table row?

I have an HTML table where each row has buttons which toggle status bits in the database for each row. Assuming Javascript is not an option, what would be the "best practice" way of handling this?
I'm currently handling it by wrapping each row in a form like this:
<table>
<tr>
<td>
<form action="/FooArea/BarController/BazAction" id="frm0" name="frm0" method="post">
<span>Item 1</span>
<input type="submit" value="Toggle1" name="submitButton" />
<input type="submit" value="Toggle2" name="submitButton" />
<input type="hidden" name="itemID" value="1" />
</form>
</td>
</tr>
<tr>
<td>
<form action="/FooArea/BarController/BazAction" id="frm1" name="frm1" method="post">
<span>Item 2</span>
<input type="submit" value="Toggle1" name="submitButton" />
<input type="submit" value="Toggle2" name="submitButton" />
<input type="hidden" name="itemID" value="2" />
</form>
</td>
</tr>
</table>
And the post method looks something like this:
string buttonName = Request.Form["submitButton"];
if (!String.IsNullOrEmpty(buttonName ))
{
int itemID = Convert.ToInt32(Request.Form["itemID"]);
switch (buttonName )
{
case "Toggle1":
DoSomething(itemID);
break;
case "Toggle2":
DoSomethingElse(itemID);
break;
}
}
Any better suggestions? Is having 50 forms on a page cool? I dunno.. let me know what you are doing in this case.
The best way to handle POST scenarios without JavaScript is, as several others have stated, a tiny form with only the necessary values, and only one submit button. Basically, what you should do is to create a helper method that creates a form with the necessary POST values in hidden fields and a submit button. For example, you could have a method you use like this:
<%= Html.PostLink("FooArea/BarController/BazAction", "Toggle1", new List<KeyValuePair<string, string>>{ new KeyValuePair<string, string>("itemId", 1), new KeyValuePair("action", "option1") }); %>
It looks pretty verbose, but I've tried to make it as generic as possible. You can probably create the List<KeyValuePair<string, string>> in the controller when you render the view, so you only have to call something
<%= Html.PostLink("FooArea/BarController/BazAction", "Toggle1", Model.Values) %>
In the action method that handles the post, you bind to the posted FormCollection, and retrieve the values of itemId and action to determine what to do, instead of checking for Request.Form values.
An implementation of the helper method might look like this:
public static string PostLink(this HtmlHelper helper, string postAction, string submitText, IEnumerable<KeyValuePair<string, string>> postValues)
{
var form = new TagBuilder("form");
// Setup basic properties like method, action
form.Attributes.Add("method", "post");
form.Attributes.Add("action", postAction);
// Instantiate a stringbuilder for the inner html of the form
var innerHtml = new StringBuilder();
// Create and append hidden fields for the post values
foreach(var value in postValues)
{
var hidden = new TagBuilder("input");
hidden.Attributes.Add("type", "hidden");
hidden.Attributes.Add("name", value.Key);
hidden.Attributes.Add("value", value.Value);
innerHtml.Append(hidden.ToString(TagRenderMode.SelfClosing));
}
// Create the submit button
var submit = new TagBuilder("input");
submit.Attributes.Add("type", "submit");
submit.Attributes.Add("value", submitText);
// Append it to the stringbuilder
innerHtml.Append(submit.ToString(TagRenderMode.SelfClosing));
// Set the InnerHtml property of the form, and return it
form.InnerHtml = innerHtml.ToString();
return form.ToString(TagRenderMode.Normal);
}
This seems like a prime case for some JQuery and Ajax functionality. But if javascript isn't an option then i think wrapping each one in a form is probably the most simple solution.
When I need to do something like this I do it pretty much the same way as you do here. It is no problem to have multiple forms in one view. Its like having multiple links in one view (but they use POST instead of GET). I guess many .net developers think its wrong because of webforms only having one form tag. In your case I would even create more forms for each submit button as they seem to do different things. I consider having to check the name of the button in the controller to be a code smell. If they do something like activate/deactivate you should probably post that as a bool or something and have both forms post to the same action.
I think technically this is the best way to go. From a usability point of view you can question if this is the best way to do it. More than 20 items in a list can get quite confusing. But ofcourse, I don't really know what you are programming :)
I agree with Mattias about creating different actions for the activate and deactivate-button. This way you avoid having to use a switch-statement.

ASP.Net MVC ActionLink

I'm trying to create an ActionLink in one of my views that sends the selected value of a dropdown list to a new action. So far I have this, I just need to find a way to populate the ID on the end of my ActionLink.
<%= Html.DropDownList("StatusDropDown") %>
<%= Html.ActionLink("Apply","Index",new {Controller="Tasks", Action="Index", id="DROPDOWN LIST SECLECTED VALUE"}) %>
Obviously this link would need to be updated whenever the selected index of the drop down is changed. Is this something I need to do in javascript or is there a better way of managing this from within ASP.Net MVC?
Thanks
If you don't want to use form submission (i.e., want the parameter passed as part of the url instead of a form parameter), you'll need to build the url client-side with javascript.
<%= Html.DropDownList("StatusDropDown") %>
<a id="applyLink" href="#">Apply</a>
<script type="text/javascript">
function setHref( elem, val )
{
if (val) {
$(elem).attr( "href", "/Tasks/" + val );
$("#applyLink").unbind("click");
}
else {
$(elem).attr( "href", "#" );
$("#applyLink").click( function() { alert( "No value chosen" ); } );
}
}
$(function() {
var dropdown = $("#StatusDropDown");
dropdown.change( function() {
setHref( this, $(this).val() );
});
setHref( dropdown, null );
});
</script>
A link goes to another page, it is in effect a redirect. The only way to update where that link goes to with reference to the drop down list is with javascript.
It sounds like you want a kind of submit action. In that case you should use a form and a submit button, creating the appropriate handlers in your controller. Remember you can just do a redirect in your controller based upon the submitted value of the form. So something like this:
<form method="post" action="/MyForm">
<input type="select" name="mySelect">
<option value="1">First Option</option>
<option value="2">Second Option</option>
</input>
</form>
And in your controller:
public ActionResult MyForm(int mySelect)
{
return Redirect(String.Format("myurl?id={0}", mySelect));
// Note the above is only preferable if you're going to an external link
// Otherwise you should use the below:
return RedirectToAction("myAction", new { id = mySelect });
}
Obviously in this simplified example, the MyForm proxy to your desired action is redundant, but it illustrates the idea so you can apply it to your specific situation.

ASP.NET MVC - Getting Html.BeginForm() to remember Querystring params when submitting via GET

I have a form rendered via Html.BeginForm(), it exists as a component in the Master page so that it appears on every page in the application. I have done this using Html.RenderAction() from Mvc Futures assembly. It's a simple search form that updates some items in the same component underneigh the search form itself, and performs a GET so that the search term appears in the querystring.
<div class="sideBarContent">
<h2>Search Products</h2>
<% using (Html.BeginForm(ViewContext.RouteData.Values["action"].ToString(),
ViewContext.RouteData.Values["controller"].ToString(), FormMethod.Get)) { %>
<fieldset>
<legend>Search Products</legend>
<div class="formRow">
<label for="ProductsSearch">Search</label>
<%= Html.TextBox("ProductsSearch") %>
</div>
<input type="submit" value="Search" class="button" />
</fieldset>
<% } %>
<ul>
// Products will eventually be listed here
</ul>
</div>
I need this form to do the following:
1) It should perform a GET to whatever current page it is on appending 'ProductsSearch' as a querystring parameter (eg. example.com/?ProductsSearch=test or example.com/books/fiction?ProductsSearch=test)
2) It should remember any exising querystring parameters that are already in the querystring, maintaining them after you click Search button eg. example.com/myOrders?page=2 after Search click it should go to example.com/myOrders?page=2&ProductsSearch=test)
I can get it to do 1) but can't work out 2).
I relise that normally for a from to GET and appending querystring params it needs to have hidden form fields, so I could write a utility function that automatically adds a bunch of hidden form fields for any querystring values, but I wanted to check that there's wasn't an easier approach, or maybe I'm going about it the wrong way.
Cheers!
You'll need to do the hidden form field method.
Even if you could attach the entire querystring to the end of the URL in the action attribute of the <form> tag, browsers don't pay attention to this when doing GET form submissions.
Your method isn't too difficult; you'd want to do something like this:
public static string QueryStringAsHidden(this HtmlHelper helper)
{
var sb = new StringBuilder();
foreach (var key in HttpContext.Current.Request.QueryString.AllKeys)
{
if (! key.StartsWith("ProductSearch"))
sb.Append(helper.Hidden(key, HttpContext.Current.Request.QueryString[key]));
}
return sb.ToString();
}
I put the .StartsWith() in there because you don't want to be on a search page and submit the search string twice (and now you can prepend paging and other search-specific variables with ProductSearch.
Edit: PS: To get the form to post to the current page, you don't have to explicitly provide action and controller -- you can also send nulls.
Edit2: Why even bother with a helper method? :)
<% HttpContext.Current.Request.QueryString.AllKeys.Where(k => !k.StartsWith("ProductSearch")).ToList().ForEach(k => Response.Write(Html.Hidden(k, HttpContext.Current.Request.QueryString[k]))); %>
James
A direct to call BeginForm() does keep your query string values. Any other overload tends to fail. I love the ease of using BeginForm() from my forms, but needed a way to class all my styled forms a certain way an not lose the query string values in the action.
Here is what I came up with:
public static MvcForm BeginNormalForm<T>(this HtmlHelper<T> htmlHelper)
{
var dictionary = new Dictionary<string, object> {{"class", "normal"}};
var rvd = new RouteValueDictionary();
if (htmlHelper.ViewContext.HttpContext != null && htmlHelper.ViewContext.HttpContext.Request != null)
{
foreach (var key in htmlHelper.ViewContext.HttpContext.Request.QueryString.AllKeys)
{
rvd[key] = htmlHelper.ViewContext.HttpContext.Request.QueryString[key];
}
}
var form = htmlHelper.BeginForm(null, null, rvd, FormMethod.Post, dictionary);
return form;
}
Seems to work well and keeps my class attribute.
Use one of the overloads of BeginForm that takes a routeValues object or dictionary.
Additional properties not in the route will be added as query parameters.

How to handle checkboxes in ASP.NET MVC forms?

Caution: This question is over nine years old!
Your best option is to search for newer questions, or to search the answers below looking for your specific version of MVC, as many answers here are obsolete now.
If you do find an answer that works for your version, please make sure the answer contains the version of MVC you are using.
(The original question starts below)
This seems a bit bizarre to me, but as far as I can tell, this is how you do it.
I have a collection of objects, and I want users to select one or more of them. This says to me "form with checkboxes." My objects don't have any concept of "selected" (they're rudimentary POCO's formed by deserializing a wcf call). So, I do the following:
public class SampleObject{
public Guid Id {get;set;}
public string Name {get;set;}
}
In the view:
<%
using (Html.BeginForm())
{
%>
<%foreach (var o in ViewData.Model) {%>
<%=Html.CheckBox(o.Id)%> <%= o.Name %>
<%}%>
<input type="submit" value="Submit" />
<%}%>
And, in the controller, this is the only way I can see to figure out what objects the user checked:
public ActionResult ThisLooksWeird(FormCollection result)
{
var winnars = from x in result.AllKeys
where result[x] != "false"
select x;
// yadda
}
Its freaky in the first place, and secondly, for those items the user checked, the FormCollection lists its value as "true false" rather than just true.
Obviously, I'm missing something. I think this is built with the idea in mind that the objects in the collection that are acted upon within the html form are updated using UpdateModel() or through a ModelBinder.
But my objects aren't set up for this; does that mean that this is the only way? Is there another way to do it?
Html.CheckBox is doing something weird - if you view source on the resulting page, you'll see there's an <input type="hidden" /> being generated alongside each checkbox, which explains the "true false" values you're seeing for each form element.
Try this, which definitely works on ASP.NET MVC Beta because I've just tried it.
Put this in the view instead of using Html.CheckBox():
<% using (Html.BeginForm("ShowData", "Home")) { %>
<% foreach (var o in ViewData.Model) { %>
<input type="checkbox" name="selectedObjects" value="<%=o.Id%>">
<%= o.Name %>
<%}%>
<input type="submit" value="Submit" />
<%}%>
Your checkboxes are all called selectedObjects, and the value of each checkbox is the GUID of the corresponding object.
Then post to the following controller action (or something similar that does something useful instead of Response.Write())
public ActionResult ShowData(Guid[] selectedObjects) {
foreach (Guid guid in selectedObjects) {
Response.Write(guid.ToString());
}
Response.End();
return (new EmptyResult());
}
This example will just write the GUIDs of the boxes you checked; ASP.NET MVC maps the GUID values of the selected checkboxes into the Guid[] selectedObjects parameter for you, and even parses the strings from the Request.Form collection into instantied GUID objects, which I think is rather nice.
HtmlHelper adds an hidden input to notify the controller about Unchecked status.
So to have the correct checked status:
bool bChecked = form[key].Contains("true");
In case you're wondering WHY they put a hidden field in with the same name as the checkbox the reason is as follows :
Comment from the sourcecode MVCBetaSource\MVC\src\MvcFutures\Mvc\ButtonsAndLinkExtensions.cs
Render an additional <input
type="hidden".../> for checkboxes.
This addresses scenarios where
unchecked checkboxes are not sent in
the request. Sending a hidden input
makes it possible to know that the
checkbox was present on the page when
the request was submitted.
I guess behind the scenes they need to know this for binding to parameters on the controller action methods. You could then have a tri-state boolean I suppose (bound to a nullable bool parameter). I've not tried it but I'm hoping thats what they did.
You should also use <label for="checkbox1">Checkbox 1</label> because then people can click on the label text as well as the checkbox itself. Its also easier to style and at least in IE it will be highlighted when you tab through the page's controls.
<%= Html.CheckBox("cbNewColors", true) %><label for="cbNewColors">New colors</label>
This is not just a 'oh I could do it' thing. Its a significant user experience enhancement. Even if not all users know they can click on the label many will.
I'm surprised none of these answers used the built in MVC features for this.
I wrote a blog post about this here, which even actually links the labels to the checkbox. I used the EditorTemplate folder to accomplish this in a clean and modular way.
You will simply end up with a new file in the EditorTemplate folder that looks like this:
#model SampleObject
#Html.CheckBoxFor(m => m.IsChecked)
#Html.HiddenFor(m => m.Id)
#Html.LabelFor(m => m.IsChecked, Model.Id)
in your actual view, there will be no need to loop this, simply 1 line of code:
#Html.EditorFor(x => ViewData.Model)
Visit my blog post for more details.
Here's what I've been doing.
View:
<input type="checkbox" name="applyChanges" />
Controller:
var checkBox = Request.Form["applyChanges"];
if (checkBox == "on")
{
...
}
I found the Html.* helper methods not so useful in some cases, and that I was better off doing it in plain old HTML. This being one of them, the other one that comes to mind is radio buttons.
Edit: this is on Preview 5, obviously YMMV between versions.
They appear to be opting to read the first value only, so this is "true" when the checkbox is checked, and "false" when only the hidden value is included. This is easily fetched with code like this:
model.Property = collection["ElementId"].ToLower().StartsWith("true");
#Dylan Beattie Great Find!!! I Thank you much. To expand even further, this technique also works perfect with the View Model approach. MVC is so cool, it's smart enough to bind an array of Guids to a property by the same name of the Model object bound to the View. Example:
ViewModel:
public class SampleViewModel
{
public IList<SampleObject> SampleObjectList { get; set; }
public Guid[] SelectedObjectIds { get; set; }
public class SampleObject
{
public Guid Id { get; set; }
public string Name { get; set; }
}
}
View:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Sample View</h2>
<table>
<thead>
<tr>
<th>Checked</th>
<th>Object Name</th>
</tr>
</thead>
<% using (Html.BeginForm()) %>
<%{%>
<tbody>
<% foreach (var item in Model.SampleObjectList)
{ %>
<tr>
<td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
<td><%= Html.Encode(item.Name)%></td>
</tr>
<% } %>
</tbody>
</table>
<input type="submit" value="Submit" />
<%}%>
Controller:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult SampleView(Guid id)
{
//Object to pass any input objects to the View Model Builder
BuilderIO viewModelBuilderInput = new BuilderIO();
//The View Model Builder is a conglomerate of repositories and methods used to Construct a View Model out of Business Objects
SampleViewModel viewModel = sampleViewModelBuilder.Build(viewModelBuilderInput);
return View("SampleView", viewModel);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SampleView(SampleViewModel viewModel)
{
// The array of Guids successfully bound to the SelectedObjectIds property of the View Model!
return View();
}
Anyone familiar with the View Model philosophy will rejoice, this works like a Champ!
I'd also like to point out that you can name each checkbox a different name, and have that name part of the actionresults parameters.
Example,
View:
<%= Html.CheckBox("Rs232CheckBox", false, new { #id = "rs232" })%>RS-232
<%= Html.CheckBox("Rs422CheckBox", false, new { #id = "rs422" })%>RS-422
Controller:
public ActionResults MyAction(bool Rs232CheckBox, bool Rs422CheckBox) {
...
}
The values from the view are passed to the action since the names are the same.
I know this solution isn't ideal for your project, but I thought I'd throw the idea out there.
<input type = "checkbox" name = "checkbox1" /> <label> Check to say hi.</label>
From the Controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection fc)
{
var s = fc["checkbox1"];
if (s == "on")
{
string x = "Hi";
}
}
This issue is happening in the release 1.0 as well. Html.Checkbox() causes another hidden field to be added with the same name/id as of your original checkbox. And as I was trying loading up a checkbox array using document.GetElemtentsByName(), you can guess how things were getting messed up. It's a bizarre.
From what I can gather, the model doesn't want to guess whether checked = true or false, I got around this by setting a value attribute on the checkbox element with jQuery before submitting the form like this:
$('input[type="checkbox"]').each(function () {
$(this).attr('value', $(this).is(':checked'));
});
This way, you don't need a hidden element just to store the value of the checkbox.
I know that this question was written when MVC3 wasn't out, but for anyone who comes to this question and are using MVC3, you may want the "correct" way to do this.
While I think that doing the whole
Contains("true");
thing is great and clean, and works on all MVC versions, the problem is that it doesn't take culture into account (as if it really matters in the case of a bool).
The "correct" way to figure out the value of a bool, at least in MVC3, is to use the ValueProvider.
var value = (bool)ValueProvider.GetValue("key").ConvertTo(typeof(bool));
I do this in one of my client's sites when I edit permissions:
var allPermissionsBase = Request.Params.AllKeys.Where(x => x.Contains("permission_")).ToList();
var allPermissions = new List<KeyValuePair<int, bool>>();
foreach (var key in allPermissionsBase)
{
// Try to parse the key as int
int keyAsInt;
int.TryParse(key.Replace("permission_", ""), out keyAsInt);
// Try to get the value as bool
var value = (bool)ValueProvider.GetValue(key).ConvertTo(typeof(bool));
}
Now, the beauty of this is you can use this with just about any simple type, and it will even be correct based on the Culture (think money, decimals, etc).
The ValueProvider is what is used when you form your Actions like this:
public ActionResult UpdatePermissions(bool permission_1, bool permission_2)
but when you are trying to dynamically build these lists and check the values, you will never know the Id at compile time, so you have to process them on the fly.
The easiest way to do is so...
You set the name and value.
<input type="checkbox" name="selectedProducts" value="#item.ProductId" />#item.Name
Then on submitting grab the values of checkboxes and save in an int array.
then the appropriate LinQ Function. That's it..
[HttpPost]
public ActionResult Checkbox(int[] selectedObjects)
{
var selected = from x in selectedObjects
from y in db
where y.ObjectId == x
select y;
return View(selected);
}
Same as nautic20's answer, just simply use MVC default model binding checkbox list with same name as a collection property of string/int/enum in ViewModel. That is it.
But one issue need to point out. In each checkbox component, you should not put "Id" in it which will affect MVC model binding.
Following code will work for model binding:
<% foreach (var item in Model.SampleObjectList)
{ %>
<tr>
<td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
<td><%= Html.Encode(item.Name)%></td>
</tr>
<% } %>
Following codes will not binding to model (difference here is it assigned id for each checkbox)
<% foreach (var item in Model.SampleObjectList)
{ %>
<tr>
<td><input type="checkbox" name="SelectedObjectIds" id="[some unique key]" value="<%= item.Id%>" /></td>
<td><%= Html.Encode(item.Name)%></td>
</tr>
<% } %>
this is what i did to loose the double values when using the Html.CheckBox(...
Replace("true,false","true").Split(',')
with 4 boxes checked, unchecked, unchecked, checked it turns
true,false,false,false,true,false
into
true,false,false,true.
just what i needed
How about something like this?
bool isChecked = false;
if (Boolean.TryParse(Request.Form.GetValues(”chkHuman”)[0], out isChecked) == false)
ModelState.AddModelError(”chkHuman”, “Nice try.”);
When using the checkbox HtmlHelper, I much prefer to work with the posted checkbox form data as an array. I don't really know why, I know the other methods work, but I think I just prefer to treat comma separated strings as an array as much as possible.
So doing a 'checked' or true test would be:
//looking for [true],[false]
bool isChecked = form.GetValues(key).Contains("true");
Doing a false check would be:
//looking for [false],[false] or [false]
bool isNotChecked = !form.GetValues(key).Contains("true");
The main difference is to use GetValues as this returns as an array.
Just do this on $(document).ready :
$('input:hidden').each(function(el) {
var that = $(this)[0];
if(that.id.length < 1 ) {
console.log(that.id);
that.parentElement.removeChild(that);
}
});
My solution is:
<input type="checkbox" id="IsNew-checkbox" checked="checked" />
<input type="hidden" id="IsNew" name="IsNew" value="true" />
<script language="javascript" type="text/javascript" >
$('#IsNew-checkbox').click(function () {
if ($('#IsNew-checkbox').is(':checked')) {
$('#IsNew').val('true');
} else {
$('#IsNew').val('false');
}
});
</script>
More you can find here:
http://www.blog.mieten.pl/2010/12/asp-net-mvc-custom-checkbox-as-solution-of-string-was-not-recognized-as-a-valid-boolean/
I had nearly the same Problem but the return Value of my Controller was blocked with other Values.
Found a simple Solution but it seems a bit rough.
Try to type Viewbag. in your Controller and now you give it a name like Viewbag.Checkbool
Now switch to the View and try this #Viewbag.Checkbool with this you will get the value out of the Controller.
My Controller Parameters look like this:
public ActionResult Anzeigen(int productid = 90, bool islive = true)
and my Checkbox will update like this:
<input id="isLive" type="checkbox" checked="#ViewBag.Value" ONCLICK="window.location.href = '/MixCategory/Anzeigen?isLive=' + isLive.checked.toString()" />
Using #mmacaulay , I came up with this for bool:
// MVC Work around for checkboxes.
bool active = (Request.Form["active"] == "on");
If checked
active = true
If unchecked
active = false

Resources