I have several checkboxes on a form. Only one of them is checked when it needs to be; all the others are unchecked regardless of whether the isChecked parameter is passed in as either true or false.
The checkboxes are coded like this:
<%= Html.CheckBox("cbName",Model.checkvalue)%>
<%= Html.CheckBox("cbName1",Model.checkvalue1)%>
I have stepped through the code and Model.checkValue and Model.checkValue1 are both true, but cbName is not checked and cbName1 is checked (in fact, in my actual app' there are several more CheckBoxes and none are checked -except the second one in the form- although the Model properties are all true in the test I ran).
Has anyone come across this (mis)behavior before & can you let me know where I am going wrong, please? I can't find a similar question anywhere, so I am hoping I am just making a simple error that will be quick to fix...
what about use different way of rendering the code ( of course you can later simplify this code or create your own helper):
<%
if(Model.checkvalue1){
%>
<%= Html.CheckBox("name", new {checked =checked }) %>
<%}else{%>
<%= Html.CheckBox("name", null) %>
<%}%>
idea 2
make sure that the value you are passing in is boolean: therefore cast is as boolean
<%= Html.CheckBox("cbName1",(bool)Model.checkvalue1)%>
idea 3
before using the code
<% bool myTempValue = Model.checkvalue1; %>
<%= Html.CheckBox("cbName1",myTempValue)%>
There could be some reasons for this behavior:
Is there any query string parameter named cbName in URL of the page? Or, is it a POST request of the form? Query string and form (POST) data take precedence over explicit values set in code.
What browser are you using? FireFox sometimes preserves form data over page reloads. If you check a checkbox and refresh the page, FireFox checks the checkbox again, even when there is no "checked" attribute in HTML input element.
It was because the underlying data uses a nullable boolean.
I switched the CheckBox to a CheckBoxFor and got the error outlined in this question and this told me that the problem is the fact that the underlying data currently uses a nullable boolean. Since this data type will be switched for a not null boolean once ready I don't need to work around this.
I hope this answer helps someone else.
Thank you for everyone's contributions.
Related
I'm new to Rails.
I have a situation where we have a fairly important form that we can't default answers for users as it revolves around government tax authorisation related things so our boolean answers essentially have three states:
nil -> user hasn't provided an answer
true -> User has said true
false -> User has said false
The issue I'm having in our Rails backend with this is by default the form.check_box :some_proper is defaulting the input to false when if the value is nil it needs to remain nil.
So what's happening is a whole series of nil values are changing to false when our form is submitted.
I have provided some code examples, but I can't find anyway of doing what's needed and we may just need to swap from checkboxes to select fields or something.
%dt= form.label :knowledge_intensive
%dd= form.check_box(:knowledge_intensive, {}, "1", "0")
I have attached a GIF to illustrate the issue clearer:
Demo of issue in GIF Form
The form builder adds a hidden field with the same name as your knowledge_intensive field. If you inspect the generated HTML it will appear immediately before the input for the checkbox.
The reason for this is to allow an unchecked box to pass through as false. I'm not sure how you can get around this, as this mechanism is required to pass the state as a param (HTML spec implies unchecked checkboxes aren't passed as form params). There's no easy way to have separate nil/true/false values - you are probably better off using radio buttons for that.
But that's the reason. The auxiliary hidden field is has a value of '0' and that will be interpreted as 'false' by Rails, unless the user checks the check box.
Does that make sense?
I'm trying to have an if else statement in the controller to do something if the check_box_tag is checked and something else if it isn't checked.
<%= check_box_tag "apply[]", 1, false %>
If it is checked and the form is submitted "apply"=>["1"] is passed as a parameter, if it isn't checked nothing is sent.
Can I have a "apply"=>["0"] passed as a param if it isn't checked?
The check_box_tag indeed does not use the hidden field so it does not send anything in case the box is unchecked (unlike the check_box helper, which is nevertheless still not useful in case of an array param, as Meier notes above).
If you are trying to use your checkbox in a similar way as in this SO question (i.e. to send a user-selected array of ids for example), the simple solution might be to react on an empty param in the controller. Something in the way of:
params[:apply] ||= []
If, on the other hand, you wanted to use the checkboxes as an ordered array where each value would be determined by its constant position in the array, either true or false, (i.e. if you wanted to get something like this in the apply param: [0, 1, 0, 0, 1]), this wouldn't work. You'd have to choose a different approach, e.g. use the checkboxes with a hash param instead of array.
The rails guide has a warning box about this special case:
http://guides.rubyonrails.org/form_helpers.html
Array parameters do not play well with the check_box helper. According
to the HTML specification unchecked checkboxes submit no value.
However it is often convenient for a checkbox to always submit a
value. The check_box helper fakes this by creating an auxiliary hidden
input with the same name. If the checkbox is unchecked only the hidden
input is submitted and if it is checked then both are submitted but
the value submitted by the checkbox takes precedence. When working
with array parameters this duplicate submission will confuse Rails
since duplicate input names are how it decides when to start a new
array element. It is preferable to either use check_box_tag or to use
hashes instead of arrays.
I asked this question before, but I decided to be more specific, so maybe somebody could help.
My question is about this particular problem:
In the ASP.NET MVC app. I have a check box, "Food/Bev", which is of a boolean type, and i have a "Select" list on the Form, and I'd like to know how to manage this:
If the check box is checked:
A dropdown list "Caterer" becomes a required field.
A request cannot be submitted unless the Caterer option is
selected from the list.
If the check box is not checked:
The Caterer dropdown list is not a required field.
And vice virsa.
If both fields are empty, then these fields are not required.
In the Model I have this code:
if (string.IsNullOrEmpty(Caterer)
&& (FoodBeverage == true))
yield return new RuleViolation("Caterer", "Caterer is a required field");
In a View I put this code:
For the "select" field "Caterer":
<label for="Caterer">Caterer</label>
<% if (Model.Request.Caterer == null && Model.Request.FoodBeverage !=null) %>
<select name="Caterer", "required">
<option>A</option>
<option>B</option>
<option>C</option>
For the "checkbox" field "Food/Bev":
<% if (!Model.Request.FoodBeverage && Model.Request.Caterer == null) %>
<%= Html.CheckBox("FoodBeverage", Model.Request.FoodBeverage, new { #class = "required" })%>
<%= Html.ValidationMessage("FoodBeverage", "*")%>
The problem is that the system treats these fields as "required" in both scenarios: if they are both "null" and in the case if one of them is selected or checked.
Looks like the "if" condition on the form doesn't work.
I think the problem here is simply that the If logic isn't validated by the ValidateInput attribute; assuming you're using that of course.
Because MVC1 doesn't do client side validation, this is probably one of the cases where you can implement it, for your very specific requirement.
Add a Javascript Submit function to your form submit, and then you can check the state of the checkbox and that the select list has a valid selection, and simply return false if it's not.
If you check the output code as it stands, you can find the CSS class names the validation logic puts on, so you can emulate the same behavior.
Also, I know this isn't a solution, but if you can upgrade to a later version of MVC I would try it, the unobstrusive ClientSide validation in MVC3 is far superior and anything that can avoid a server round-trip in my book is good.
I'm a bit confused and sorry if this question is repeated elsewhere, I did check and it didnt seem to be here yet.
Is there a way, (without use of JavaScript) to get the currently selected item of a DropDownList and say send it off to an ActionLink?
<%= Html.DropDownList("Elements") %>
<%=Html.ActionLink("Add Authorization Element", "AddElement", new {elementGuid = ??? }) %>
The bit I am looking for is something to replace:
???
Thanks,
Ric
Not without JavaScript, no. Of course, it's trivial with JavaScript.
If you want to do both, add JavaScript to the drop down, then put a submit button inside a noscript tag. Users without JavaScript will have to click the button. Users with JavaScript won't see it.
I have ran into an odd problem with the ActionLink method in ASP.NET MVC Beta. When using the Lambda overload from the MVC futures I cannot seem to specify a parameter pulled from ViewData.
When I try this:
<%= Html.ActionLink<PhotoController>(p => p.Upload(((string)ViewData["groupName"])), "upload new photo") %>
The HTML contains a link with an empty URL.
upload new photo
However if I hard code the parameter, like this:
<%= Html.ActionLink<PhotoController>(p => p.Upload("groupA"), "upload new photo") %>
The output contains an actual URL.
upload new photo
I assume this probably has something to do with the visibility and availability of the ViewData, and it not being there when the Lambda gets evaluated by the internals of the framework. But that is just a guess.
Am I doing something incorrect in the first sample to cause this, or is this some short of bug?
Update: I am using the latest version of the MVC futures. It has been pointed out that this works for some people. Since it doesn't work for me this makes me think that it is something specific to what I am doing. Does anybody have any suggestion for what to look at next, because this one really has me stumped.
Have you updated your version of the Microsoft.Web.Mvc.dll where the Strongly typed actionlink resides.
Apparently this dll has been updated for the Beta release. The function may have been slightly modified.
I just tried this
<%= Html.ActionLink<HomeController>(x=>x.Search((string)ViewData["search"]), "search?") %>
and it worked fine.
Ok, I figured out what my problem was.
Apparently I was not even setting the ViewData slot that I was trying to read from in the view, resulting in it being a null value.
So effectually I was writing:
<%= Html.ActionLink<PhotoController>(p => p.Upload(null), "upload new photo") %>
I think the ultimate kicker to this whole thing was the fact that the parameter (groupname) represents a non-defaultable value in my routing table.
routes.MapRoute(
"Group",
"group/{groupname}/{controller}/{action}/{id}",
new {controller = "Photos", action = "View", Id = ""});
So according to the routing rule the property groupname has to be present, but according go the Lambda gropname was omitted (null). This resulted in the MVC framework being unable to find a route that satisfied my query, and just returning null.