ASP .Net MVC, problem with checkboxes! - asp.net-mvc

Basically I have a set of checkboxes that are dynamically created from view data like so:
<input type="checkbox" name="Calendars" value="<%= c.ID %>" /><%= c.Name %>
The value being the Calendar Id.
I can get what checkbox has been brought back using the FormsCollection its messy but it works!
(There also seems to be a bug with the checkbox helper that renders a hidden field next to the checkbox which means true is actually returned as "true,false"! I can work around this so its not an issue just thought Id mention it)
The problem comes when trying to hook the checkboxes up on an edit page!
I have a schedule class which can have multiple calendars and I want to show which calendars a schedule has by checking them on the edit!
My view is strongly typed but MVC magic can't map this!
Any ideas on whats the best way to do this??
I had tried passing the calendar ids in ViewData and do some inline code to check the appropriate checkbox but this is getting messy!
Thanks!!
UPDATE:
Done this
s.ID == c.ID).Select(s => s).Count() > 0) ? "checked=checked" : "" %>

You need to add "checked" tag manually to every check box:
<input type="checkbox" name="Calendars" value="<%= c.ID %>" checked="checked" /><%= c.Name %>

You dont need <input type="checkbox" - use Html.Checkbox(). It renders a hidden field next to the checkbox - but it is not a bug. From ASP.NET MVC source, InputExtensions.cs, line 201:
// 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.
Use this:
<%= Html.CheckBox("Calendars", c.ID) %>

Related

Rails Simple Form single checkbox twice in querystring

I have a search form which I return to after searching, to be able to refine the search. I just added a checkbox to that form.
In the view:
<%= f.input :available_tomorrow, as: :boolean, label: false,
inline_label: t('public.search.form.available_tomorrow.label'),
input_html: { name: :available_tomorrow, value: params[:available_tomorrow],
id: :available_tomorrow } %>
In the model:
attr_reader :available_tomorrow
HTLM produced:
<div class="form-group boolean optional search_available_tomorrow">
<input name="available_tomorrow" type="hidden" value="0">
<label class="checkbox">
<input class="boolean optional" id="available_tomorrow" name="available_tomorrow" type="checkbox" value="1">
Available tomorrow
</label>
</div>
When I check the box, all search parameters appear fine in the url querystring but that one:
&available_tomorrow=0&available_tomorrow=1
Looks like the value property of both field is sent, and neither changes. If I uncheck the box, I only get &available_tomorrow=0 in the querystring. The second part is only added if the checkbox is checked.
Everything works as intended (the search does return the right results depending on the checkbox state, the checkbox is in the right state when the search form is updated). But that querystring is ugly with both available_tomorrow parameters, looks like the first one should never appear. Ideas?
This is normal behavior for a form with a checkbox when you POST the form: If the checkbox is not checked, only the hidden field with value 0 is sent with the formdata. If the checkbox is checked, the input with the value 1 is also sent.
The hidden field for the checkbox is always sent, this is because otherwise no value for the checkbox would be sent.
Long story short: don't mind the querystring in your search url, nobody will ever look at them. :)

How to assign a dynamic value to the label helper in asp.net MVC

