I'm currently trying to create a view in asp.net MVC2 which includes a checkbox in each row. This will be a "mark" box, and there will be a button on the view which can then be used for multiple deletion.
I have a model which contains a list of the objects being listed, so I have some code which reads as:-
<% foreach (CancelledCard item in Model.CancelledCards) { %>
I've then tried to use
<%: Html.CheckBoxFor(item >= item.Checked) %>
but I'm getting an error.
What am I missing? What's the right way to do this in MVC2?
In C# a lambda expression uses => and not >=:
<%: Html.CheckBoxFor(item => item.Checked) %>
Also instead of saying that you get an error, you could have posted the error message. It would have been much more clear.
<%: Html.CheckBoxFor(item >= item.Checked) %>
is wrong. It should be:
<%: Html.CheckBoxFor(item => item.Checked) %>
Related
I keep getting this error
undefined method`content'for"Post::ActiveRecord_Associations_CollectionProxy:0x00000104e87060"
When I do <%= #user.posts.content %>
but when I do <%= #user.posts.count %> everything shows up normal and it works... I don't understand why I can call count and it show's the number of posts in the users show.html.erb page but when I try and show the content it throws and error.
Any ideas?
Instead of <%= #user.posts.content %>
Use this
<% #user.posts.each do |post| %>
<%= post.content %>
<% end %>
#user.posts return a collection of posts. So, when you call count you get the count of all records returned by #user.posts. BUT in order to access content attribute of each post, you will need to iterate over the collection and display the relevant data.
I browsed all SO questions and answers about this topic but I'm still unable to make my scenario work.
I want to trigger a click button action when a dropdown menu option is selected ; seems simple and should be very common with AJAX.
Here are the relevant excerpts of my code:
<%= form_for(#test, :html => {:id => "form_id", :name => "MyForm", :remote => "true"}) do |form| %>
<%= form.label "Menu1" %>
<%= form.select (:Menu1, [["Option1","value1"],["Option2","value2"]], :html_options=>{:onChange=>"javascript: this.form.apply_button_name.click();"}) %>
<!-- more select menus and text fields here -->
<div class="actions">
<%= form.submit "Apply", :name => "apply_button_name", :remote => "true" %>
</div>
<% end %>
I used ":remote => "true" both for the form and the button because that's the only way to get AJAX working. I also tried with and without explicit "html_options" and "javascript:", after I browsed some SO answers that suggested that but that did not help. I also tried onSelect, and onClick instead of onChange, but still no luck.
The generated HTML is the following:
Menu1
<select id="test_Menu1" name="test[Menu1]"><option value="value1">Option1</option>
<option value="value2" selected="selected">Option2</option></select>
As you can see, there's no onChange event handler in the HTML code ; WHY? Anyone is seeing what am I doing wrong?
Thanks for any help.
Modify your call to form.select, like this:
<%= form.select :Menu1, [["Option1","value1"],["Option2","value2"]], {},
:onChange=>"javascript: this.form.apply_button_name.click();" %>
If you examine the documentation for:
API Dock Ruby on Rails select
You will see that the select form helper takes the form:
select(object, method, choices, options = {}, html_options = {})
If you don't pass anything for the option hash (in your case this will be an empty hash), the form thinks that your html_options hash are your options hash, and gets confused.
A way to check this is to add something like {:onchange=> "alert('Hello');"} and either see if the event successfully triggers, or alternatively, in your actual web page, right click on the select element and inspect it. If no onchange option is present in the html, that means that your rails form helper is indeed confusing the html_options with the other options. So, what you should have:
<%= form.select (:Menu1, [["Option1","value1"],["Option2","value2"]], {}, {:onChange=>"handler();"} %>
MAKE SURE TO INCLUDE THE EMPTY HASH FOR THE OPTIONS BEFORE THE HTML OPTIONS AND YOU SHOULD BE FINE. I don't think you even need to have the html_options and javascript stuff you have.
Lastly, if onChange doesn't work, try to use onchange with no capital C.
I'm learning about HTMLHelpers in ASP.NET MVC.
To render the form HTML tag you would write something like
<% using(Html.BeginForm("HandleForm", "Home")) {%>
<!--Form content goes here-->
<% } %>
or
<% Html.BeginForm(); %>
… Form Contents …
<% Html.EndForm(); %>
To render the a checkbox you would use
<%= Html.CheckBox("bookType") %>
What I would like to know is is why we need to use <% when we use BeginForm whereas we need to use <%= when we use other HTMLHelper methods
Cheers,
Html.CheckBox returns a string of HTML containing an <input> tag.
You need to print this string to the page by writing <%= ... %>.
Html.BeginForm prints the HTML inside the method (by calling Response.Write), and doesn't return HTML. (instead, it returns an IDisposable, so that you can use it in a using block)
Since you aren't printing its return value, you put it in a <% ... %> block, which executes code without printing its results.
<% %> wraps a code block
<%="string" %> is equivalent to <% Response.Write("string") %>
and in ASP.NET MVC 3 you can automatically HtmlEncode with <%: "<htmlTag>" %>
You can definitely write <%=Html.BeginForm() %> but you will also need to write <%=Html.EndForm() %>. Wrapping Html.BeginForm() within a using block will just render the closing </form> tag for you.
Because <%= means "Print this for me", pretty much the same as doing:
<% Response.Write("content"); %>
When <% means that you have a code-block that might do more than just print the value you have nested in it.
I created a Display Template which when passed a string renders a disabled text box
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<String>" %>
<%: Html.TextBoxFor(model => model, new { disabled = "disabled" })%>
Which works great. However, for some reason MVC wants to try and stuff DateTimes and Ints through it as well, which is throwing exceptions
The model item passed into the dictionary is of type 'System.Int32', but this dictionary requires a model item of type 'System.String'.
Any ideas?
You don't need to strongly type the template to a String.
you can try something like this :
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%= Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue,
, new { disabled = "disabled" }) %>
And in your view you call it like this
Html.DisplayModelFor(model => mode.name);
For more information see an example of the default built-in editor template for the string in Brad Wilson article in his his series on Templates in ASP.NET MVC.
You should consider going through the complete series. I can't express how helpful this series was for me.
I have the following asp.net mvc2 template:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ncontinuity2.core.dto.TrainingLookUpContainer>" %>
<%= Html.EditorFor(x => ViewData.Model.TrainingTree, "TrainingCategory")%>
You can see that I want to bind it to a model of type TrainingLookUpContainer.
The problem is, the following mark up is being generated:
<input id="ViewData_Model_TrainingTree_TrainingCourses_0__Uid" name="ViewData.Model.TrainingTree.TrainingCourses[0].Uid" type="hidden" value="cbd43b5a-2a6a-493f-98e4-9dc9010cbaaf" />
The bit I object to is the ViewData_Model_ prefix for the id of the element and the ViewData.Model. prefix for the name attribute.
I have no idea where this prefix is coming from and it of course means that the model never gets bound when it comes to posting the form.
Is there another way, I can control the mark up that is getting generated or is this a bug in the framework. I have used EditorFor in other parts and it works fine.
change
<%= Html.EditorFor(x => ViewData.Model.TrainingTree, "TrainingCategory")%>
to
<%= Html.EditorFor(x => x.TrainingTree, "TrainingCategory")%>