Use AJAX when adding a new authorized_key from the user home page.
authorTom Clegg <tom@curoverse.com>
Fri, 17 Jan 2014 20:06:34 +0000 (12:06 -0800)
committerTom Clegg <tom@curoverse.com>
Fri, 17 Jan 2014 20:06:34 +0000 (12:06 -0800)
On success, replace reminder box with a "Key added" message. On
failure, display the error message below the form.

refs #1880

apps/workbench/app/assets/javascripts/users.js [new file with mode: 0644]
apps/workbench/app/controllers/application_controller.rb
apps/workbench/app/views/application/error.json.erb [new file with mode: 0644]
apps/workbench/app/views/authorized_keys/create.js.erb [new file with mode: 0644]
apps/workbench/app/views/users/_notifications.html.erb

diff --git a/apps/workbench/app/assets/javascripts/users.js b/apps/workbench/app/assets/javascripts/users.js
new file mode 100644 (file)
index 0000000..c9c69a0
--- /dev/null
@@ -0,0 +1,40 @@
+$(document).
+    on('ajax:success', 'form.new_authorized_key',
+       function(e, data, status, xhr) {
+           $(e.target).parents('div.daxalert').fadeOut('slow', function() {
+               $('<div class="alert alert-success daxalert"><button type="button" class="close" data-dismiss="alert">&times;</button><p>Key added.</p></div>').hide().replaceAll(this).fadeIn('slow');
+           });
+       }).
+    on('ajax:complete', 'form.new_authorized_key',
+       function(e, data, status, xhr) {
+           $($('input[name=disable_element]', e.target).val()).
+               fadeTo(200, 1.0);
+       }).
+    on('ajax:error', 'form.new_authorized_key',
+       function(e, xhr, status, error) {
+           var error_div;
+           response = $.parseJSON(xhr.responseText);
+           error_div = $(e.target).parent().find('div.ajax-errors');
+           if (error_div.length == 0) {
+               $(e.target).parent().append('<div class="alert alert-error ajax-errors"></div>');
+               error_div = $(e.target).parent().find('div.ajax-errors');
+           }
+           if (response.errors) {
+               error_div.html($('<p/>').text(response.errors).html());
+           } else {
+               error_div.html('<p>Sorry, request failed.');
+           }
+           error_div.show();
+           $($('input[name=disable_element]', e.target).val()).
+               fadeTo(200, 1.0);
+       }).
+    on('click', 'form[data-remote] input[type=submit]',
+       function(e) {
+           $(e.target).parents('form').eq(0).parent().find('div.ajax-errors').html('').hide();
+           $($(e.target).
+             parents('form').
+             find('input[name=disable_element]').
+             val()).
+               fadeTo(200, 0.3);
+           return true;
+       });
index b7d377572d4b21e73cd19399835b842d2fa13c2e..d90d68c1ca8bfce82611415fe4cdcfaa32f50c85 100644 (file)
@@ -27,8 +27,12 @@ class ApplicationController < ActionController::Base
 
   def render_error(opts)
     respond_to do |f|
-      f.html { render opts.merge(controller: 'application', action: 'error') }
+      # json must come before html here, so it gets used as the
+      # default format when js is requested by the client. This lets
+      # ajax:error callback parse the response correctly, even though
+      # the browser can't.
       f.json { render opts.merge(json: {success: false, errors: @errors}) }
+      f.html { render opts.merge(controller: 'application', action: 'error') }
     end
   end
 
diff --git a/apps/workbench/app/views/application/error.json.erb b/apps/workbench/app/views/application/error.json.erb
new file mode 100644 (file)
index 0000000..8371ff9
--- /dev/null
@@ -0,0 +1 @@
+{"errors":<%= raw @errors.to_json %>}
\ No newline at end of file
diff --git a/apps/workbench/app/views/authorized_keys/create.js.erb b/apps/workbench/app/views/authorized_keys/create.js.erb
new file mode 100644 (file)
index 0000000..092bc2b
--- /dev/null
@@ -0,0 +1 @@
+;
index 88978ef148530cd7680fb57c623744f06e4f2b9a..9b9fc12e17310aded7889788fcc511b6f219b30e 100644 (file)
       When you have an SSH key you would like to use, paste the SSH public key
       in the text box.
     </div>
-      <%= form_for AuthorizedKey.new do |f| %>
-       <%= hidden_field_tag :return_to, request.original_url %>
-       <%= f.text_area :public_key, cols: 50, rows: 4, placeholder: "Paste your public key here", style: "width: 100%" %>
-       <%= f.submit :Save, value: raw("&check;"), class: "btn btn-primary pull-right" %>
-      <% end %>
+    <%= form_for AuthorizedKey.new, remote: true do |f| %>
+      <div class="row-fluid">
+        <div class="span12">
+          <%= hidden_field_tag :return_to, request.original_url %>
+          <%= hidden_field_tag :disable_element, 'input[type=submit]' %>
+          <%= f.text_area :public_key, rows: 4, placeholder: "Paste your public key here", style: "width: 100%" %>
+        </div>
+      </div>
+      <div class="row-fluid">
+        <div class="span4 offset8">
+          <%= f.submit :Save, value: raw("&check;"), class: "btn btn-primary pull-right", style: "width: 100%" %>
+        </div>
+      </div>
+    <% end %>
   </div>
 <% end %>