Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
b3787643
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 搜索 >>
提交
b3787643
编写于
1月 30, 2010
作者:
J
Joshua Peek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Move link_to_function and link_to_remote into prototype_legacy_helper
plugin
上级
2de311a0
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
82 addition
and
348 deletion
+82
-348
actionpack/README
actionpack/README
+34
-43
actionpack/lib/action_view/helpers/javascript_helper.rb
actionpack/lib/action_view/helpers/javascript_helper.rb
+0
-54
actionpack/lib/action_view/helpers/prototype_helper.rb
actionpack/lib/action_view/helpers/prototype_helper.rb
+0
-141
actionpack/lib/action_view/helpers/scriptaculous_helper.rb
actionpack/lib/action_view/helpers/scriptaculous_helper.rb
+48
-53
actionpack/test/template/javascript_helper_test.rb
actionpack/test/template/javascript_helper_test.rb
+0
-29
actionpack/test/template/prototype_helper_test.rb
actionpack/test/template/prototype_helper_test.rb
+0
-28
未找到文件。
actionpack/README
浏览文件 @
b3787643
...
...
@@ -37,15 +37,15 @@ A short rundown of the major features:
def
show
@
customer =
find_customer
end
def
update
@
customer =
find_customer
@
customer.attributes =
params[:customer]
@
customer.save
?
@
customer.save
?
redirect_to(:action =
>
"show"
)
:
render(:action =
>
"edit"
)
end
private
def
find_customer
()
Customer.find
(
params
[
:id
])
end
end
...
...
@@ -64,7 +64,7 @@ A short rundown of the major features:
<
%
unless
@
person.is_client
?
%
>
Not for clients to see...
<
%
end
%
>
{Learn more}[link:classes/ActionView.html]
...
...
@@ -99,24 +99,24 @@ A short rundown of the major features:
before_filter
:authenticate
,
:cache
,
:audit
after_filter
{
|
c
|
c.response.body =
Gzip::compress(c.response.body)
}
after_filter
LocalizeFilter
def
index
#
Before
this
action
is
run
,
the
user
will
be
authenticated
,
the
cache
#
will
be
examined
to
see
if
a
valid
copy
of
the
results
already
#
exists
,
and
the
action
will
be
logged
for
auditing.
#
After
this
action
has
run
,
the
output
will
first
be
localized
then
#
After
this
action
has
run
,
the
output
will
first
be
localized
then
#
compressed
to
minimize
bandwidth
usage
end
private
def
authenticate
#
Implement
the
filter
with
full
access
to
both
request
and
response
end
end
{
Learn
more
}[
link:classes
/
ActionController
/
Filters
/
ClassMethods.html
]
*
Helpers
for
forms
,
dates
,
action
links
,
and
text
...
...
@@ -124,26 +124,26 @@ A short rundown of the major features:
<
%=
html_date_select
(
Date.today
)
%
>
<
%=
link_to
"
New
post
",
:controller =
>
"post"
,
:action =
>
"new"
%
>
<
%=
truncate
(
post.title
,
:length =
>
25)
%
>
{Learn more}[link:classes/ActionView/Helpers.html]
* Layout sharing for template reuse (think simple version of Struts
* Layout sharing for template reuse (think simple version of Struts
Tiles[http://jakarta.apache.org/struts/userGuide/dev_tiles.html])
class WeblogController
<
ActionController::Base
layout
"
weblog_layout
"
def
hello_world
end
end
Layout
file
(
called
weblog_layout
)
:
<
html
><body><
%=
yield
%
></body></html>
Template for hello_world action:
<h1>
Hello world
</h1>
Result of running hello_world action:
<html><body><h1>
Hello world
</h1></body></html>
...
...
@@ -156,9 +156,9 @@ A short rundown of the major features:
Accessing /clients/37signals/basecamp/project/dash calls ProjectController#dash with
{ "client_name" => "37signals", "project_name" => "basecamp" } in params[:params]
From that URL, you can rewrite the redirect in a number of ways:
redirect_to(:action => "edit") =>
/clients/37signals/basecamp/project/dash
...
...
@@ -168,15 +168,6 @@ A short rundown of the major features:
{Learn more}[link:classes/ActionController/Base.html]
* Javascript and Ajax integration
link_to_function "Greeting", "alert('Hello world!')"
link_to_remote "Delete this post", :update => "posts",
:url => { :action => "destroy", :id => post.id }
{Learn more}[link:classes/ActionView/Helpers/JavaScriptHelper.html]
* Easy testing of both controller and rendered template through ActionController::TestCase
class LoginControllerTest
<
ActionController::TestCase
...
...
@@ -218,18 +209,18 @@ A short rundown of the major features:
class WeblogController
<
ActionController::Base
caches_page
:show
caches_action
:account
def
show
#
the
output
of
the
method
will
be
cached
as
#
the
output
of
the
method
will
be
cached
as
#
ActionController::Base.page_cache_directory
+
"/
weblog
/
show
/
n.html
"
#
and
the
web
server
will
pick
it
up
without
even
hitting
Rails
end
def
account
#
the
output
of
the
method
will
be
cached
in
the
fragment
store
#
but
Rails
is
hit
to
retrieve
it
,
so
filters
are
run
end
def
update
List.update
(
params
[
:list
][
:id
],
params
[
:list
])
expire_page
:action =
>
"show"
,
:id =
>
params[:list][:id]
...
...
@@ -256,26 +247,26 @@ A short rundown of the major features:
class
AccountController
<
ActionController::Base
scaffold
:account
end
The
AccountController
now
has
the
full
CRUD
range
of
actions
and
default
templates:
list
,
show
,
destroy
,
new
,
create
,
edit
,
update
{
Learn
more
}[
link:classes
/
ActionController
/
Scaffolding
/
ClassMethods.html
]
*
Form
building
for
Active
Record
model
objects
The
post
object
has
a
title
(
varchar
),
content
(
text
),
and
The
post
object
has
a
title
(
varchar
),
content
(
text
),
and
written_on
(
date
)
<%=
form
"
post
"
%
>
...will generate something like (the selects will have more options, of
course):
<form
action=
"create"
method=
"POST"
>
<p>
<b>
Title:
</b><br/>
<b>
Title:
</b><br/>
<input
type=
"text"
name=
"post[title]"
value=
"<%= @post.title %>"
/>
</p>
<p>
...
...
@@ -293,7 +284,7 @@ A short rundown of the major features:
</form>
This form generates a params[:post] array that can be used directly in a save action:
class WeblogController
<
ActionController::Base
def
create
post =
Post.create(params[:post])
...
...
@@ -318,19 +309,19 @@ methods:
class
WeblogController
<
ActionController::Base
layout
"
weblog
/
layout
"
def
index
@
posts =
Post.find(:all)
end
def
show
@
post =
Post.find(params[:id])
end
def
new
@
post =
Post.new
end
def
create
@
post =
Post.create(params[:post])
redirect_to
:action =
>
"show"
,
:id =
>
@post.id
...
...
@@ -364,7 +355,7 @@ And the templates look like this:
weblog/new.html.erb:
<
%=
form
"
post
"
%
>
This simple setup will list all the posts in the system on the index page,
which is called by accessing /weblog/. It uses the form builder for the Active
Record model to make the new screen, which in turn hands everything over to
...
...
@@ -379,7 +370,7 @@ The latest version of Action Pack can be found at
* http://rubyforge.org/project/showfiles.php?group_id=249
Documentation can be found at
Documentation can be found at
* http://api.rubyonrails.com
...
...
actionpack/lib/action_view/helpers/javascript_helper.rb
浏览文件 @
b3787643
...
...
@@ -41,60 +41,6 @@ module JavaScriptHelper
include
PrototypeHelper
# Returns a link of the given +name+ that will trigger a JavaScript +function+ using the
# onclick handler and return false after the fact.
#
# The first argument +name+ is used as the link text.
#
# The next arguments are optional and may include the javascript function definition and a hash of html_options.
#
# The +function+ argument can be omitted in favor of an +update_page+
# block, which evaluates to a string when the template is rendered
# (instead of making an Ajax request first).
#
# The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
#
# Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
#
#
# Examples:
# link_to_function "Greeting", "alert('Hello world!')"
# Produces:
# <a onclick="alert('Hello world!'); return false;" href="#">Greeting</a>
#
# link_to_function(image_tag("delete"), "if (confirm('Really?')) do_delete()")
# Produces:
# <a onclick="if (confirm('Really?')) do_delete(); return false;" href="#">
# <img src="/images/delete.png?" alt="Delete"/>
# </a>
#
# link_to_function("Show me more", nil, :id => "more_link") do |page|
# page[:details].visual_effect :toggle_blind
# page[:more_link].replace_html "Show me less"
# end
# Produces:
# <a href="#" id="more_link" onclick="try {
# $("details").visualEffect("toggle_blind");
# $("more_link").update("Show me less");
# }
# catch (e) {
# alert('RJS error:\n\n' + e.toString());
# alert('$(\"details\").visualEffect(\"toggle_blind\");
# \n$(\"more_link\").update(\"Show me less\");');
# throw e
# };
# return false;">Show me more</a>
#
def
link_to_function
(
name
,
*
args
,
&
block
)
html_options
=
args
.
extract_options!
.
symbolize_keys
function
=
block_given?
?
update_page
(
&
block
)
:
args
[
0
]
||
''
onclick
=
"
#{
"
#{
html_options
[
:onclick
]
}
; "
if
html_options
[
:onclick
]
}#{
function
}
; return false;"
href
=
html_options
[
:href
]
||
'#'
content_tag
(
:a
,
name
,
html_options
.
merge
(
:href
=>
href
,
:onclick
=>
onclick
))
end
# Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the
# onclick handler.
#
...
...
actionpack/lib/action_view/helpers/prototype_helper.rb
浏览文件 @
b3787643
...
...
@@ -102,147 +102,6 @@ module PrototypeHelper
:form
,
:with
,
:update
,
:script
,
:type
]).
merge
(
CALLBACKS
)
end
# Returns a link to a remote action defined by <tt>options[:url]</tt>
# (using the url_for format) that's called in the background using
# XMLHttpRequest. The result of that request can then be inserted into a
# DOM object whose id can be specified with <tt>options[:update]</tt>.
# Usually, the result would be a partial prepared by the controller with
# render :partial.
#
# Examples:
# # Generates: <a href="#" onclick="new Ajax.Updater('posts', '/blog/destroy/3', {asynchronous:true, evalScripts:true});
# # return false;">Delete this post</a>
# link_to_remote "Delete this post", :update => "posts",
# :url => { :action => "destroy", :id => post.id }
#
# # Generates: <a href="#" onclick="new Ajax.Updater('emails', '/mail/list_emails', {asynchronous:true, evalScripts:true});
# # return false;"><img alt="Refresh" src="/images/refresh.png?" /></a>
# link_to_remote(image_tag("refresh"), :update => "emails",
# :url => { :action => "list_emails" })
#
# You can override the generated HTML options by specifying a hash in
# <tt>options[:html]</tt>.
#
# link_to_remote "Delete this post", :update => "posts",
# :url => post_url(@post), :method => :delete,
# :html => { :class => "destructive" }
#
# You can also specify a hash for <tt>options[:update]</tt> to allow for
# easy redirection of output to an other DOM element if a server-side
# error occurs:
#
# Example:
# # Generates: <a href="#" onclick="new Ajax.Updater({success:'posts',failure:'error'}, '/blog/destroy/5',
# # {asynchronous:true, evalScripts:true}); return false;">Delete this post</a>
# link_to_remote "Delete this post",
# :url => { :action => "destroy", :id => post.id },
# :update => { :success => "posts", :failure => "error" }
#
# Optionally, you can use the <tt>options[:position]</tt> parameter to
# influence how the target DOM element is updated. It must be one of
# <tt>:before</tt>, <tt>:top</tt>, <tt>:bottom</tt>, or <tt>:after</tt>.
#
# The method used is by default POST. You can also specify GET or you
# can simulate PUT or DELETE over POST. All specified with <tt>options[:method]</tt>
#
# Example:
# # Generates: <a href="#" onclick="new Ajax.Request('/person/4', {asynchronous:true, evalScripts:true, method:'delete'});
# # return false;">Destroy</a>
# link_to_remote "Destroy", :url => person_url(:id => person), :method => :delete
#
# By default, these remote requests are processed asynchronous during
# which various JavaScript callbacks can be triggered (for progress
# indicators and the likes). All callbacks get access to the
# <tt>request</tt> object, which holds the underlying XMLHttpRequest.
#
# To access the server response, use <tt>request.responseText</tt>, to
# find out the HTTP status, use <tt>request.status</tt>.
#
# Example:
# # Generates: <a href="#" onclick="new Ajax.Request('/words/undo?n=33', {asynchronous:true, evalScripts:true,
# # onComplete:function(request){undoRequestCompleted(request)}}); return false;">hello</a>
# word = 'hello'
# link_to_remote word,
# :url => { :action => "undo", :n => word_counter },
# :complete => "undoRequestCompleted(request)"
#
# The callbacks that may be specified are (in order):
#
# <tt>:loading</tt>:: Called when the remote document is being
# loaded with data by the browser.
# <tt>:loaded</tt>:: Called when the browser has finished loading
# the remote document.
# <tt>:interactive</tt>:: Called when the user can interact with the
# remote document, even though it has not
# finished loading.
# <tt>:success</tt>:: Called when the XMLHttpRequest is completed,
# and the HTTP status code is in the 2XX range.
# <tt>:failure</tt>:: Called when the XMLHttpRequest is completed,
# and the HTTP status code is not in the 2XX
# range.
# <tt>:complete</tt>:: Called when the XMLHttpRequest is complete
# (fires after success/failure if they are
# present).
#
# You can further refine <tt>:success</tt> and <tt>:failure</tt> by
# adding additional callbacks for specific status codes.
#
# Example:
# # Generates: <a href="#" onclick="new Ajax.Request('/testing/action', {asynchronous:true, evalScripts:true,
# # on404:function(request){alert('Not found...? Wrong URL...?')},
# # onFailure:function(request){alert('HTTP Error ' + request.status + '!')}}); return false;">hello</a>
# link_to_remote word,
# :url => { :action => "action" },
# 404 => "alert('Not found...? Wrong URL...?')",
# :failure => "alert('HTTP Error ' + request.status + '!')"
#
# A status code callback overrides the success/failure handlers if
# present.
#
# If you for some reason or another need synchronous processing (that'll
# block the browser while the request is happening), you can specify
# <tt>options[:type] = :synchronous</tt>.
#
# You can customize further browser side call logic by passing in
# JavaScript code snippets via some optional parameters. In their order
# of use these are:
#
# <tt>:confirm</tt>:: Adds confirmation dialog.
# <tt>:condition</tt>:: Perform remote request conditionally
# by this expression. Use this to
# describe browser-side conditions when
# request should not be initiated.
# <tt>:before</tt>:: Called before request is initiated.
# <tt>:after</tt>:: Called immediately after request was
# initiated and before <tt>:loading</tt>.
# <tt>:submit</tt>:: Specifies the DOM element ID that's used
# as the parent of the form elements. By
# default this is the current form, but
# it could just as well be the ID of a
# table row or any other DOM element.
# <tt>:with</tt>:: A JavaScript expression specifying
# the parameters for the XMLHttpRequest.
# Any expressions should return a valid
# URL query string.
#
# Example:
#
# :with => "'name=' + $('name').value"
#
# You can generate a link that uses AJAX in the general case, while
# degrading gracefully to plain link behavior in the absence of
# JavaScript by setting <tt>html_options[:href]</tt> to an alternate URL.
# Note the extra curly braces around the <tt>options</tt> hash separate
# it as the second parameter from <tt>html_options</tt>, the third.
#
# Example:
# link_to_remote "Delete this post",
# { :update => "posts", :url => { :action => "destroy", :id => post.id } },
# :href => url_for(:action => "destroy", :id => post.id)
def
link_to_remote
(
name
,
options
=
{},
html_options
=
nil
)
link_to_function
(
name
,
remote_function
(
options
),
html_options
||
options
.
delete
(
:html
))
end
# Creates a button with an onclick event which calls a remote action
# via XMLHttpRequest
# The options for specifying the target with :url
...
...
actionpack/lib/action_view/helpers/scriptaculous_helper.rb
浏览文件 @
b3787643
...
...
@@ -3,11 +3,11 @@
module
ActionView
module
Helpers
# Provides a set of helpers for calling Scriptaculous JavaScript
# Provides a set of helpers for calling Scriptaculous JavaScript
# functions, including those which create Ajax controls and visual effects.
#
# To be able to use these helpers, you must include the Prototype
# JavaScript framework and the Scriptaculous JavaScript library in your
# To be able to use these helpers, you must include the Prototype
# JavaScript framework and the Scriptaculous JavaScript library in your
# pages. See the documentation for ActionView::Helpers::JavaScriptHelper
# for more information on including the necessary JavaScript.
#
...
...
@@ -18,22 +18,17 @@ module ScriptaculousHelper
unless
const_defined?
:TOGGLE_EFFECTS
TOGGLE_EFFECTS
=
[
:toggle_appear
,
:toggle_slide
,
:toggle_blind
]
end
# Returns a JavaScript snippet to be used on the Ajax callbacks for
# starting visual effects.
#
# Example:
# <%= link_to_remote "Reload", :update => "posts",
# :url => { :action => "reload" },
# :complete => visual_effect(:highlight, "posts", :duration => 0.5)
#
# If no +element_id+ is given, it assumes "element" which should be a local
# variable in the generated JavaScript execution context. This can be
# variable in the generated JavaScript execution context. This can be
# used for example with +drop_receiving_element+:
#
# <%= drop_receiving_element (...), :loading => visual_effect(:fade) %>
#
# This would fade the element that was dropped on the drop receiving
# This would fade the element that was dropped on the drop receiving
# element.
#
# For toggling visual effects, you can use <tt>:toggle_appear</tt>, <tt>:toggle_slide</tt>, and
...
...
@@ -44,13 +39,13 @@ module ScriptaculousHelper
# http://script.aculo.us for more documentation.
def
visual_effect
(
name
,
element_id
=
false
,
js_options
=
{})
element
=
element_id
?
ActiveSupport
::
JSON
.
encode
(
element_id
)
:
"element"
js_options
[
:queue
]
=
if
js_options
[
:queue
].
is_a?
(
Hash
)
'{'
+
js_options
[
:queue
].
map
{
|
k
,
v
|
k
==
:limit
?
"
#{
k
}
:
#{
v
}
"
:
"
#{
k
}
:'
#{
v
}
'"
}.
join
(
','
)
+
'}'
elsif
js_options
[
:queue
]
"'
#{
js_options
[
:queue
]
}
'"
end
if
js_options
[
:queue
]
[
:endcolor
,
:direction
,
:startcolor
,
:scaleMode
,
:restorecolor
].
each
do
|
option
|
js_options
[
option
]
=
"'
#{
js_options
[
option
]
}
'"
if
js_options
[
option
]
end
...
...
@@ -61,7 +56,7 @@ def visual_effect(name, element_id = false, js_options = {})
"new Effect.
#{
name
.
to_s
.
camelize
}
(
#{
element
}
,
#{
options_for_javascript
(
js_options
)
}
);"
end
end
# Makes the element with the DOM ID specified by +element_id+ sortable
# by drag-and-drop and make an Ajax call whenever the sort order has
# changed. By default, the action called gets the serialized sortable
...
...
@@ -71,84 +66,84 @@ def visual_effect(name, element_id = false, js_options = {})
#
# <%= sortable_element("my_list", :url => { :action => "order" }) %>
#
# In the example, the action gets a "my_list" array parameter
# containing the values of the ids of elements the sortable consists
# In the example, the action gets a "my_list" array parameter
# containing the values of the ids of elements the sortable consists
# of, in the current order.
#
# Important: For this to work, the sortable elements must have id
# attributes in the form "string_identifier". For example, "item_1". Only
# the identifier part of the id attribute will be serialized.
#
#
# Additional +options+ are:
#
# * <tt>:format</tt> - A regular expression to determine what to send as the
# serialized id to the server (the default is <tt>/^[^_]*_(.*)$/</tt>).
#
#
# * <tt>:constraint</tt> - Whether to constrain the dragging to either
# <tt>:horizontal</tt> or <tt>:vertical</tt> (or false to make it unconstrained).
#
#
# * <tt>:overlap</tt> - Calculate the item overlap in the <tt>:horizontal</tt>
# or <tt>:vertical</tt> direction.
#
#
# * <tt>:tag</tt> - Which children of the container element to treat as
# sortable (default is <tt>li</tt>).
#
#
# * <tt>:containment</tt> - Takes an element or array of elements to treat as
# potential drop targets (defaults to the original target element).
#
#
# * <tt>:only</tt> - A CSS class name or array of class names used to filter
# out child elements as candidates.
#
#
# * <tt>:scroll</tt> - Determines whether to scroll the list during drag
# operations if the list runs past the visual border.
#
#
# * <tt>:tree</tt> - Determines whether to treat nested lists as part of the
# main sortable list. This means that you can create multi-layer lists,
# and not only sort items at the same level, but drag and sort items
# between levels.
#
#
# * <tt>:hoverclass</tt> - If set, the Droppable will have this additional CSS class
# when an accepted Draggable is hovered over it.
#
# when an accepted Draggable is hovered over it.
#
# * <tt>:handle</tt> - Sets whether the element should only be draggable by an
# embedded handle. The value may be a string referencing a CSS class value
# (as of script.aculo.us V1.5). The first child/grandchild/etc. element
# found within the element that has this CSS class value will be used as
# the handle.
#
#
# * <tt>:ghosting</tt> - Clones the element and drags the clone, leaving
# the original in place until the clone is dropped (default is <tt>false</tt>).
#
#
# * <tt>:dropOnEmpty</tt> - If true the Sortable container will be made into
# a Droppable, that can receive a Draggable (as according to the containment
# rules) as a child element when there are no more elements inside (default
# is <tt>false</tt>).
#
#
# * <tt>:onChange</tt> - Called whenever the sort order changes while dragging. When
# dragging from one Sortable to another, the callback is called once on each
# Sortable. Gets the affected element as its parameter.
#
#
# * <tt>:onUpdate</tt> - Called when the drag ends and the Sortable's order is
# changed in any way. When dragging from one Sortable to another, the callback
# is called once on each Sortable. Gets the container as its parameter.
#
#
# See http://script.aculo.us for more documentation.
def
sortable_element
(
element_id
,
options
=
{})
javascript_tag
(
sortable_element_js
(
element_id
,
options
).
chop!
)
end
def
sortable_element_js
(
element_id
,
options
=
{})
#:nodoc:
options
[
:with
]
||=
"Sortable.serialize(
#{
ActiveSupport
::
JSON
.
encode
(
element_id
)
}
)"
options
[
:onUpdate
]
||=
"function(){"
+
remote_function
(
options
)
+
"}"
options
.
delete_if
{
|
key
,
value
|
PrototypeHelper
::
AJAX_OPTIONS
.
include?
(
key
)
}
[
:tag
,
:overlap
,
:constraint
,
:handle
].
each
do
|
option
|
options
[
option
]
=
"'
#{
options
[
option
]
}
'"
if
options
[
option
]
end
options
[
:containment
]
=
array_or_string_for_javascript
(
options
[
:containment
])
if
options
[
:containment
]
options
[
:only
]
=
array_or_string_for_javascript
(
options
[
:only
])
if
options
[
:only
]
%(Sortable.create(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});)
end
...
...
@@ -156,24 +151,24 @@ def sortable_element_js(element_id, options = {}) #:nodoc:
#
# Example:
# <%= draggable_element("my_image", :revert => true)
#
#
# You can change the behaviour with various options, see
# http://script.aculo.us for more documentation.
def
draggable_element
(
element_id
,
options
=
{})
javascript_tag
(
draggable_element_js
(
element_id
,
options
).
chop!
)
end
def
draggable_element_js
(
element_id
,
options
=
{})
#:nodoc:
%(new Draggable(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});)
end
# Makes the element with the DOM ID specified by +element_id+ receive
# dropped draggable elements (created by +draggable_element+).
# and make an AJAX call. By default, the action called gets the DOM ID
# and make an AJAX call. By default, the action called gets the DOM ID
# of the element as parameter.
#
# Example:
# <%= drop_receiving_element("my_cart", :url =>
# <%= drop_receiving_element("my_cart", :url =>
# { :controller => "cart", :action => "add" }) %>
#
# You can change the behaviour with various options, see
...
...
@@ -181,41 +176,41 @@ def draggable_element_js(element_id, options = {}) #:nodoc:
#
# Some of these +options+ include:
# * <tt>:accept</tt> - Set this to a string or an array of strings describing the
# allowable CSS classes that the +draggable_element+ must have in order
# allowable CSS classes that the +draggable_element+ must have in order
# to be accepted by this +drop_receiving_element+.
#
#
# * <tt>:confirm</tt> - Adds a confirmation dialog. Example:
#
#
# :confirm => "Are you sure you want to do this?"
#
#
# * <tt>:hoverclass</tt> - If set, the +drop_receiving_element+ will have
# this additional CSS class when an accepted +draggable_element+ is
# hovered over it.
#
# hovered over it.
#
# * <tt>:onDrop</tt> - Called when a +draggable_element+ is dropped onto
# this element. Override this callback with a JavaScript expression to
# this element. Override this callback with a JavaScript expression to
# change the default drop behaviour. Example:
#
#
# :onDrop => "function(draggable_element, droppable_element, event) { alert('I like bananas') }"
#
#
# This callback gets three parameters: The Draggable element, the Droppable
# element and the Event object. You can extract additional information about
# the drop - like if the Ctrl or Shift keys were pressed - from the Event object.
#
#
# * <tt>:with</tt> - A JavaScript expression specifying the parameters for
# the XMLHttpRequest. Any expressions should return a valid URL query string.
def
drop_receiving_element
(
element_id
,
options
=
{})
javascript_tag
(
drop_receiving_element_js
(
element_id
,
options
).
chop!
)
end
def
drop_receiving_element_js
(
element_id
,
options
=
{})
#:nodoc:
options
[
:with
]
||=
"'id=' + encodeURIComponent(element.id)"
options
[
:onDrop
]
||=
"function(element){"
+
remote_function
(
options
)
+
"}"
options
.
delete_if
{
|
key
,
value
|
PrototypeHelper
::
AJAX_OPTIONS
.
include?
(
key
)
}
options
[
:accept
]
=
array_or_string_for_javascript
(
options
[
:accept
])
if
options
[
:accept
]
options
[
:accept
]
=
array_or_string_for_javascript
(
options
[
:accept
])
if
options
[
:accept
]
options
[
:hoverclass
]
=
"'
#{
options
[
:hoverclass
]
}
'"
if
options
[
:hoverclass
]
# Confirmation happens during the onDrop callback, so it can be removed from the options
options
.
delete
(
:confirm
)
if
options
[
:confirm
]
...
...
actionpack/test/template/javascript_helper_test.rb
浏览文件 @
b3787643
...
...
@@ -30,35 +30,6 @@ def test_escape_javascript
assert_equal
%(dont <
\\
/close> tags)
,
escape_javascript
(
%(dont </close> tags)
)
end
def
test_link_to_function
assert_dom_equal
%(<a href="#" onclick="alert('Hello world!'); return false;">Greeting</a>)
,
link_to_function
(
"Greeting"
,
"alert('Hello world!')"
)
end
def
test_link_to_function_with_existing_onclick
assert_dom_equal
%(<a href="#" onclick="confirm('Sanity!'); alert('Hello world!'); return false;">Greeting</a>)
,
link_to_function
(
"Greeting"
,
"alert('Hello world!')"
,
:onclick
=>
"confirm('Sanity!')"
)
end
def
test_link_to_function_with_rjs_block
html
=
link_to_function
(
"Greet me!"
)
do
|
page
|
page
.
replace_html
'header'
,
"<h1>Greetings</h1>"
end
assert_dom_equal
%(<a href="#" onclick="Element.update("header", "
\\
u003Ch1
\\
u003EGreetings
\\
u003C/h1
\\
u003E");; return false;">Greet me!</a>)
,
html
end
def
test_link_to_function_with_rjs_block_and_options
html
=
link_to_function
(
"Greet me!"
,
:class
=>
"updater"
)
do
|
page
|
page
.
replace_html
'header'
,
"<h1>Greetings</h1>"
end
assert_dom_equal
%(<a href="#" class="updater" onclick="Element.update("header", "
\\
u003Ch1
\\
u003EGreetings
\\
u003C/h1
\\
u003E");; return false;">Greet me!</a>)
,
html
end
def
test_link_to_function_with_href
assert_dom_equal
%(<a href="http://example.com/" onclick="alert('Hello world!'); return false;">Greeting</a>)
,
link_to_function
(
"Greeting"
,
"alert('Hello world!')"
,
:href
=>
'http://example.com/'
)
end
def
test_button_to_function
assert_dom_equal
%(<input type="button" onclick="alert('Hello world!');" value="Greeting" />)
,
button_to_function
(
"Greeting"
,
"alert('Hello world!')"
)
...
...
actionpack/test/template/prototype_helper_test.rb
浏览文件 @
b3787643
...
...
@@ -82,33 +82,6 @@ def setup
super
end
def
test_link_to_remote
assert_dom_equal
%(<a class=\"fine\" href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true}); return false;\">Remote outauthor</a>)
,
link_to_remote
(
"Remote outauthor"
,
{
:url
=>
{
:action
=>
"whatnot"
}},
{
:class
=>
"fine"
})
assert_dom_equal
%(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onComplete:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>)
,
link_to_remote
(
"Remote outauthor"
,
:complete
=>
"alert(request.responseText)"
,
:url
=>
{
:action
=>
"whatnot"
})
assert_dom_equal
%(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onSuccess:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>)
,
link_to_remote
(
"Remote outauthor"
,
:success
=>
"alert(request.responseText)"
,
:url
=>
{
:action
=>
"whatnot"
})
assert_dom_equal
%(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>)
,
link_to_remote
(
"Remote outauthor"
,
:failure
=>
"alert(request.responseText)"
,
:url
=>
{
:action
=>
"whatnot"
})
assert_dom_equal
%(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot?a=10&b=20', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>)
,
link_to_remote
(
"Remote outauthor"
,
:failure
=>
"alert(request.responseText)"
,
:url
=>
{
:action
=>
"whatnot"
,
:a
=>
'10'
,
:b
=>
'20'
})
assert_dom_equal
%(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:false, evalScripts:true}); return false;\">Remote outauthor</a>)
,
link_to_remote
(
"Remote outauthor"
,
:url
=>
{
:action
=>
"whatnot"
},
:type
=>
:synchronous
)
assert_dom_equal
%(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, insertion:'bottom'}); return false;\">Remote outauthor</a>)
,
link_to_remote
(
"Remote outauthor"
,
:url
=>
{
:action
=>
"whatnot"
},
:position
=>
:bottom
)
end
def
test_link_to_remote_html_options
assert_dom_equal
%(<a class=\"fine\" href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true}); return false;\">Remote outauthor</a>)
,
link_to_remote
(
"Remote outauthor"
,
{
:url
=>
{
:action
=>
"whatnot"
},
:html
=>
{
:class
=>
"fine"
}
})
end
def
test_link_to_remote_url_quote_escaping
assert_dom_equal
%(<a href="#" onclick="new Ajax.Request('http://www.example.com/whatnot
\\
\'s', {asynchronous:true, evalScripts:true}); return false;">Remote</a>)
,
link_to_remote
(
"Remote"
,
{
:url
=>
{
:action
=>
"whatnot's"
}
})
end
def
test_button_to_remote
assert_dom_equal
%(<input class=\"fine\" type=\"button\" value=\"Remote outpost\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true});\" />)
,
button_to_remote
(
"Remote outpost"
,
{
:url
=>
{
:action
=>
"whatnot"
}},
{
:class
=>
"fine"
})
...
...
@@ -610,4 +583,3 @@ def test_class_proxy_call_with_block
assert_equal
"MyObject.myMethod(function() { $(
\"
one
\"
).show();
\n
$(
\"
two
\"
).hide(); });"
,
@generator
.
to_s
end
end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录