generate subscript in controller and pass to view - html

In controller, I can pass string to view.
How can I pass string with subscript?
In html its easy, just use a <sub> tag.
I tried 3 times to pass this subscript to view but failed.
If I pass <sub> inside the string, it will display I<sub>tag</sub> instead of Itag.
If I use string1="string"+<sub>+"tag"+</sub> ,and pass
string1, The controller will give error!
Last, I tried directly to copy subscript string inside the page, I
also got an error that it can't get displayed.
How can I pass subscript string to view? I got to loop different conditions so I cant each use <sub> tag, I need pass from controller.
Edit:
I tried this code in controller
#valuedisplay=#value.to_s + " m/s<sup>2</sup>".html_safe
As suggest solution ,and I get:
Just as what I said in 1st try,display the <sup> instead of m2.
If I do it in view,I have many different types of data ,I need add checking data type code in view according to different types,its doable but will make the view messy, I felt there should be a neat way to settle it in controller?

You need to safely render the HTML in your view, and for this purpose, you need to call html_safe function on your string:
#str = "I<sub>tag</sub>".html_safe
And, now when you pass this #str to your view, it will render the #str as expected.
In view:
<%= #str %>
Caution:
It would be a very bad practice to do so. <sub>ag</sub> belongs to view, so it should be in view. You can do something like following:
In controller:
#str = "tag"
And in view:
I<sub><%= #str %></sub>
<%# or %>
<%= "I<sub>#{#str}</sub>" %>

Related

How to include html tags inside the text method of an `options_from_collection_for_select`?

I'm making a form that has a select_tag, and I want to format the displayed text a certain way. Here's what I tried so far, in the object's model:
def display_name
return description.upcase+"<div class='pull-right'>"+date.upcase+"</div>"
end
This doesn't work, I just end up with html as a string.
I already tried adding .html_safe:
return descricao.upcase+"<div class='pull-right'>".html_safe+date.upcase+"</div>".html_safe
Any ideas?

Best practice for custom text_method in collection_select?

I have Rails app with a use case to display prices in a collection_select dropdown box. For instance, names of products and their prices, or clients and amounts owing.
I well know it's bad MVC practice to simply include the relevant helpers to get access to functions like number_to_currency, but the best I can do with a custom method on the Product or Payment model is get a value that looks like $20.2. So, it's readable but sub-optimal in that most users of the system will be expecting twenty dollars and twenty cents to be represented as $20.20.
Does anyone have any suggestions for easily customising the text_method of a collection_select?
The text_method as well as the value_method in collection_select accepts a symbol but also a lambda/proc block which will get the current collection element as a parameter. See the docs here. The lambda is executed in the context of the view so all view helpers should be available inside it.
So to get the model price formatted by a currency formatter you should be able to call collection_select like the following:
<%= collection_select :user, :payment_id, #user.payments,
:id, ->(pmt) { number_to_currency(pmt.amount) } %>
You have not shown your model associations, so this is just an example of a user having many payments for which you want to format the price in the select box text.
Abandon ship with the collection_select method, and just use select in your view:
<% options = #payments.each { |p| number_to_currency(p.price), p.id } %>
<%= f.select :payment, options %>
Since you're in the view, everything you'd expect is there, both model and helper methods.
I'm making assumptions on your HTML since you didn't give a specific example, but I think the code block above is everything you need to get going. For more details: http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-select
If you are married to collection_select, you could always roll your own number formatter for currency; shouldn't be difficult with pure Ruby. But, the method above will be more powerful in the long run and afford your more options with helpers down the line, and let you use functions consistently across views.
I ended up building on GoGoCarl's suggestion, but moving the array generation to a helper:
module PaymentsHelper
def invoices_for_payment_select(invoice)
#invoices.collect { |i| ["#{i.client.name} - #{number_to_currency(i.outstanding)}", i.id] }
end
end
This way I can reuse the dropdown box should I need to and keep the view neat.

Need Validation on html dropdownlist with data from Viewbag

