Index: activeselect.info
===================================================================
RCS file: activeselect.info
diff -N activeselect.info
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ activeselect.info	4 Jan 2007 10:56:06 -0000
@@ -0,0 +1,3 @@
+; $Id$
+name = Active select
+description = Defines the activeselect form element, which allows modules to have AJAX-enabled select boxes.
Index: activeselect.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/activeselect/activeselect.js,v
retrieving revision 1.17
diff -u -p -r1.17 activeselect.js
--- activeselect.js	14 Apr 2006 15:07:50 -0000	1.17
+++ activeselect.js	4 Jan 2007 10:56:07 -0000
@@ -1,48 +1,37 @@
 // $Id: activeselect.js,v 1.17 2006/04/14 15:07:50 jaza Exp $
 
-// Global Killswitch
-if (isJsEnabled()) {
-  addLoadEvent(activeselectAutoAttach);
-}
-
 /**
  * Attaches the activeselect behaviour to all required fields
  */
-function activeselectAutoAttach() {
+Drupal.activeselectAutoAttach = function () {
   var asdb = [];
-  var inputs = document.getElementsByTagName('input');
-  var input = null;
-  for (var i = 0; input = inputs[i]; i++) {
-    if (input && hasClass(input, 'activeselect-path')) {
-  	  var index = input.id.substr(0, input.id.length - 18);
-  	  var uri = input.value +'/'+ encodeURIComponent(index).substr(5);
-  	  input = $(index + '-activeselect-extra');
-  	  var extra = input.value;
-  	  input = $(index + '-activeselect-targets');
-  	  var targets = input.value;
-  	  input = $(index);
-  	  if (!asdb[uri]) {
-        asdb[uri] = new ASDB(uri, targets);
-      }
+  $('input.activeselect-path').each(function () {
+    var index = this.id.substr(0, this.id.length - 18);
+    var uri = this.value +'/'+ encodeURIComponent(index).substr(5);
+    var extra = $('#' + index + '-activeselect-extra').val();
+    var targets = $('#' + index + '-activeselect-targets').val();
+    var input = $('#' + index).get(0);
 
-      new jsAS(input, asdb[uri], targets, extra);
+    if (!asdb[uri]) {
+      asdb[uri] = new Drupal.ASDB(uri, targets);
     }
-  }
+    new Drupal.jsAS(input, asdb[uri], targets, extra);
+  });
 }
 
 /**
  * An ActiveSelect object
  */
-function jsAS(input, db, targets, extra) {
+Drupal.jsAS = function (input, db, targets, extra) {
   var as = this;
   this.input = input;
   this.db = db;
-  this.input.onchange = function (event) { return as.onchange(this, event); };
+  $(this.input).change(function (event) { return as.onchange(this, event); });
   this.extra = extra;
   var targetsArray = targets.split(',');
   this.targets = [];
   for (var target = 0; target < targetsArray.length; target++) {
-    var newTarget = $(targetsArray[target]);
+    var newTarget = $('#' + targetsArray[target]).get(0);
     newTarget.owner = this;
     this.targets.push(newTarget);
   }
@@ -56,7 +45,7 @@ function jsAS(input, db, targets, extra)
 /**
  * Handler for the "onchange" event
  */
-jsAS.prototype.onchange = function (input, e) {
+Drupal.jsAS.prototype.onchange = function (input, e) {
   if (!e) {
     e = window.event;
   }
@@ -67,49 +56,52 @@ jsAS.prototype.onchange = function (inpu
 /**
  * Return the currently selected options as a pipe-delimited string
  */
-jsAS.prototype.getSelectedOptions = function () {
+Drupal.jsAS.prototype.getSelectedOptions = function () {
   var selectedOptions = [];
   var maxWidth = 0;
-  for (var i = 0; i < this.input.options.length; i++) {
-    if (this.input.options[i].selected) {
-      var optionString = this.input.options[i].value.replace(/\|/g, '&#124;') +'|'+ this.input.options[i].text.replace(/\|/g, '&#124;');
+  $('#' + this.input.id + ' option').each(function () {
+    if (this.selected) {
+      var optionString = this.value.replace(/\|/g, '&#124;') +'|'+ this.text.replace(/\|/g, '&#124;');
       selectedOptions.push(optionString);
     }
-    if (this.input.options[i].text.length > maxWidth) {
-      maxWidth = this.input.options[i].text.length;
+    if (this.text.length > maxWidth) {
+      maxWidth = this.text.length;
     }
-  }
+  });
   this.setSelectWidth(maxWidth);
 
   return selectedOptions.join('||');
 }
 
 /**
- * Sets the width of the activeselect element, and adjusts the position of the
- * throbber background image
+ * Sets the width and background position of the activeselect element.
  */
-jsAS.prototype.setSelectWidth = function (width) {
+Drupal.jsAS.prototype.setSelectWidth = function (width) {
   if (width != null) {
     this.selectWidth = ((width * 10) * 1.5) + 20;
   }
-  this.input.style.width = this.selectWidth +'px';
-  this.input.style.backgroundPosition = (this.selectWidth - 35) +'px 2px';
+  $(this.input).css({
+    width: this.selectWidth +'px',
+    backgroundPosition: (this.selectWidth - 35) +'px 2px'
+  });
 }
 
 /**
  * Sets the width of the specified target element
  */
-jsAS.prototype.setTargetWidth = function (target, width) {
+Drupal.jsAS.prototype.setTargetWidth = function (target, width) {
   if (width != null) {
     this.targets[target].targetWidth = (width * 10) * 1.2;
   }
-  this.targets[target].style.width = this.targets[target].targetWidth +'px';
+  $(this.targets[target]).css({
+    width: this.targets[target].targetWidth +'px'
+  });
 }
 
 /**
  * Starts a search
  */
-jsAS.prototype.populateTargets = function () {
+Drupal.jsAS.prototype.populateTargets = function () {
   var as = this;
   this.db.owner = this;
 
@@ -119,7 +111,7 @@ jsAS.prototype.populateTargets = functio
 /**
  * Fills the target select boxes with any matches received
  */
-jsAS.prototype.populate = function (matches) {
+Drupal.jsAS.prototype.populate = function (matches) {
   for (targetIndex in this.targets) {
     var target = this.targets[targetIndex];
     var matchesTarget = 0;
@@ -143,9 +135,7 @@ jsAS.prototype.populate = function (matc
         }
       }
 
-      while (target.hasChildNodes()) {
-        target.removeChild(target.childNodes[0]);
-      }
+      $(target).empty();
       var targetMatches = matches[matchesTarget]['options'];
       var maxWidth = 0;
       for (currMatch in targetMatches) {
@@ -159,7 +149,7 @@ jsAS.prototype.populate = function (matc
         // 'new Option()' used instead of appendChild(), because IE6 refuses to
         // display option text if the latter method is used (otherwise they seem
         // to behave the same).
-        this.targets[targetIndex].options[this.targets[targetIndex].options.length] = new Option(text, value, false, selected);
+        $(this.targets[targetIndex]).append(new Option(text, value, false, selected));
         if (selected && !this.targets[targetIndex].multiple) {
           this.targets[targetIndex].selectedIndex = this.targets[targetIndex].options.length-1;
         }
@@ -168,7 +158,7 @@ jsAS.prototype.populate = function (matc
         this.targets[targetIndex].selectedIndex = 0;
       }
 
-      if (hasClass(this.targets[targetIndex], 'form-activeselect')) {
+      if (this.hasClass(this.targets[targetIndex], 'form-activeselect')) {
         // Since IE does not support the DOM 2 methods for manually firing an
         // event, we must cater especially to its needs.
         // Reference: http://www.howtocreate.co.uk/tutorials/javascript/domevents
@@ -195,9 +185,23 @@ jsAS.prototype.populate = function (matc
 }
 
 /**
+ * Returns true if an element has a specified class name
+ */
+Drupal.jsAS.prototype.hasClass = function (node, className) {
+  if (node.className == className) {
+    return true;
+  }
+  var reg = new RegExp('(^| )'+ className +'($| )')
+  if (reg.test(node.className)) {
+    return true;
+  }
+  return false;
+}
+
+/**
  * An ActiveSelect DataBase object
  */
-function ASDB(uri, targets) {
+Drupal.ASDB = function (uri, targets) {
   this.uri = uri;
   this.targets = targets;
   this.delay = 300;
@@ -207,7 +211,7 @@ function ASDB(uri, targets) {
 /**
  * Performs a cached and delayed search
  */
-ASDB.prototype.search = function(searchString, targets, extra) {
+Drupal.ASDB.prototype.search = function(searchString, targets, extra) {
   this.searchString = searchString;
   if (this.cache[searchString]) {
     return this.owner.populate(this.cache[searchString]);
@@ -217,36 +221,41 @@ ASDB.prototype.search = function(searchS
   }
   var db = this;
   this.timer = setTimeout(function() {
-    db.owner.input.style.width = db.owner.selectWidth +'px';
-    db.owner.input.style.backgroundPosition = (db.owner.selectWidth - 35) +'px -18px';
+    $(db.owner.input).css({
+      width: db.owner.selectWidth +'px',
+      backgroundPosition: (db.owner.selectWidth - 35) +'px -18px'
+    });
     var targetIds = [];
     for (var target = 0; target < targets.length; target++) {
       if (targets[target].id) {
-        targetIds.push(targets[target].id.substr(5));
+        targetIds.push($(targets[target]).id().substr(5));
       }
     }
     var targetsString = targetIds.join(',');
-    var uri = db.uri +'/'+ encodeURIComponent(targetsString) +'/'+ encodeURIComponent(searchString);
-    uri += '/'+ encodeURIComponent(extra);
-    HTTPGet(uri, db.receive, db);
+
+    // Ajax GET request for activeselect
+    $.ajax({
+      type: "GET",
+      url: db.uri +'/'+ encodeURIComponent(targetsString) +'/'+ encodeURIComponent(searchString) +'/'+ encodeURIComponent(extra),
+      success: function (data) {
+        // Split into array of key->value pairs
+        if (data.length > 0) {
+          var targets = Drupal.parseJson(data);
+          if (typeof targets['status'] == 'undefined' || targets['status'] != 0) {
+            db.cache[searchString] = targets;
+            db.owner.populate(targets);
+          }
+        }
+      },
+      error: function (xmlhttp) {
+        asdb.owner.setSelectWidth(null);
+        alert('An HTTP error '+ xmlhttp.status +' occured.\n'+ db.uri);
+      }
+    });
   }, this.delay);
 }
 
-/**
- * HTTP callback function. Passes select options to the activeselect object
- */
-ASDB.prototype.receive = function(string, xmlhttp, asdb) {
-  // Note: Safari returns 'undefined' status if the request returns no data.
-  if (xmlhttp.status != 200 && typeof xmlhttp.status != 'undefined') {
-    asdb.owner.setSelectWidth(null);
-    return alert('An HTTP error '+ xmlhttp.status +' occured.\n'+ asdb.uri);
-  }
-  // Split into array of key->value pairs
-  if (string.length > 0) {
-    var targets = parseJson(string);
-    if (typeof targets['status'] == 'undefined' || targets['status'] != 0) {
-      asdb.cache[asdb.searchString] = targets;
-      asdb.owner.populate(targets);
-    }
-  }
+// Global Killswitch
+if (Drupal.jsEnabled) {
+  $(document).ready(Drupal.activeselectAutoAttach);
 }
Index: activeselect.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/activeselect/activeselect.module,v
retrieving revision 1.7.2.1
diff -u -p -r1.7.2.1 activeselect.module
--- activeselect.module	17 Apr 2006 07:11:53 -0000	1.7.2.1
+++ activeselect.module	4 Jan 2007 10:56:07 -0000
@@ -14,8 +14,6 @@ function activeselect_help($section) {
   switch ($section) {
     case 'admin/help#activeselect':
       return '<p>'. t('The activeselect module defines the activeselect form element. An activeselect element is the same as a regular select element, except that when the user selects a new option (or set of options), a different select element (the target element) gets its list updated. This is done using AJAX, and it is designed to degrade gracefully if the required JavaScript support is not present. The target element can be either a regular select box, or another activeselect box (which in turn can trigger another target box, which can trigger yet another, resulting in a hierarchical cascade of activeselect elements).') .'</p>';
-    case 'admin/modules#description':
-      return t('Defines the activeselect form element, which allows modules to have AJAX-enabled select boxes.');
   }
 }
 
@@ -76,7 +74,7 @@ function theme_activeselect($element) {
   $extra = '';
   if ($element['#activeselect_path'] && $element['#activeselect_targets']) {
     $module_path = drupal_get_path('module', 'activeselect'). '/';
-    theme_add_style($module_path. 'activeselect.css');
+    drupal_add_css($module_path. 'activeselect.css');
     drupal_add_js($module_path. 'activeselect.js');
     $class[] = ' form-activeselect';
     $extra = '<input class="activeselect-path" type="hidden" id="'. $element['#id'] .'-activeselect-path" value="'. check_url(url($element['#activeselect_path'], NULL, NULL, TRUE)) .'" disabled="disabled" />'. "\n";
@@ -89,5 +87,5 @@ function theme_activeselect($element) {
   }
   _form_set_class($element, $class);
 
-  return theme('form_element', $element['#title'], '<select name="'. $element['#name'] .''. ($element['#multiple'] ? '[]' : '') .'"'. ($element['#multiple'] ? ' multiple="multiple" ' : '') . drupal_attributes($element['#attributes']) .' id="' . $element['#id'] .'" '. $size. '>'. form_select_options($element) .'</select>', $element['#description'], $element['#id'], $element['#required'], form_get_error($element)). $extra;
+  return theme('form_element', $element, '<select name="'. $element['#name'] .''. ($element['#multiple'] ? '[]' : '') .'"'. ($element['#multiple'] ? ' multiple="multiple" ' : '') . drupal_attributes($element['#attributes']) .' id="' . $element['#id'] .'" '. $size. '>'. form_select_options($element) .'</select>'). $extra;
 }
