From 689c10b618c6c469ce82a7f09e117567def577de Mon Sep 17 00:00:00 2001 From: Azul Date: Wed, 23 Apr 2014 14:58:30 +0200 Subject: simple form: add wrapped and loading... buttons #5542 the loading... text on the buttons was not capitalized before. So in order to change this in a (more or less) single place i added new button types to simple_form: button :wrapped - normal button, with loading and an optional cancel button wrapped in the classical bootstrap action div. cancel option contains the url to go to when canceling. button :loading - simple button with loading text capitalized by using i18n (simple_form.buttons.loading) Conflicts: engines/support/app/views/tickets/new.html.haml --- app/views/sessions/new.html.haml | 4 +--- app/views/users/new.html.haml | 4 +--- config/initializers/simple_form.rb | 2 ++ config/locales/simple_form.en.yml | 3 +++ .../app/views/tickets/_new_comment_form.html.haml | 4 ++-- engines/support/app/views/tickets/_tabs.html.haml | 4 ++-- engines/support/app/views/tickets/new.html.haml | 7 +----- lib/extensions/simple_form.rb | 28 ++++++++++++++++++++++ 8 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 lib/extensions/simple_form.rb diff --git a/app/views/sessions/new.html.haml b/app/views/sessions/new.html.haml index 316eec1..6f3b324 100644 --- a/app/views/sessions/new.html.haml +++ b/app/views/sessions/new.html.haml @@ -6,6 +6,4 @@ = simple_form_for [:api, @session], :validate => true, :html => { :id => :new_session, :class => 'form-horizontal' } do |f| = f.input :login, :required => false, :label => t(:username), :input_html => { :id => :srp_username } = f.input :password, :required => false, :input_html => { :id => :srp_password } - .form-actions - = f.button :submit, :value => t(:login), :class => 'btn-primary' - = link_to t(:cancel), home_path, :class => 'btn' + = f.button :wrapped, value: t(:login), cancel: home_path diff --git a/app/views/users/new.html.haml b/app/views/users/new.html.haml index 173dd8c..3478989 100644 --- a/app/views/users/new.html.haml +++ b/app/views/users/new.html.haml @@ -13,7 +13,5 @@ = f.input :login, :label => t(:username), :required => false, :input_html => { :id => :srp_username } = f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password } = f.input :password_confirmation, :required => false, :validate => true, :input_html => { :id => :srp_password_confirmation } - .form-actions - = f.button :submit, :value => t(:signup), :class => 'btn btn-primary' - = link_to t(:cancel), home_path, :class => 'btn' + = f.button :wrapped, value: t(:signup), cancel: home_path diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb index e3f8d09..710dacc 100644 --- a/config/initializers/simple_form.rb +++ b/config/initializers/simple_form.rb @@ -1,3 +1,5 @@ +require 'extensions/simple_form' + # Use this setup block to configure all options available in SimpleForm. SimpleForm.setup do |config| # Wrappers are used by the form builder to generate a diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 0df11fe..4beeb7d 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -10,6 +10,9 @@ en: # html: '*' error_notification: default_message: "Please review the problems below:" + buttons: + cancel: 'Cancel' + loading: 'Loading...' # Labels and hints examples # labels: # defaults: diff --git a/engines/support/app/views/tickets/_new_comment_form.html.haml b/engines/support/app/views/tickets/_new_comment_form.html.haml index 8418e01..40c737f 100644 --- a/engines/support/app/views/tickets/_new_comment_form.html.haml +++ b/engines/support/app/views/tickets/_new_comment_form.html.haml @@ -7,7 +7,7 @@ = c.input :body, :label => false, :as => :text, :input_html => {:class => "full-width", :rows=> 5} - if admin? = c.input :private, :as => :boolean, :label => false, :inline_label => true - = f.button :button, t(:post_reply), :name => 'commit', :class => 'btn-primary', :type => 'submit', :value => 'post_reply' + = f.button :loading, t(:post_reply), class: 'btn-primary', value: 'post_reply' - if logged_in? && @ticket.is_open - = f.button :button, t(:reply_and_close), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'reply_and_close' + = f.button :loading, t(:reply_and_close), value: 'reply_and_close' = link_to t(:cancel), auto_tickets_path, :class => :btn diff --git a/engines/support/app/views/tickets/_tabs.html.haml b/engines/support/app/views/tickets/_tabs.html.haml index b7b5d3a..445a909 100644 --- a/engines/support/app/views/tickets/_tabs.html.haml +++ b/engines/support/app/views/tickets/_tabs.html.haml @@ -1,7 +1,7 @@ -# -# SORT ORDER TABS -# -- unless action?(:new) +- unless action?(:new) or action?(:create) %ul.nav.nav-pills.pull-right.slim %li{:class=> ("active" if search_order.start_with? 'created_at')} = link_to_order('created') @@ -19,5 +19,5 @@ = link_to_status 'closed' %li{:class => ("active" if search_status == 'all')} = link_to_status 'all' - %li{:class => ("active" if action?(:new))} + %li{:class => ("active" if action?(:new) || action?(:create))} = link_to icon(:plus, :black) + t(:new_ticket), auto_new_ticket_path diff --git a/engines/support/app/views/tickets/new.html.haml b/engines/support/app/views/tickets/new.html.haml index 65ed67b..ab008d2 100644 --- a/engines/support/app/views/tickets/new.html.haml +++ b/engines/support/app/views/tickets/new.html.haml @@ -14,9 +14,4 @@ = c.input :body, :label => t(:description), :as => :text, :input_html => {:class => "full-width", :rows=> 5} - if admin? = c.input :private, :as => :boolean, :label => false, :inline_label => true - .form-actions - = f.button :submit, :class => 'btn-primary', :value => t(:create_thing, :thing => t(:ticket)) - - if logged_in? - = link_to t(:cancel), auto_tickets_path, :class => :btn - - else - = link_to t(:cancel), home_path, :class => 'btn' + = f.button :wrapped, cancel: (logged_in? ? auto_tickets_path : home_path) diff --git a/lib/extensions/simple_form.rb b/lib/extensions/simple_form.rb new file mode 100644 index 0000000..f28e18f --- /dev/null +++ b/lib/extensions/simple_form.rb @@ -0,0 +1,28 @@ +module WrappedButton + def wrapped_button(*args, &block) + template.content_tag :div, :class => "form-actions" do + options = args.extract_options! + options[:class] = ['btn-primary', options[:class]].compact + args.unshift :loading + args << options + if cancel = options.delete(:cancel) + cancel_link = template.link_to I18n.t('simple_form.buttons.cancel'), + cancel, class: :btn + button(*args, &block) + ' ' + cancel_link + else + button(*args, &block) + end + end + end +end +SimpleForm::FormBuilder.send :include, WrappedButton + +module LoadingButton + def loading_button(*args, &block) + options = args.extract_options! + options[:"data-loading-text"] = I18n.t('simple_form.buttons.loading') + args << options + button_button(*args, &block) + end +end +SimpleForm::FormBuilder.send :include, LoadingButton -- cgit v1.2.3 From 6c13d3323c180a333fd0f32d17a62adce9fcf2bb Mon Sep 17 00:00:00 2001 From: Azul Date: Wed, 23 Apr 2014 15:27:40 +0200 Subject: using simple_form for the last form that was not using it. --- engines/support/app/controllers/tickets_controller.rb | 8 ++++---- engines/support/app/views/tickets/_edit_form.html.haml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/engines/support/app/controllers/tickets_controller.rb b/engines/support/app/controllers/tickets_controller.rb index 650f628..d552209 100644 --- a/engines/support/app/controllers/tickets_controller.rb +++ b/engines/support/app/controllers/tickets_controller.rb @@ -43,18 +43,18 @@ class TicketsController < ApplicationController end def update - if params[:commit] == 'close' + if params[:button] == 'close' @ticket.is_open = false @ticket.save redirect_to_tickets - elsif params[:commit] == 'open' + elsif params[:button] == 'open' @ticket.is_open = true @ticket.save redirect_to auto_ticket_path(@ticket) else @ticket.attributes = cleanup_ticket_params(params[:ticket]) - if params[:commit] == 'reply_and_close' + if params[:button] == 'reply_and_close' @ticket.close end @@ -98,7 +98,7 @@ class TicketsController < ApplicationController # def redirect_to_tickets if logged_in? - if params[:commit] == t(:reply_and_close) + if params[:button] == t(:reply_and_close) redirect_to auto_tickets_path else redirect_to auto_ticket_path(@ticket) diff --git a/engines/support/app/views/tickets/_edit_form.html.haml b/engines/support/app/views/tickets/_edit_form.html.haml index 714f8ff..7958334 100644 --- a/engines/support/app/views/tickets/_edit_form.html.haml +++ b/engines/support/app/views/tickets/_edit_form.html.haml @@ -17,7 +17,7 @@ regarding_user_link = '' end -= form_for @ticket do |f| += simple_form_for @ticket do |f| = hidden_ticket_fields %p.first - if @ticket.is_open? @@ -39,10 +39,10 @@ = t(:regarding_account) = regarding_user_link = f.text_field :regarding_user - = f.button t(:save), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'save' + = f.button :loading, t(:save), :value => 'save' - if @ticket.is_open? - = f.button t(:close), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'close' + = f.button :loading, t(:close), :value => 'close' - else - = f.button t(:open), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'open' + = f.button :loading, t(:open), :value => 'open' - if admin? = link_to t(:destroy), auto_ticket_path(@ticket), :confirm => t(:are_you_sure), :method => :delete, :class => 'btn' -- cgit v1.2.3 From e727d211630591a3aaed5eba0eb50c7d4964b6f8 Mon Sep 17 00:00:00 2001 From: Azul Date: Wed, 23 Apr 2014 16:54:40 +0200 Subject: ensure buttons are properly loading... and reset --- app/assets/javascripts/application.js | 1 + app/assets/javascripts/buttons.js | 39 +++++++++++++++++++++++++++++++++++ app/assets/javascripts/users.js | 21 +++---------------- 3 files changed, 43 insertions(+), 18 deletions(-) create mode 100644 app/assets/javascripts/buttons.js diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index ab07e1f..9af373d 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -20,3 +20,4 @@ //= require platform //= require tickets //= require users +//= require buttons diff --git a/app/assets/javascripts/buttons.js b/app/assets/javascripts/buttons.js new file mode 100644 index 0000000..7142957 --- /dev/null +++ b/app/assets/javascripts/buttons.js @@ -0,0 +1,39 @@ +/* + * Buttons.js + * + * Use bootstrap loading state after submitting a form. + * + * Some form inputs are validaded before the submission + * so triggering loading state on click events is not a + * good idea. If the validation fails the errors will + * be displayed but the button would be in loading state. + * + * We used to trigger it based on form submission but + * we have a few forms that contain multiple buttons. + * So now we mark the buttons as clicked on click and + * put the clicked button into loading state on submit. + * + */ + +(function() { + markAsClicked = function () { + var btn = $(this) + btn.addClass('clicked') + setTimeout(function () { + btn.removeClass('clicked') + }, 1000) + }; + + markAsLoading = function(submitEvent) { + var form = submitEvent.target; + $(form).addClass('submitted') + // bootstrap loading state: + $(form).find('.btn.clicked[type="submit"]').button('loading'); + }; + + $(document).ready(function() { + $('form').submit(markAsLoading); + $('.btn[type="submit"]').click(markAsClicked); + }); + +}).call(this); diff --git a/app/assets/javascripts/users.js b/app/assets/javascripts/users.js index 8486756..4a86ef5 100644 --- a/app/assets/javascripts/users.js +++ b/app/assets/javascripts/users.js @@ -35,24 +35,10 @@ data: $(form).serialize() }); req.done( function() { - $(form).find('input[type="submit"]').button('reset'); + $(form).find('.btn[type="submit"]').button('reset'); }); }; - - markAsSubmitted = function(submitEvent) { - var form = submitEvent.target; - $(form).addClass('submitted') - // bootstrap loading state: - $(form).find('input[type="submit"]').button('loading'); - }; - - resetButtons = function(submitEvent) { - var form = $('form.submitted') - // bootstrap loading state: - $(form).find('input[type="submit"]').button('reset'); - $(form).removeClass('submitted') - }; - + // // PUBLIC FUNCTIONS // @@ -79,7 +65,7 @@ clear_errors(); var errors = extractErrors(message); displayErrors(errors); - resetButtons(); + $('.btn[type="submit"]').button('reset'); } function extractErrors(message) { @@ -115,7 +101,6 @@ // $(document).ready(function() { - $('form').submit(markAsSubmitted); $('#new_user').submit(prevent_default); $('#new_user').submit(srp.signup); $('#new_session').submit(prevent_default); -- cgit v1.2.3 From 615261a6f0d1bae5d999e3014f18191ed1ba1008 Mon Sep 17 00:00:00 2001 From: Azul Date: Wed, 23 Apr 2014 17:14:30 +0200 Subject: move open and close buttons into status display They do not save any changes. So i think it's better to keep them separated from the Save button that does save changes. --- engines/support/app/views/tickets/_edit_form.html.haml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/engines/support/app/views/tickets/_edit_form.html.haml b/engines/support/app/views/tickets/_edit_form.html.haml index 7958334..bf175fe 100644 --- a/engines/support/app/views/tickets/_edit_form.html.haml +++ b/engines/support/app/views/tickets/_edit_form.html.haml @@ -21,9 +21,13 @@ = hidden_ticket_fields %p.first - if @ticket.is_open? - %span.label.label-info= t(:open) + %span.label.label-info + %b{style: 'padding:10px'}= t(:open) + = f.button :loading, t(:close), value: 'close', class: 'btn-mini' - else - %span.label.label-success= t(:closed) + %span.label.label-success + %b{style: 'padding:10px'}= t(:closed) + = f.button :loading, t(:open), value: 'open', class: 'btn-mini' %span.label.label-clear= t(:created_by_on, :user => created_by, :time => @ticket.created_at.to_s(:short)).html_safe %div= t(:subject) = f.text_field :subject, :class => 'large full-width' @@ -40,9 +44,5 @@ = regarding_user_link = f.text_field :regarding_user = f.button :loading, t(:save), :value => 'save' - - if @ticket.is_open? - = f.button :loading, t(:close), :value => 'close' - - else - = f.button :loading, t(:open), :value => 'open' - if admin? = link_to t(:destroy), auto_ticket_path(@ticket), :confirm => t(:are_you_sure), :method => :delete, :class => 'btn' -- cgit v1.2.3 From f23ca91c01ce14d75c221ccddb7d8b1b7e2c0cef Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 24 Apr 2014 13:17:06 +0200 Subject: make test independent of button tag input or button can be used --- test/integration/browser/account_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/browser/account_test.rb b/test/integration/browser/account_test.rb index a5677ad..6d5f7f9 100644 --- a/test/integration/browser/account_test.rb +++ b/test/integration/browser/account_test.rb @@ -131,9 +131,9 @@ class AccountTest < BrowserIntegrationTest end def assert_invalid_login(page) - assert page.has_selector? 'input.btn-primary.disabled' + assert page.has_selector? '.btn-primary.disabled' assert page.has_content? I18n.t(:invalid_user_pass) - assert page.has_no_selector? 'input.btn-primary.disabled' + assert page.has_no_selector? '.btn-primary.disabled' end def inject_malicious_js -- cgit v1.2.3 From ed3575856276f25b7c8253e302646dc7684a5da8 Mon Sep 17 00:00:00 2001 From: Azul Date: Fri, 25 Apr 2014 08:09:10 +0200 Subject: use i18n keys for signup & login buttons --- config/locales/simple_form.en.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 4beeb7d..5d0c675 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -26,4 +26,11 @@ en: # defaults: # username: 'User name to sign in.' # password: 'No special characters, please.' + helpers: + submit: + user: + create: "Sign up" + update: "Save" + session: + create: "Log in" -- cgit v1.2.3