From 707c456aa31a8939d024b0ad9138f0e637019f0d Mon Sep 17 00:00:00 2001
From: Mark Carver <mark.carver@me.com>
Date: Fri, 27 Dec 2013 16:27:45 -0600
Subject: [PATCH] Issue #2163197 by Mark Carver: Allow fieldsets to be
 persistent and save focus when AJAXing.

---
 js/project-issue.js | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 project_issue.info  |  1 +
 2 files changed, 87 insertions(+)
 create mode 100644 js/project-issue.js

diff --git a/js/project-issue.js b/js/project-issue.js
new file mode 100644
index 0000000..54cca40
--- /dev/null
+++ b/js/project-issue.js
@@ -0,0 +1,86 @@
+(function ($) {
+
+  /**
+   * A placeholder to save the currently focused input between AJAX requests.
+   */
+  Drupal.ajax.focusedInput = false;
+
+  /**
+   * Persistent input focus (retains the proper focus after AJAX replacements).
+   */
+  Drupal.behaviors.projectIssueAjaxFocusedInput = {
+    attach: function (context) {
+      var $context = $(context);
+      var inputs = ':input:not([type="hidden"],:submit)';
+      // Only bind a top level click event once to remove the stored focus if
+      // element is not an input.
+      $('body').once('ajax-focused-input', function () {
+        $(this).bind('mousedown', function (e) {
+          if (!$(e.target).is(inputs)) {
+            Drupal.ajax.focusedInput = false;
+          }
+        });
+      });
+      if (Drupal.ajax.focusedInput) {
+        // Do not use $context here, focused input could not be part of it.
+        $(':input[name="' + Drupal.ajax.focusedInput + '"]').focus();
+      }
+      // Bind various events on input elements to ensure we save the
+      // proper currently focused element.
+      var $inputs = $context.find(inputs)
+        .bind({
+          'keydown': function (e) {
+            var code = (e.keyCode ? e.keyCode : e.which);
+            // Detect tab keystroke.
+            if (code === 9) {
+              // Obtain the name of the next input element in the DOM
+              // structure.
+              Drupal.ajax.focusedInput = $inputs.eq(parseInt($inputs.index($(this)), 10) + 1).attr('name');
+            }
+          },
+          'mousedown': function () {
+            Drupal.ajax.focusedInput = $(this).attr('name');
+          },
+          'focus': function () {
+            Drupal.ajax.focusedInput = $(this).attr('name');
+          }
+        });
+    }
+  };
+
+  /**
+   * Persistent issue fieldsets (keeps them open/closed between HTTP requests).
+   */
+  Drupal.behaviors.projectIssuePersistentFieldsets = {
+    attach: function () {
+      // Only continue if localStorage is supported in the browser.
+      if (typeof window.localStorage !== 'undefined') {
+        // Only bind once.
+        $('#project-issue-ajax-form').once('issue-form', function () {
+          $('fieldset.collapsible', this).each(function() {
+            var $fieldset = $(this);
+            var id = $fieldset.attr('id');
+            // If the ID of the fieldset is present in localStorage, it's open.
+            if (window.localStorage[id]) {
+              $fieldset.removeClass('collapsed');
+            }
+            // Otherwise, it's closed.
+            else {
+              $fieldset.addClass('collapsed');
+            }
+            // Bind the "collapsed" event to change the localStorage value.
+            $fieldset.bind('collapsed', function(e){
+              if (!e.value) {
+                window.localStorage[id] = true;
+              }
+              else if (window.localStorage[id]) {
+                delete window.localStorage[id];
+              }
+            });
+          });
+        });
+      }
+    }
+  };
+
+})(jQuery);
diff --git a/project_issue.info b/project_issue.info
index 7477059..04ecd2d 100644
--- a/project_issue.info
+++ b/project_issue.info
@@ -27,6 +27,7 @@ recommends[] = diff
 ; particular, better support for hiding obsolete files.
 recommends[] = extended_file_field
 
+scripts[] = js/project-issue.js
 
 stylesheets[all][] = project_issue.css
 
-- 
1.8.3.4

