From 4b3ba0dd6a8dcba6a5b5fdc830079a9bba21d478 Mon Sep 17 00:00:00 2001 From: lukemelia Date: Mon, 3 Dec 2007 03:24:05 +0000 Subject: [PATCH] AJAX spinners are now contextual instead of in the same place on every Ajax request. git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@668 a4c988fc-2ded-0310-b66e-134b36920a42 --- tracks/app/helpers/todos_helper.rb | 30 ++++---- tracks/app/views/contexts/_context_form.rhtml | 11 ++- .../app/views/contexts/_context_listing.rhtml | 16 ++--- .../app/views/projects/_project_listing.rhtml | 23 ++++--- .../views/projects/_project_state_group.rhtml | 12 ++-- tracks/config/environment.rb.tmpl | 1 + tracks/lib/prototype_helper_extensions.rb | 27 ++++++++ tracks/public/javascripts/application.js | 15 +--- .../unit/prototype_helper_extensions_test.rb | 68 +++++++++++++++++++ .../lib/synthesis/asset_package_helper.rb | 4 +- 10 files changed, 148 insertions(+), 59 deletions(-) create mode 100644 tracks/lib/prototype_helper_extensions.rb create mode 100644 tracks/test/unit/prototype_helper_extensions_test.rb diff --git a/tracks/app/helpers/todos_helper.rb b/tracks/app/helpers/todos_helper.rb index 23139eb1..e342aea7 100644 --- a/tracks/app/helpers/todos_helper.rb +++ b/tracks/app/helpers/todos_helper.rb @@ -14,12 +14,12 @@ module TodosHelper :id => dom_id(@todo, 'form'), :class => dom_id(@todo, 'form') + " inline-form edit_todo_form" }, &block ) - apply_behavior 'form.'+dom_id(@todo, 'form'), make_remote_form( - :method => :put, - :before => "$('" + dom_id(@todo, 'submit') + "').startWaiting()", - :loaded => "$('" + dom_id(@todo, 'submit') + "').stopWaiting()", - :condition => "!$('" + dom_id(@todo, 'submit') + "').isWaiting()"), - :prevent_default => true + apply_behavior 'form.edit_todo_form', make_remote_form( + :method => :put, + :before => "this.down('button.positive').startWaiting()", + :loaded => "this.down('button.positive').stopWaiting()", + :condition => "!(this.down('button.positive').isWaiting())"), + :prevent_default => true end def remote_delete_icon @@ -27,9 +27,10 @@ module TodosHelper todo_path(@todo), :class => "icon delete_icon", :title => "delete the action '#{@todo.description}'") apply_behavior '.item-container a.delete_icon:click', :prevent_default => true do |page| - page << "if (confirm('Are you sure that you want to ' + this.title + '?')) {" - page << " new Ajax.Request(this.href, { asynchronous : true, evalScripts : true, method : 'delete', parameters : { '_source_view' : '#{@source_view}' }})" - page << "}" + page.confirming "'Are you sure that you want to ' + this.title + '?'" do + page << "itemContainer = this.up('.item-container'); itemContainer.startWaiting();" + page << remote_to_href(:method => 'delete', :with => "{ '_source_view' : '#{@source_view}' }", :complete => "itemContainer.stopWaiting();") + end end str end @@ -39,10 +40,9 @@ module TodosHelper toggle_star_todo_path(@todo), :class => "icon star_item", :title => "star the action '#{@todo.description}'") apply_behavior '.item-container a.star_item:click', - remote_function(:url => javascript_variable('this.href'), :method => 'put', - :with => "{ _source_view : '#{@source_view}' }"), + remote_to_href(:method => 'put', :with => "{ _source_view : '#{@source_view}' }"), :prevent_default => true - str + str end def remote_edit_icon @@ -51,7 +51,8 @@ module TodosHelper edit_todo_path(@todo), :class => "icon edit_icon") apply_behavior '.item-container a.edit_icon:click', :prevent_default => true do |page| - page << "new Ajax.Request(this.href, { asynchronous : true, evalScripts : true, method : 'get', parameters : { '_source_view' : '#{@source_view}' }, onLoading: function(request){ Effect.Pulsate(this)}});" + page << "Effect.Pulsate(this);" + page << remote_to_href(:method => 'get', :with => "{ _source_view : '#{@source_view}' }") end else str = '' + image_tag("blank.png") + " " @@ -62,8 +63,7 @@ module TodosHelper def remote_toggle_checkbox str = check_box_tag('item_id', toggle_check_todo_path(@todo), @todo.completed?, :class => 'item-checkbox') apply_behavior '.item-container input.item-checkbox:click', - remote_function(:url => javascript_variable('this.value'), :method => 'put', - :with => "{ _source_view : '#{@source_view}' }") + remote_to_href(:method => 'put', :with => "{ _source_view : '#{@source_view}' }") str end diff --git a/tracks/app/views/contexts/_context_form.rhtml b/tracks/app/views/contexts/_context_form.rhtml index 2db8edeb..68e3dde0 100644 --- a/tracks/app/views/contexts/_context_form.rhtml +++ b/tracks/app/views/contexts/_context_form.rhtml @@ -1,7 +1,7 @@ <% context = context_form @context = context-%> diff --git a/tracks/app/views/contexts/_context_listing.rhtml b/tracks/app/views/contexts/_context_listing.rhtml index 7f433acd..03ad73f3 100644 --- a/tracks/app/views/contexts/_context_listing.rhtml +++ b/tracks/app/views/contexts/_context_listing.rhtml @@ -15,10 +15,11 @@ VISIBLE <% end %> <%= image_tag( "blank.png", :title => "Delete context", :class=>"delete_item") %> - <%= apply_behavior "a.delete_context_button:click", { :prevent_default => true, :external => true} do |page| - page << "if (confirm('Are you sure that you want to ' + this.title + '?')) {" - page << " new Ajax.Request(this.href, {asynchronous:true," - page << " evalScripts:true, method:'delete'}); };" + <%= apply_behavior "a.delete_context_button:click", { :prevent_default => true, :external => true} do |page, element| + page.confirming "'Are you sure that you want to ' + this.title + '?'" do + element.up('.context').start_waiting + page << remote_to_href(:method => 'delete') + end end -%> <%= image_tag( "blank.png", :title => "Edit context", :class=>"edit_item") %> <%= apply_behavior 'a.edit_context_button:click', :prevent_default => true do |page, element| @@ -32,9 +33,4 @@ <%= render :partial => 'context_form', :object => context %> - -<% if controller.action_name == 'create' %> - -<% end %> + \ No newline at end of file diff --git a/tracks/app/views/projects/_project_listing.rhtml b/tracks/app/views/projects/_project_listing.rhtml index 852e2bcd..dfe0dd41 100644 --- a/tracks/app/views/projects/_project_listing.rhtml +++ b/tracks/app/views/projects/_project_listing.rhtml @@ -11,17 +11,22 @@
<%= project.current_state.to_s.upcase %> - <%= image_tag( "blank.png", :title => "Delete project", :class=>"delete_item") %> - <%= apply_behavior "a.delete_project_button:click", { :prevent_default => true, :external => true} do |page| - page << "if (confirm('Are you sure that you want to ' + this.title + '?')) {" - page << " new Ajax.Request(this.href, {asynchronous:true," - page << " evalScripts:true, method:'delete'}); };" + <%= image_tag( "blank.png", + :title => "Delete project", + :class=>"delete_item") %> + <%= apply_behavior "a.delete_project_button:click", { :prevent_default => true, :external => true } do |page, element| + page.confirming "'Are you sure that you want to ' + this.title + '?'" do + element.up('.project').start_waiting + page << remote_to_href(:method => 'delete') + end end -%> <%= image_tag( "blank.png", :title => "Edit project", :class=>"edit_item") %> - <%= apply_behavior "a.edit_project_button:click", { :prevent_default => true, :external => true} do |page| - page << " this.up('.project').startWaiting();" - page << " new Ajax.Request( this.href, {asynchronous:true, evalScripts:true, method:'get'});" - end + <%= apply_behavior 'a.edit_project_button:click', { :prevent_default => true, :external => true } do |page, element| + element.up('div.project').start_waiting + page << remote_to_href(:method => 'get') + end -%>
diff --git a/tracks/app/views/projects/_project_state_group.rhtml b/tracks/app/views/projects/_project_state_group.rhtml index 9a82bb28..6fe6ef21 100644 --- a/tracks/app/views/projects/_project_state_group.rhtml +++ b/tracks/app/views/projects/_project_state_group.rhtml @@ -3,14 +3,16 @@
<%= link_to("Sort Alphabetically", alphabetize_projects_path(:state => state), :class => "alphabetize_link", :title => "Sort these projects alphabetically") %> - <% apply_behavior '.alphabetize_link:click', :prevent_default => true do |page| - page << "if (confirm('Are you sure that you want to sort these projects alphabetically? This will replace the existing sort order.')) {" - page << " new Ajax.Request(this.href, { asynchronous : true, evalScripts : true, method : 'post' })" - page << "}" + <% apply_behavior '.alphabetize_link:click', :prevent_default => true do |page, element| + page.confirming 'Are you sure that you want to sort these projects alphabetically? This will replace the existing sort order.' do + page << "alphaSort = this.up('.alpha_sort'); + alphaSort.startWaiting();" + page << remote_to_href(:complete => "alphaSort.stopWaiting()") + end end %>
-
+
<%= render :partial => 'project_listing', :collection => project_state_group %>
<%= sortable_element "list-#{state}-projects", get_listing_sortable_options("list-#{state}-projects") %> diff --git a/tracks/config/environment.rb.tmpl b/tracks/config/environment.rb.tmpl index 2e85c77b..462443f9 100644 --- a/tracks/config/environment.rb.tmpl +++ b/tracks/config/environment.rb.tmpl @@ -67,6 +67,7 @@ require 'todo_list' require 'config' require 'activerecord_base_tag_extensions' # Needed for tagging-specific extensions require 'digest/sha1' #Needed to support 'rake db:fixtures:load' on some ruby installs: http://dev.rousette.org.uk/ticket/557 +require 'prototype_helper_extensions' if (AUTHENTICATION_SCHEMES.include? 'ldap') require 'net/ldap' #requires ruby-net-ldap gem be installed diff --git a/tracks/lib/prototype_helper_extensions.rb b/tracks/lib/prototype_helper_extensions.rb new file mode 100644 index 00000000..5d4325ba --- /dev/null +++ b/tracks/lib/prototype_helper_extensions.rb @@ -0,0 +1,27 @@ +module ActionView + module Helpers + module PrototypeHelper + + def remote_to_href(options = {}) + remote_function(options.merge(:url => javascript_variable('this.href'))) + "\n" + end + + class JavaScriptGenerator #:nodoc: + module GeneratorMethods + + # Executes the content of the block if the user confirms the javascript confirmation. Example: + # + # page.confirming("Are you sure?") do + # page.visual_effect :hide, 'information' + # end + def confirming(message) + message = "'#{message}'" unless message =~ /^['"]/ + self << "if (confirm(#{message})) {" + yield + self << "}" + end + end + end + end + end +end \ No newline at end of file diff --git a/tracks/public/javascripts/application.js b/tracks/public/javascripts/application.js index 03e2fb45..66ff9a4b 100644 --- a/tracks/public/javascripts/application.js +++ b/tracks/public/javascripts/application.js @@ -34,21 +34,12 @@ var TracksForm = { toggleDiv.toggleClassName('hide_form'); } } -Ajax.Responders.register({ - onCreate: function() { - if($('busy') && Ajax.activeRequestCount>0) - Effect.Appear('busy',{duration:0.5,queue:'end'}); - }, - onComplete: function() { - if($('busy') && Ajax.activeRequestCount==0) - Element.hide('busy'); - } -//, -// uncomment the next three lines for easier debugging with FireBug +// uncomment the next four lines for easier debugging with FireBug +// Ajax.Responders.register({ // onException: function(source, exception) { // console.error(exception); // } -}); +// }); /* fade flashes automatically */ Event.observe(window, 'load', function() { diff --git a/tracks/test/unit/prototype_helper_extensions_test.rb b/tracks/test/unit/prototype_helper_extensions_test.rb new file mode 100644 index 00000000..a3d2ef16 --- /dev/null +++ b/tracks/test/unit/prototype_helper_extensions_test.rb @@ -0,0 +1,68 @@ +require File.dirname(__FILE__) + '/../test_helper' +require File.dirname(__FILE__) + '/../../lib/prototype_helper_extensions' + +class PrototypeHelperExtensionsTest < Test::Unit::TestCase + include ActionView::Helpers::JavaScriptHelper + include ActionView::Helpers::PrototypeHelper + include ActionView::Helpers::ScriptaculousHelper + + include ActionView::Helpers::UrlHelper + include ActionView::Helpers::TagHelper + include ActionView::Helpers::TextHelper + include ActionView::Helpers::FormTagHelper + include ActionView::Helpers::FormHelper + include ActionView::Helpers::CaptureHelper + + def setup + @template = nil + @controller = Class.new do + def url_for(options, *parameters_for_method_reference) + if options.is_a?(String) + options + elsif options.is_a?(Hash) + url = "http://www.example.com/" + url << options[:action].to_s if options and options[:action] + url << "?a=#{options[:a]}" if options && options[:a] + url << "&b=#{options[:b]}" if options && options[:a] && options[:b] + url + elsif options.is_a?(JavaScriptRef) + url = options.to_json + else + raise 'unhandled type' + options.class.inspect + end + end + end.new + @generator = create_generator + end + + + def test_confirming + @generator.confirming("Please confirm.") do + @generator.alert 'foo' + end + assert_equal "if (confirm('Please confirm.')) {\nalert(\"foo\");\n}", @generator.to_s + end + + def test_confirming_with_javascript + @generator.confirming("'Please confirm ' + this.title + '.'") do + @generator.alert 'foo' + end + assert_equal "if (confirm('Please confirm ' + this.title + '.')) {\nalert(\"foo\");\n}", @generator.to_s + end + + def test_remote_to_href + assert_equal "new Ajax.Request(this.href, {asynchronous:true, evalScripts:true})\n", remote_to_href + end + + def test_remote_to_href_with_options + assert_equal "new Ajax.Request(this.href, {asynchronous:true, evalScripts:true, method:'put'})\n", remote_to_href(:method => 'put') + end + + protected + def create_generator + block = Proc.new { |*args| yield *args if block_given? } + JavaScriptGenerator.new self, &block + end + +end + diff --git a/tracks/vendor/plugins/asset_packager/lib/synthesis/asset_package_helper.rb b/tracks/vendor/plugins/asset_packager/lib/synthesis/asset_package_helper.rb index bc4ff15c..8c49fa78 100644 --- a/tracks/vendor/plugins/asset_packager/lib/synthesis/asset_package_helper.rb +++ b/tracks/vendor/plugins/asset_packager/lib/synthesis/asset_package_helper.rb @@ -13,7 +13,7 @@ module Synthesis end sources.collect!{|s| s.to_s} - sources = (RAILS_ENV != "development" ? + sources = (RAILS_ENV != "development" || SUPPRESS_ASSET_PACKAGER ? AssetPackage.targets_from_sources("javascripts", sources) : AssetPackage.sources_from_targets("javascripts", sources)) @@ -24,7 +24,7 @@ module Synthesis options = sources.last.is_a?(Hash) ? sources.pop.stringify_keys : { } sources.collect!{|s| s.to_s} - sources = (RAILS_ENV != "development" ? + sources = (RAILS_ENV != "development" || SUPPRESS_ASSET_PACKAGER ? AssetPackage.targets_from_sources("stylesheets", sources) : AssetPackage.sources_from_targets("stylesheets", sources))