diff --git a/js/auto-submit.js b/js/auto-submit.js
index f84db23..bac3c44 100644
--- a/js/auto-submit.js
+++ b/js/auto-submit.js
@@ -22,53 +22,68 @@
  *  '#attributes' => array('class' => array('ctools-use-ajax', 'ctools-auto-submit-click')),
  * @endcode
  *
- * Currently only 'select' and 'textfield' types are supported. We probably
- * could use additional support for radios and checkboxes.
+ * Currently only 'select', 'radio', 'checkbox' and 'textfield' types are supported. We probably
+ * could use additional support for HTML5 input types.
  */
 
 Drupal.behaviors.CToolsAutoSubmit = {
   attach: function() {
-    var timeoutID = 0;
+    // 'this' references the form element
+    function triggerSubmit (e) {
+      if (!$(this).hasClass('ctools-ajaxing')) {
+        $(this).find('.ctools-auto-submit-click').click();
+      }
+    }
 
-    // Bind to any select widgets that will be auto submitted.
-    $('select.ctools-auto-submit:not(.ctools-auto-submit-processed),.ctools-auto-submit-full-form *[type!=input]:not(.ctools-auto-submit-processed)')
-      .addClass('.ctools-auto-submit-processed')
-      .change(function() {
-        $(this.form).find('.ctools-auto-submit-click').click();
-      });
-
-    // Bind to any textfield widgets that will be auto submitted.
-    $('input[type=text].ctools-auto-submit:not(.ctools-auto-submit-processed),.ctools-auto-submit-full-form input[type=text]:not(.ctools-auto-submit-processed)')
-      .addClass('.ctools-auto-submit-processed')
-      .keyup(function(e) {
-        var form = this.form;
-        switch (e.keyCode) {
-          case 16: // shift
-          case 17: // ctrl
-          case 18: // alt
-          case 20: // caps lock
-          case 33: // page up
-          case 34: // page down
-          case 35: // end
-          case 36: // home
-          case 37: // left arrow
-          case 38: // up arrow
-          case 39: // right arrow
-          case 40: // down arrow
-          case 9:  // tab
-          case 13: // enter
-          case 27: // esc
-            return false;
-          default:
-            if (!$(form).hasClass('ctools-ajaxing')) {
-              if ((timeoutID)) {
-                clearTimeout(timeoutID);
-              }
-
-              timeoutID = setTimeout(function() { $(form).find('.ctools-auto-submit-click').click(); }, 300);
-          }
+    // the change event bubbles so we only need to bind it to the outer form
+    $('form.ctools-auto-submit-full-form')
+      .add('.ctools-auto-submit')
+      .filter('form, select, input:not(:text, :submit)')
+      .not('.ctools-auto-submit-processed')
+      .change(function (e) { 
+        // don't trigger on text change for full-form
+        if ($(e.target).is(':not(:text, :submit)')) {
+          triggerSubmit.call(e.target.form);
         }
-    });
+      })
+      .addClass('ctools-auto-submit-processed');
+
+    // e.keyCode: key
+    // 16: shift
+    // 17: ctrl
+    // 18: alt
+    // 20: caps lock
+    // 33: page up
+    // 34: page down
+    // 35: end
+    // 36: home
+    // 37: left arrow
+    // 38: up arrow
+    // 39: right arrow
+    // 40: down arrow
+    //  9: tab
+    // 13: enter
+    // 27: esc
+    var discardKeyCode = [16, 17,18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 9, 13, 27];
+    // Don't wait for change event on textfields
+    $('.ctools-auto-submit-full-form input:text, input:text.ctools-auto-submit')
+      .not('.ctools-auto-submit-processed')
+      .each(function () {
+        // each textinput element has his own timeout
+        var timeoutID = 0;
+        $(this)
+          .bind('keydown keyup', function (e) {
+            if ($.inArray(e.keyCode, discardKeyCode) === -1) {
+              timeoutID && clearTimeout(timeoutID);
+            }
+          })
+          .keyup(function(e) {
+            if ($.inArray(e.keyCode, discardKeyCode) === -1) {
+              timeoutID = setTimeout($.proxy(triggerSubmit, this.form), 500);
+            }
+          });
+        }) // each
+      .addClass('ctools-auto-submit-processed');
   }
 }
 })(jQuery);