I know I'm not supposed to use the Viewbag and that I should build a menu using Html.DropDowlListFor() so that i can add attribute bound to the members of the model, BUT, that would involve a pretty extensive code rewrite....
I have a custom controller with a menu:
*.ASCX
<%: Html.DropDownList("CityIDs", new SelectList(ViewBag.cities, "Id", "Name"), "--Select--", new { style = "width:200px" })%>
<%= Html.ValidationMessage("CityIDs") %>
The List populates just fine and I can default to the top item to "--Select--"
The prbolem is that I want the validation error to occur on anything that is not from the viewbag.... how can I achieve this?
Validation for dropdown lists only ensures that something was posted. If you want to ensure that the value that was posted is actually one of a set of "allowed" values, then you'll have to manually do that in your post action:
var cityIds = db.Cities.Select(m => m.Id);
if (!cityIds.Contains(model.CityIDs))
{
ModelState.AddModelError("CityIDs", "You must select one of the available choices.");
}
if (ModelState.IsValid)
{
...
Two things:
Notice that I'm pulling the city ids straight from the database (the actual code you'd need here, of course, depends on your specific implementation). The important thing, though, is that ViewBag only survives a single request, so you can't look for them in ViewBag after posting.
Despite the pluralized name of CityIDs, using the DropDownList helper ensures that only a single selected value will exist. If this is actually supposed to be a multiselect, then you need to use ListBox instead, and update this conditional here to account for check for multiple values.
Populates the top item with Text = "--Select--" and Value = ""
which will post a blank value for CityIDs and cause an error in ModelState.

unescape HTML in options for select

I've got a select tag, which is used to change the filter via the URL. On change I reload the page to update the results accordingly. The newly selected filter should obviously appear as selected. But this fails to work.
<%= select_tag("filter_rating" , (:selected =>) options_for_select(rating_filter_options, (request.env['PATH_INFO']))) %>
I deleted the (:selected =>) as it seems unnecessary.
rating_filter_options value:
# [["by my rating", "/all"], ["1+", "/rating%3E=1"], ... , ["5", "/rating%3E=5"]]
The reason why the current filter will not get selected is that request.env['PATH_INFO'] returns /rating>=1, which is different than /rating%3E=5. So the solution would be to unescape that nasty %3E.
I tried using CGI.unescape, h, html_safe on the select tag, but so far my attempts have failed.
Any ideas?
Update:
I changed the helper that generated the rating_filter_options and placed the CGI.unescape correctly so it now returns:
# [["by my rating", "/all"], ["1+", "/rating>=1"], ... , ["5", "/rating>=5"]]
Also, I use CGI.unescape for the request.env['PATH_INFO'] to make sure it is the same. The result in logs & HTML approve that it is correct now. BUT the selected filter still does not get selected...
CGI should work.
irb(main):112:0> CGI.unescape("/rating%3E=1")
=> "/rating>=1"

Rails form_for setting options and setting selected option

Another simple question i'm sure so sorry in advance but i cant seem to find a solution to what i am trying to do.
I have form with a select field (vehicle_size) that i want to populate with all existing options that are currently in the database for records that have vehicle_size set. I also want to set the selected option to whatever the option in the database is currently set to (if set) but i guess the problem that i am having is the reason that this value isn't being set already.
I currently have this code:
<%= f.select(:vehicle_size, #models.index_by {|m| m.vehicle_size}, :selected => :vehicle_size) %>
which is populating the select options correctly but in my new and edit pages (both using this form) the select menu is blank even though currently all records are be set to one of the existing options (vehicle_size may actually be blank for some records in future).
If i then select an option from the menu and save the record the vehicle_size option has a strange value. something along the lines of :
#<Model:0x007fd13e6c3790>
I'm pretty sure i'm using index_by in the wrong way so some pointers on what i'm missing would be great.
The parameters of f.select are: attribute_name,option_tags,options.
option_tags is supposed to be a string of html option tags.
There are some helpers to construct such a string from i.e. an array of values, a collection etc.: options_for_select, options_from_selection_for_select.
You have to use one of these helpers.
You can get the existing vehicle_sizees with:
Model.pluck(:vehicle_size).uniq
so your select could look like:
<%= f.select :vehicle_size, options_for_select(Model.pluck(:vehicle_size).uniq,#model.vehicle_size) %>
See the Rails Guide on form helpers.