表单帮助方法
参考文章:rails guides-表单帮助方法
一、form_tag
详细使用请阅读api,一般用于处理非模型的表单提交,如搜索表单等。
1.简单的form_tag(以搜索表单为例)
<%= form_tag("/search", method: "get") do %> #搜索表单的请求类型一定要用 GET,这样用户才能把某个搜索结果页面加入收藏夹,以便后续访问
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>
会生成以下html代码
<form accept-charset="UTF-8" action="/search" method="get">
<div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="✓" /></div>
<label for="q">Search for:</label>
<input id="q" name="q" type="text" /> <!--表单中的每个 input 元素都有 ID 属性,其值和 name 属性的值一样,如这里的id="q" -->
<input name="commit" type="submit" value="Search" />
</form>
2.调用 form_tag 时使用多个 Hash 参数
form_tag 方法可接受两个参数:表单提交地址和一个 Hash 选项。Hash 选项指定提交表单使用的请求方法和 HTML 选项,例如 form 元素的 class 属性。
form_tag({controller: "people", action: "search"}, method: "get", class: "nifty_form")
# => '<form accept-charset="UTF-8" action="/people/search" method="get" class="nifty_form">'
3.生成表单中控件的帮助方法
注:生成表单控件的方法,就是生成html文件,完全可以使用html语句代替之。当然,使用这些帮助方法,可以快速的构建出表单,推荐使用。下面简单介绍几种,更多请阅读API.
3.1 复选框
check_box_tag(name, value = "1", checked = false, options = {})
check_box_tag 方法的第一个参数是 name 属性的值。第二个参数是 value 属性的值(可以不加,默认value=1),第三个为cheaked属性,默认为false,第4个可以是disabled的标签。选中复选框后,value 属性的值会包含在提交的表单数据中,因此可以通过 params 获取。
<%= check_box_tag(:pet_dog) %>
<%= label_tag(:pet_dog, "I own a dog") %>
<%= check_box_tag(:pet_cat,"yes",true,class="CAT_STYLE") %>
<%= label_tag(:pet_cat, "I own a cat") %>
生成以下代码
<input type="checkbox" name="pet_dog" id="pet_dog" value="1" />
<label for="pet_dog">I own a dog</label>
<input type="checkbox" name="pet_cat" id="pet_cat" value="yes" disabled="disabled" class="cat" checked="checked" />
<label for="pet_cat">I own a cat</label>
<input id="age_child" name="age" type="radio" value="child" />
<label for="age_child">I am younger than 21</label>
<input id="age_adult" name="age" type="radio" value="adult" />
<label for="age_adult">I'm over 21</label>
3.2 单选框
radio_button_tag(name, value, checked = false, options = {})
单选框有点类似复选框,但是各单选框之间是互斥的,只能选择一组中的一个,和复选框用法一样,只是name必须一样。
<%= radio_button_tag(:age, "child") %>
<%= label_tag(:age_child, "I am younger than 21") %>
<%= radio_button_tag(:age, "adult") %>
<%= label_tag(:age_adult, "I'm over 21") %>
生成以下代码
<input id="age_child" name="age" type="radio" value="child" />
<label for="age_child">I am younger than 21</label>
<input id="age_adult" name="age" type="radio" value="adult" />
<label for="age_adult">I'm over 21</label>
3.3更多帮助方法
其他值得说明的表单控件包括:多行文本输入框,密码输入框,隐藏输入框,搜索关键字输入框,电话号码输入框,日期输入框,时间输入框,颜色输入框,日期时间输入框,本地日期时间输入框,月份输入框,星期输入框,URL 地址输入框,Email 地址输入框,数字输入框和范围输入框:
<%= text_area_tag(:message, "Hi, nice site", size: "24x6") %>
<%= password_field_tag(:password) %>
<%= hidden_field_tag(:parent_id, "5") %>
<%= search_field(:user, :name) %>
<%= telephone_field(:user, :phone) %>
<%= date_field(:user, :born_on) %>
<%= datetime_field(:user, :meeting_time) %>
<%= datetime_local_field(:user, :graduation_day) %>
<%= month_field(:user, :birthday_month) %>
<%= week_field(:user, :birthday_week) %>
<%= url_field(:user, :homepage) %>
<%= email_field(:user, :address) %>
<%= color_field(:user, :favorite_color) %>
<%= time_field(:task, :started_at) %>
<%= number_field(:product, :price, in: 1.0..20.0, step: 0.5) %>
<%= range_field(:product, :discount, in: 1..100) %>
生成
<textarea id="message" name="message" cols="24" rows="6">Hi, nice site</textarea>
<input id="password" name="password" type="password" />
<input id="parent_id" name="parent_id" type="hidden" value="5" />
<input id="user_name" name="user[name]" type="search" />
<input id="user_phone" name="user[phone]" type="tel" />
<input id="user_born_on" name="user[born_on]" type="date" />
<input id="user_meeting_time" name="user[meeting_time]" type="datetime" />
<input id="user_graduation_day" name="user[graduation_day]" type="datetime-local" />
<input id="user_birthday_month" name="user[birthday_month]" type="month" />
<input id="user_birthday_week" name="user[birthday_week]" type="week" />
<input id="user_homepage" name="user[homepage]" type="url" />
<input id="user_address" name="user[address]" type="email" />
<input id="user_favorite_color" name="user[favorite_color]" type="color" value="#000000" />
<input id="task_started_at" name="task[started_at]" type="time" />
<input id="product_price" max="20.0" min="1.0" name="product[price]" step="0.5" type="number" />
<input id="product_discount" max="100" min="1" name="product[discount]" type="range" />
二、form_for
1.模型对象帮助方法
模型对象帮助方法的第一个参数是实例变量的名字,第二个参数是在对象上调用的方法名(一般都是模型的属性)。Rails 会把在对象上调用方法得到的值设为控件的 value 属性值,并且设置相应的 name 属性值。
<%= text_field(:person, :name) %> #传入的参数必须是实例变量的名字,例如 :person 或 "person",而不是模型对象的实例本身。
生成如下代码:
<input id="person_name" name="person[name]" type="text" value="#{@proson}"/>
2.2 把表单绑定到对象上
虽然上述用法很方便,但却不是最好的使用方式。如果 Person 有很多要编辑的属性,我们就得不断重复编写要编辑对象的名字。我们想要的是能把表单绑定到对象上的方法,form_for 帮助方法就是为此而生。这也是为什么处理有模型的表单使用form_for的原因。
如app/controllers/articles_controller.rb有:
def new
@article = Article.new
end
在 new 动作对应的视图 app/views/articles/new.html.erb 中可以像下面这样使用 form_for 方法:
<%= form_for @article, url: {action: "create"}, html: {class: "nifty_form"} do |f| %>
<%= f.text_field :title %>
<%= f.text_area :body, size: "60x12" %>
<%= f.submit "Create" %>
<% end %>
生成如下html
<form accept-charset="UTF-8" action="/articles/create" method="post" class="nifty_form">
<input id="article_title" name="article[title]" type="text" />
<textarea id="article_body" name="article[body]" cols="60" rows="12"></textarea>
<input name="commit" type="submit" value="Create" />
</form>
2.3 记录辨别技术
处理 REST 资源时,使用“记录辨别”技术可以简化 form_for 方法的调用。简单来说,你可以只把模型实例传给 form_for,让 Rails 查找模型名等其他信息:
## Creating a new article
# long-style:
form_for(@article, url: articles_path)
# same thing, short-style (record identification gets used):
form_for(@article)
## Editing an existing article
# long-style:
form_for(@article, url: article_path(@article), html: {method: "patch"})
# short-style:
form_for(@article)
form_for(@article),如果@article不存在,即@article.new_record?为true,当你提交表单时,会匹配articles_path url,如果@article是个实例,即@article.new_record? 为false,则匹配sarticle_path(@article) url。
Rails 还会自动设置 class 和 id 属性。在新建文章的表单中,id 和 class 属性的值都是 new_article。如果编辑 ID 为 23 的文章,表单的 class 为 edit_article,id 为 edit_article_23。为了行文简洁,后文会省略这些属性。