I am working on a Asp.net MVC 2.0 web application. In my form , i have non editable fields , so i wanted to display them as labels rather than textboxes.
I am strongly binding my model with view. So, i need to associate this label with one of the fields in model.
This is what i am trying to do:
<%=html.LabelFor(model=>model.changedby)%>
<%=html.DisplayFor(model=>model.changedby,XYZ)%>
But, it is displaying nothing..Please help
Updated2:
What basically i am trying to do is a add operation. i have a create view and that view has a form.
I am strongly binding this view with model.So , that i can directly associate form fields with the model Properties.
Ex:
<label> Name</label> <%=Html.TextBoxFor(m=>m.name)
So, what ever i type into the textbox , it will be stored in m.name in the model.
If the text entered is "Avinash" , then m.name gives value "Avinash"
I think i am correct upto this extent:
Similarly..
I have a field which is readonly , the user can not change the value of it.
<label>Changed On</label> <label> DateTime.Now </label>
How to bind m.ChangedOn with the labels values(DateTme.Now)
so that it will result in m.Changedon as DateTime.now
Updated3:
This is what i am writing..
<td >
<%=Html.LabelFor(Model=>Model.CreatedOn) %>:
</td>
<td>
<%=Html.HiddenFor(Model=>Model.CreatedOn) %>
</td>
You no need to wrap with <label>, since MVC LabelFor will automatically create those html tags for you
So change this
<label>
<%=html.LabelFor(model=>model.changedby)%>
</label>
to
<%= Html.LabelFor(model=>model.changedby) %>
Update:
If you want to send the data to the server while you post your form, make sure you have a data in a form fields. Only form fields like input,select,textarea are posted to server and not display tag value like label, span, div, etc
Still if you need to post the label value, you can use hidden with it
<%= Html.LabelFor(model=>model.changedby) %>
<%= Html.HiddenFor(model=>model.changedby) %>
If you have both, your hidden field will posted to server, which contains the same value
Controller code
public ActionResult Index()
{
MyviewModel model=new MyviewModel();
model.ChangedOn=DateTime.Now;
return View(model);
}
For Save
public ActionResult Save(MyviewModel model)
{
model.ChangedOn; // this property will show you hidden value
//If you need current time, since the rendered time was old. Its good to assign like below
//model.ChangedOn=DateTime.Now
}
use this
<%= Html.DisplayFor(model => model.changedby) %>

Get the value of <option> from views to the controller

Since 'HTML' do not have the attribute 'name',I am looking for a way to accept the value, which I populated in views, in the controller and assign it a variable name for another use.
This is sample of my code:`
enter code here<form action="<%=url_for(:action =>:make_comment) %>">
<fieldset>
<select>
<%#category.each {|x|%>
<option id="label"> <%=x%></option>
<%}%>
</select>
</fieldset>
<input type="submit" value="submit"/>
</form>`
Are you saying that your html doesn't have a name attribute? If so, why?
The name attribute is what the server will interpret as the "key" for the value that you are sending. I don't know what other way you could try to go about doing this.
Maybe if you paste some code from your controller and your view, I could give a better answer.
Edit: After seeing your edited question, what you want to do is have your select tag with the name attribute, and your option tags have a value attribute with the value you want to send.
Hope this helps.
This example show how you create a select tag:
select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {})
In this case, you would be able to get (in your controller) the value of the selected option through
params[:post][:person_id]
Is this what you want? Let me know if I misunderstood your question.

HTML.CheckBox(string) evaluates to two HTML elements instead of one

