aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-03-12 02:42:48 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-03-12 02:42:48 +0000
commit7ae83e5ff0a1083aecc7e39e3ca0236401f35918 (patch)
tree858af84e9989b03baa2b24d0a6b740a9cbe4ec9d /actionpack/lib
parent971c4e61c2871d92c027a3cf5cbd9a5421499291 (diff)
downloadrails-7ae83e5ff0a1083aecc7e39e3ca0236401f35918.tar.gz
rails-7ae83e5ff0a1083aecc7e39e3ca0236401f35918.tar.bz2
rails-7ae83e5ff0a1083aecc7e39e3ca0236401f35918.zip
Added first stab at Javascript/Ajax helpers
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@888 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb160
1 files changed, 160 insertions, 0 deletions
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
new file mode 100644
index 0000000000..20c2a9cf63
--- /dev/null
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -0,0 +1,160 @@
+require File.dirname(__FILE__) + '/tag_helper'
+
+# You must call <%= define_javascript_functions %> in your application before using these helpers.
+module JavascriptTagHelper
+ def link_to_display_toggle(name, tags, html_options = {})
+ toggle_functions = [ tags ].flatten.collect { |tag| "toggle_display_by_id('#{tag}'); " }.join
+ content_tag(
+ "a", name,
+ html_options.symbolize_keys.merge(:href => "#", :onclick => "#{toggle_functions}; #{html_options['onclick']}; return false;")
+ )
+ end
+
+ def link_to_function(name, function, html_options = {})
+ content_tag(
+ "a", name,
+ html_options.symbolize_keys.merge(:href => "#", :onclick => "#{function}; return false;")
+ )
+ end
+
+ def link_to_remote(name, options = {})
+ link_to_function(name, remote_function(options))
+ end
+
+ def form_remote_tag(options = {})
+ options[:form] = true
+
+ options[:html] ||= { }
+ options[:html][:onsubmit] = "#{remote_function(options)}; return false;"
+
+ tag("form", options[:html], true)
+ end
+
+ def define_javascript_functions
+<<-EOF
+<script language="JavaScript">
+/* XMLHttpRequest Methods */
+
+function update_with_response() {
+ o(arguments[0]).innerHTML = xml_request(arguments[1], arguments[2]);
+}
+
+function xml_request() {
+ var url = arguments[0];
+ var parameters = arguments[1];
+ var async = arguments[2];
+ var type = parameters ? "POST" : "GET";
+
+ req = xml_http_request_object();
+ req.open(type, url, async);
+ req.send(parameters);
+
+ return req.responseText;
+}
+
+function xml_http_request_object() {
+ var req = false;
+ try {
+ req = new ActiveXObject("Msxml2.XMLHTTP");
+ } catch (e) {
+ try {
+ req = new ActiveXObject("Microsoft.XMLHTTP");
+ } catch (E) {
+ req = false;
+ }
+ }
+
+ if (!req && typeof XMLHttpRequest!='undefined') {
+ req = new XMLHttpRequest();
+ }
+
+ return req;
+}
+
+
+/* Common methods ------------------------------ */
+
+function toggle_display_by_id(id) {
+ o(id).style.display = (o(id).style.display == "none") ? "" : "none";
+}
+
+function o(id) {
+ return document.getElementById(id);
+}
+
+
+/* Serialize a form by Sam Stephenson ------------------------------ */
+
+Form = {
+ Serializers: {
+ input: function(element) {
+ switch (element.type.toLowerCase()) {
+ case 'hidden':
+ case 'text':
+ return Form.Serializers.textarea(element);
+ case 'checkbox':
+ case 'radio':
+ return Form.Serializers.inputSelector(element);
+ }
+ },
+
+ inputSelector: function(element) {
+ if (element.checked)
+ return [element.name, element.value];
+ },
+
+ textarea: function(element) {
+ return [element.name, element.value];
+ },
+
+ select: function(element) {
+ var index = element.selectedIndex;
+ return [element.name, element.options[index].value];
+ }
+ },
+
+ serialize: function(form) {
+ var elements = Form.getFormElements(form);
+ var queryComponents = new Array();
+
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ var method = element.tagName.toLowerCase();
+
+ var parameter = Form.Serializers[method](element);
+ if (parameter) {
+ var queryComponent = encodeURIComponent(parameter[0]) + '=' +
+ encodeURIComponent(parameter[1]);
+ queryComponents.push(queryComponent);
+ }
+ }
+
+ return queryComponents.join('&');
+ },
+
+ getFormElements: function(form) {
+ var elements = new Array();
+ for (tagName in Form.Serializers) {
+ var tagElements = form.getElementsByTagName(tagName);
+ for (var j = 0; j < tagElements.length; j++)
+ elements.push(tagElements[j]);
+ }
+ return elements;
+ }
+}
+</script>
+EOF
+ end
+
+ private
+ def remote_function(options)
+ function = options[:update] ?
+ "update_with_response('#{options[:update]}', '#{url_for(options[:url])}'#{', Form.serialize(this)' if options[:form]})" :
+ "xml_request('#{url_for(options[:url])}'#{', Form.serialize(this)' if options[:form]})"
+
+ function = "#{options[:before]};#{function}" if options[:before]
+ function = "#{function};#{options[:after]}" if options[:after]
+
+ return function
+ end
+end \ No newline at end of file