Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
faba406f
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
faba406f
编写于
6月 08, 2011
作者:
B
Bogdan Gusiev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fixing select[multiple] html specification problem.
Generating hidden input with same name before each multiple select
上级
47ac8969
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
55 addition
and
8 deletion
+55
-8
actionpack/lib/action_view/helpers/form_options_helper.rb
actionpack/lib/action_view/helpers/form_options_helper.rb
+37
-6
actionpack/test/template/form_options_helper_test.rb
actionpack/test/template/form_options_helper_test.rb
+18
-2
未找到文件。
actionpack/lib/action_view/helpers/form_options_helper.rb
浏览文件 @
faba406f
...
...
@@ -128,6 +128,28 @@ module FormOptionsHelper
# By default, <tt>post.person_id</tt> is the selected option. Specify <tt>:selected => value</tt> to use a different selection
# or <tt>:selected => nil</tt> to leave all options unselected. Similarly, you can specify values to be disabled in the option
# tags by specifying the <tt>:disabled</tt> option. This can either be a single value or an array of values to be disabled.
#
# ==== Gotcha
#
# The HTML specification says when +multiple+ parameter passed to select and all options got deselected
# web browsers do not send any value to server. Unfortunately this introduces a gotcha:
# if an +User+ model has many +roles+ and have +role_ids+ accessor, and in the form that edits roles of the user
# the user deselects all roles from +role_ids+ multiple select box, no +role_ids+ parameter is sent. So,
# any mass-assignment idiom like
#
# @user.update_attributes(params[:user])
#
# wouldn't update roles.
#
# To prevent this the helper generates an auxiliary hidden field before
# every multiple select. The hidden field has the same name as multiple select and blank value.
#
# This way, the client either sends only the hidden field (representing
# the deselected multiple select box), or both fields. Since the HTML specification
# says key/value pairs have to be sent in the same order they appear in the
# form, and parameters extraction gets the last occurrence of any repeated
# key in the query string, that works for ordinary forms.
#
def
select
(
object
,
method
,
choices
,
options
=
{},
html_options
=
{})
InstanceTag
.
new
(
object
,
method
,
self
,
options
.
delete
(
:object
)).
to_select_tag
(
choices
,
options
,
html_options
)
end
...
...
@@ -557,7 +579,7 @@ def to_select_tag(choices, options, html_options)
value
=
value
(
object
)
selected_value
=
options
.
has_key?
(
:selected
)
?
options
[
:selected
]
:
value
disabled_value
=
options
.
has_key?
(
:disabled
)
?
options
[
:disabled
]
:
nil
content_tag
(
"select"
,
add_options
(
options_for_select
(
choices
,
:selected
=>
selected_value
,
:disabled
=>
disabled_value
),
options
,
selected_value
),
html_options
)
select_content_tag
(
add_options
(
options_for_select
(
choices
,
:selected
=>
selected_value
,
:disabled
=>
disabled_value
),
options
,
selected_value
),
html_options
)
end
def
to_collection_select_tag
(
collection
,
value_method
,
text_method
,
options
,
html_options
)
...
...
@@ -566,8 +588,8 @@ def to_collection_select_tag(collection, value_method, text_method, options, htm
value
=
value
(
object
)
disabled_value
=
options
.
has_key?
(
:disabled
)
?
options
[
:disabled
]
:
nil
selected_value
=
options
.
has_key?
(
:selected
)
?
options
[
:selected
]
:
value
content_tag
(
"select"
,
add_options
(
options_from_collection_for_select
(
collection
,
value_method
,
text_method
,
:selected
=>
selected_value
,
:disabled
=>
disabled_value
),
options
,
value
),
html_options
select_
content_tag
(
add_options
(
options_from_collection_for_select
(
collection
,
value_method
,
text_method
,
:selected
=>
selected_value
,
:disabled
=>
disabled_value
),
options
,
value
),
html_options
)
end
...
...
@@ -575,8 +597,8 @@ def to_grouped_collection_select_tag(collection, group_method, group_label_metho
html_options
=
html_options
.
stringify_keys
add_default_name_and_id
(
html_options
)
value
=
value
(
object
)
content_tag
(
"select"
,
add_options
(
option_groups_from_collection_for_select
(
collection
,
group_method
,
group_label_method
,
option_key_method
,
option_value_method
,
value
),
options
,
value
),
html_options
select_
content_tag
(
add_options
(
option_groups_from_collection_for_select
(
collection
,
group_method
,
group_label_method
,
option_key_method
,
option_value_method
,
value
),
options
,
value
),
html_options
)
end
...
...
@@ -584,7 +606,7 @@ def to_time_zone_select_tag(priority_zones, options, html_options)
html_options
=
html_options
.
stringify_keys
add_default_name_and_id
(
html_options
)
value
=
value
(
object
)
content_tag
(
"select"
,
select_content_tag
(
add_options
(
time_zone_options_for_select
(
value
||
options
[
:default
],
priority_zones
,
options
[
:model
]
||
ActiveSupport
::
TimeZone
),
options
,
value
...
...
@@ -603,6 +625,15 @@ def add_options(option_tags, options, value = nil)
end
option_tags
.
html_safe
end
def
select_content_tag
(
content
,
html_options
)
select
=
content_tag
(
"select"
,
content
,
html_options
)
if
html_options
[
"multiple"
]
tag
(
"input"
,
:disabled
=>
html_options
[
"disabled"
],
:name
=>
html_options
[
"name"
],
:type
=>
"hidden"
,
:value
=>
""
)
+
select
else
select
end
end
end
class
FormBuilder
...
...
actionpack/test/template/form_options_helper_test.rb
浏览文件 @
faba406f
...
...
@@ -457,6 +457,22 @@ def test_select_under_fields_for_with_string_and_given_prompt
)
end
def
test_select_with_multiple_to_add_hidden_input
output_buffer
=
select
(
:post
,
:category
,
""
,
{},
:multiple
=>
true
)
assert_dom_equal
(
"<input type=
\"
hidden
\"
name=
\"
post[category][]
\"
value=
\"\"
/><select multiple=
\"
multiple
\"
id=
\"
post_category
\"
name=
\"
post[category][]
\"
></select>"
,
output_buffer
)
end
def
test_select_with_multiple_and_disabled_to_add_disabled_hidden_input
output_buffer
=
select
(
:post
,
:category
,
""
,
{},
:multiple
=>
true
,
:disabled
=>
true
)
assert_dom_equal
(
"<input disabled=
\"
disabled
\"
type=
\"
hidden
\"
name=
\"
post[category][]
\"
value=
\"\"
/><select multiple=
\"
multiple
\"
disabled=
\"
disabled
\"
id=
\"
post_category
\"
name=
\"
post[category][]
\"
></select>"
,
output_buffer
)
end
def
test_select_with_blank
@post
=
Post
.
new
@post
.
category
=
"<mus>"
...
...
@@ -649,11 +665,11 @@ def test_collection_select_with_blank_as_string_and_style
)
end
def
test_collection_select_with_multiple_option_appends_array_brackets
def
test_collection_select_with_multiple_option_appends_array_brackets
_and_hidden_input
@post
=
Post
.
new
@post
.
author_name
=
"Babe"
expected
=
"<select id=
\"
post_author_name
\"
name=
\"
post[author_name][]
\"
multiple=
\"
multiple
\"
><option value=
\"\"
></option>
\n
<option value=
\"
<Abe>
\"
><Abe></option>
\n
<option value=
\"
Babe
\"
selected=
\"
selected
\"
>Babe</option>
\n
<option value=
\"
Cabe
\"
>Cabe</option></select>"
expected
=
"<
input type=
\"
hidden
\"
name=
\"
post[author_name][]
\"
value=
\"\"
/><
select id=
\"
post_author_name
\"
name=
\"
post[author_name][]
\"
multiple=
\"
multiple
\"
><option value=
\"\"
></option>
\n
<option value=
\"
<Abe>
\"
><Abe></option>
\n
<option value=
\"
Babe
\"
selected=
\"
selected
\"
>Babe</option>
\n
<option value=
\"
Cabe
\"
>Cabe</option></select>"
# Should suffix default name with [].
assert_dom_equal
expected
,
collection_select
(
"post"
,
"author_name"
,
dummy_posts
,
"author_name"
,
"author_name"
,
{
:include_blank
=>
true
},
:multiple
=>
true
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录