The code
<%=Html.CheckBox("SendEmail") %>
evaluates to two HTML elements when it's rendered
<input id="SendEmail" name="SendEmail" type="checkbox" value="true" />
<input name="SendEmail" type="hidden" value="false" />
Is this by a bug? Or by design? If it's by design, why?
I was having some trouble this morning with retrieving selected values from a checkbox group in my MVC app. I sent this out to my team and thought I'd share it with everyone else.
When posting back values for checkboxes, the standard behaviour of all browsers is to completely leave out un-checked checkboxes from the post back. So if you have a checkbox that isn’t checked then nothing shows up for this in Request.Form. This is a fairly well-known phenomenon that most developers account for.
In ASP.Net MVC when you use Html.Checkbox, it attempts to get around this and ensure that you have a value posted back (in this case ‘false’) for un-checked checkboxes. This is done by adding a hidden field containing the value ‘false’.
Eg.
<%= Html.CheckBox("Sites", s.Selected, new { value = s.Value })%>
Produces the HTML
<input id="Sites" name="Sites" type="checkbox" value="1" /><input name="Sites" type="hidden" value="false" />
This is all good and well, until you attempt to use checkbox groups. That is more than one checkbox with the same name where the values are sent back in a single comma separated string.
MVC can split this string up for you automatically if you define the value as an array (string[] Sites).
Here’s the view code:
<% foreach(var s in Model) { %>
<li><%= Html.CheckBox("Sites", s.Selected, new { value = s.Value })%>
<label><%= s.Name %></label>
</li>
<% } %>
The appropriate controller action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int Id, string Name, string SubmissionUrl, string[] Sites)
Unfortunately, because the Html.Checkbox produces this hidden field value as well, the resulting array contains not only values for the selected checkboxes but also ‘false’ for every un-checked checkbox. You get an array that looks something like this:
[0] 'false'
[1] 'false'
[2] '110'
[3] '50'
[4] 'false'
Where 'false' is for checkboxes that are not selected, and integers are the values for the checkboxes that are selected.
This can throw your code out quite a bit if you have only integers for the values of your checkboxes and want to define the result as an array of integers, like so:
public ActionResult Edit(int Id, string Name, string SubmissionUrl, int[] Sites)
Which results in an exception being thrown because it can’t convert the string value ‘false’ to an integer.
The solution is very simple, just avoid Html.Checkbox and manually create the checkboxes in your view code like this:
<% foreach(var s in Model) { %>
<li><input type="checkbox" name="Sites" value="<%=s.Value%>" <% if (s.Selected) { %>checked="checked"<% } %> />
<label><%= s.Name %></label>
</li>
<% } %>
Hope this helps someone else!
When all else fails, read the source code. :) this is from HtmlHelper.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'm not exactly sure how useful that is, but at least you know the intention.
I think I found something on the web that is directly related to my question.

Why is it removed: ASP.NET MVC CheckBoxList (without MVCContrib)

Why is the CheckBoxList removed from ASP.NET MVC preview release 5?
Currently I don't see any way in which I can create a list of checkboxes (with similar names but different id's) so people can select 0-1-more options from the list.
There is an CheckBoxList list present in the MVCContrib library, but it is deprecated. I can understand this for the other HtmlHelpers, but there does not seem to be a replacement for the CheckBoxList in preview 5.
I would like to create a very simple list like you see below, but what is the best way to do this using ASP.NET MVC preview release 5?
<INPUT TYPE="checkbox" NAME="Inhoud" VALUE="goed"> goed
<INPUT TYPE="checkbox" NAME="Inhoud" VALUE="redelijk"> redelijk
<INPUT TYPE="checkbox" NAME="Inhoud" VALUE="matig"> matig
<INPUT TYPE="checkbox" NAME="Inhoud" VALUE="slecht"> slecht
A for loop in the view to generate the checkboxes
<% foreach(Inhoud i in ViewData["InhoudList"] as List<Inhoud>) { %>
<input type="checkbox" name="Inhoud" value="<%= i.name %>" checked="checked" /> <%= i.name %>
<% } %>
Don't use Html.Checkbox, as that will generate two values for each item in the list (as it uses a hidden input for false values)
I recently blogged about implementing the CheckBoxList helper in the MVC Beta. Here is the link.
I have my own implementation of CheckListBox which has support for ModelState.
If you are interested it's in Un CheckBoxList que funciona en ASP.NET MVC. The post is in Spanish, but you shouldn't have any problems reading the code.
What is interesting in Jeremiah solution is the fact that you can set the initial state of the checkboxes, something you can't do with my CheckListBox.
I recommend using JeremiahClark extension posted above. (CheckBoxList)
My controller resulted into very simple instructions. For clarify I add a fragment of my code that's absent in the sample.
var rolesList = new List<CheckBoxListInfo>();
foreach (var role in Roles.GetAllRoles())
{
rolesList.Add(new CheckBoxListInfo(role, role, Roles.IsUserInRole(user.UserName, role)));
}
ViewData["roles"] = listaRoles;
And in the view:
<div><%= Html.CheckBoxList("roles", ViewData["roles"]) %></div>
That's all.

Resources