Create Custom HTML Helpers in Ruby on Rails

create custom html helpers in ruby on rails

To create a new helper:

  1. choose a name for the helper file, for instance tags_helper.rb
  2. create the file in the /app/helpers directory
  3. create a module according to the file name. In this case

    module TagsHelper
    end
  4. define your helper as method

    module TagsHelper
    def hello_world(name)
    "hello #{name}"
    end
    end

Now you can use the hello_world helper method in your view.

Helpers in Rails - What's the best approach when building the html string?

If html is longer than 1 line, i usually put the html in a partial and call it with a custom helper method

view

<= display_my_html(@item, {html_class: "active"}) %>

helper

def display_my_html(item, opts={})
name = item.name.upcase
html_class = opts.key?(:html_class) ? opts[:html_class] : "normal"

render "my_html", name: name, html_class: html_class
end

partial

<div class="<%= html_class %>">
<span class="user">
<%= name %>
</span>
</div>

Custom HTML attribute requires a custom helper?

Oops. It's just

<%= f.text_field :question, :id=>"poll_question", :class=>"BigInput", :style=>"width:98%;", 'data-submit_clear'=>'1' %>

Restrict title display to admin users - custom html helper

I had to create a helper to check for admin users:

def admin?
# check if this user is an admin
end

Then I had to create a custom helper which returns a title for an admin user:

def generate_title(this)
if admin?
"id:#{this}"
end
end

And finally update my cell to use the custom helper:

<td title="<%= generate_title(alert.id) %>">Hello</td>

Its all about the custom helpers!

Ruby on Rails Custom Helper outputting HTML nested list

If you want to stick with helpers, then something like this could help:

def present_search_results(results)
content_tag(:ul, class: "websites-list") do

results.map do |website_id, bookmarks|
bookmarks = [bookmarks] unless bookmarks.is_a?(Array)

content_tag(:li, class: "website-#{website_id}") do
website = Website.find(website_id)
concat(website.url)
concat(
content_tag(:ul, class: "bookmarks-list") do

bookmarks.map do |bookmark_id|
bookmark = Bookmark.find(bookmark_id)
content_tag(:li, bookmark.title)
end.reduce(:+)
end
)
end
end.reduce(:+)
end
end

But, in my opinion, that code is not easy to read, so you could use plain html instead, like this:

def present_search_results(results)
list = "<ul class='websites-list'>"

results.each do |(website_id, bookmarks)|
bookmarks = [bookmarks] unless bookmarks.is_a?(Array)
website = Website.find(website_id)

list += "<li class='website-#{website_id}'>#{website}"
list += "<ul class='bookmarks-list'>"

bookmarks.each do |bookmark_id|
bookmark = Bookmark.find(bookmark_id)
list += "<li>#{bookmark.title}</li>"
end

list += "</ul></li>"
end

list += "</ul>"
list.html_safe
end

I like this one better, since it is easier to read. But both with output the list you want.

Create a helper or something for haml with ruby on rails

You can use haml_tag too

def content_box
haml_tag :div, :class => "holder" do
haml_tag :div, :class => "top"
haml_tag :div, :class => "content" do
yield
haml_tag :div, :class => "bottom"
end
end

and in haml

%html
%head
%body
Maybee some content here.
= content_box do
Content that goes in the content_box like news or stuff

Custom form helpers

Yes, you can add to the FormBuilder class and get access to the object passed into the form_for. I've done this for a lot of things: dates, times, measurements, etc. Heres an example:

class ActionView::Helpers::FormBuilder
include ActionView::Helpers::TagHelper
include ActionView::Helpers::FormTagHelper
include ActionView::Helpers::FormOptionsHelper
include ActionView::Helpers::CaptureHelper
include ActionView::Helpers::AssetTagHelper

# Accepts an int and displays a smiley based on >, <, or = 0
def smile_tag(method, options = {})
value = @object.nil? ? 0 : @object.send(method).to_i
options[:id] = field_id(method,options[:index])
smiley = ":-|"
if value > 0
smiley = ":-)"
elsif smiley < 0
smiley = ":-("
end
return text_field_tag(field_name(method,options[:index]),options) + smiley
end

def field_name(label,index=nil)
output = index ? "[#{index}]" : ''
return @object_name + output + "[#{label}]"
end

def field_id(label,index=nil)
output = index ? "_#{index}" : ''
return @object_name + output + "_#{label}"
end

end

Which you can use like this:

<% form_for @quiz do |f| %>
<%= f.smile_tag(:score) %>
<% end %>

There are some instance variables created by Rails that you can access in these helper methods:

  • @object - the model object specified by the form
  • @object_name - the class name of the object
  • @template - I think its an instance of the ActionView, you can possibly bypass all the includes I added by calling methods on the template. Haven't tried that yet.
  • @options - options passed to the FormBuilder when its created by the form_for call

I wrote the field_id and field_name methods to create these attributes on the HTML input elements the same way the regular helpers do, I'm sure there is a way to tie into the same methods that Rails uses, but I haven't found it yet.

The sky is the limit on what you can do with these helper methods, they simply return strings. You can create entire HTML tables or pages in one, but you better have a good reason to.

This file should be added in the app/helpers folder

Rails: understanding custom form helper

form.radio_button helper returns a string and I18n.t too returns a string. So, you can concatenate them.

More details how form tag is generated

This is a code of radio_button:

https://github.com/casunlight/rails/blob/master/actionview/lib/action_view/helpers/form_helper.rb

def radio_button(object_name, method, tag_value, options = {})
Tags::RadioButton.new(object_name, method, self, tag_value, options).render
end

Look at implementation of render method

https://github.com/casunlight/rails/blob/master/actionview/lib/action_view/helpers/tags/radio_button.rb#L20

def render
options = @options.stringify_keys
options["type"] = "radio"
options["value"] = @tag_value
options["checked"] = "checked" if input_checked?(object, options)
add_default_name_and_id_for_value(@tag_value, options)
tag("input", options)
end

Tag helper generate html tag and return his as html safed string:

https://github.com/casunlight/rails/blob/master/actionview/lib/action_view/helpers/tag_helper.rb#L67

def tag(name, options = nil, open = false, escape = true)
"<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
end

Rails: Best practice to generate custom HTML in Model?

I would do the following

def embed_element(external_video)
content_tag(:embed, '', :src => external_video.video_source)
end

You should probably check the docs for more information on the content tag method.

Also note that the content_tag() method will insert a closing tag. Something you seem to be forgetting...



Related Topics



Leave a reply



Submit