Author: jablko
Date: Thu Sep 24 12:45:33 2009
New Revision: 3499

Log:
Support adding new items with autocomplete inputs, fixes issues 984 and 677 -- 
force

Modified:
   trunk/apps/qubit/modules/informationobject/templates/editIsadSuccess.php
   trunk/apps/qubit/modules/informationobject/templates/editRadSuccess.php
   trunk/web/js/autocomplete.js

Modified: 
trunk/apps/qubit/modules/informationobject/templates/editIsadSuccess.php
==============================================================================
--- trunk/apps/qubit/modules/informationobject/templates/editIsadSuccess.php    
Thu Sep 24 12:40:45 2009        (r3498)
+++ trunk/apps/qubit/modules/informationobject/templates/editIsadSuccess.php    
Thu Sep 24 12:45:33 2009        (r3499)
@@ -111,12 +111,14 @@
       <?php echo $form->creators->label(__('Name of 
creator(s)'))->renderLabel() ?>
       <?php echo $form->creators->render(array('class' => 
'form-autocomplete')) ?>
       <?php echo $form->creators->help(__('Record the name of the 
organization(s) or the individual(s) responsible for the creation, accumulation 
and maintenance of the records in the unit of description. The name should 
given in the standardized form as prescribed by international or national 
conventions in accordance with the principles of ISAAR(CPF).'))->renderHelp() ?>
+      <input class="add" type="hidden" value="<?php echo 
url_for(array('module' => 'actor', 'action' => 'create')) ?> 
#authorized_form_of_name"/>
       <input class="list" type="hidden" value="<?php echo 
url_for(array('module' => 'actor', 'action' => 'list')) ?>"/>
     </div>
 
     <div class="form-item">
       <?php echo $form->repository->renderLabel() ?>
       <?php echo $form->repository->render(array('class' => 
'form-autocomplete')) ?>
+      <input class="add" type="hidden" value="<?php echo 
url_for(array('module' => 'repository', 'action' => 'create')) ?> 
#authorized_form_of_name"/>
       <input class="list" type="hidden" value="<?php echo 
url_for(array('module' => 'repository', 'action' => 'list', 'informationObject' 
=> $informationObject->id, 'aclAction' => $aclActionId)) ?>"/>
     </div>
 

Modified: 
trunk/apps/qubit/modules/informationobject/templates/editRadSuccess.php
==============================================================================
--- trunk/apps/qubit/modules/informationobject/templates/editRadSuccess.php     
Thu Sep 24 12:40:45 2009        (r3498)
+++ trunk/apps/qubit/modules/informationobject/templates/editRadSuccess.php     
Thu Sep 24 12:45:33 2009        (r3499)
@@ -76,8 +76,9 @@
     </table>
 
     <div class="form-item">
-      <?php echo $form->repository->label(__('Repository'))->renderLabel() ?>
+      <?php echo $form->repository->renderLabel() ?>
       <?php echo $form->repository->render(array('class' => 
'form-autocomplete')) ?>
+      <input class="add" type="hidden" value="<?php echo 
url_for(array('module' => 'repository', 'action' => 'create')) ?> 
#authorized_form_of_name"/>
       <input class="list" type="hidden" value="<?php echo 
url_for(array('module' => 'repository', 'action' => 'list')) ?>"/>
     </div>
 

Modified: trunk/web/js/autocomplete.js
==============================================================================
--- trunk/web/js/autocomplete.js        Thu Sep 24 12:40:45 2009        (r3498)
+++ trunk/web/js/autocomplete.js        Thu Sep 24 12:45:33 2009        (r3499)
@@ -3,253 +3,465 @@
 Drupal.behaviors.autocomplete = {
   attach: function (context)
     {
-      $('select.form-autocomplete', context).each(function ()
+      $('form:has(select.form-autocomplete)', context).each(function ()
         {
-          // Share <select> with nested scopes
-          var select = this;
+          // Share <form> with nested scopes
+          var form = this;
 
-          // Make autocomplete <input>, copy @class from <select>, copy @id
-          // from <select> so <label for="..."> is correct
-          var input = $(<input class={$(this).attr('class')} 
id={$(this).attr('id')}/>.toXMLString()).insertAfter(this)[0]
-
-          if ($(this).attr('multiple'))
+          // Support multiple submit listeners which must all complete before
+          // form is submitted
+          var count = 0;
+          function done()
           {
-            // If multiple <select>, make <ul> of selected <option>s
-            var ul = $(<ul/>.toXMLString()).insertAfter(this)[0];
+            // Decrement count of listeners and submit if all done
+            if (1 > --count)
+            {
+              $(form)
 
-            $('option:selected', this).each(function ()
-              {
-                // Make <li> of hidden <input> with <option> value, and <span>
-                // with <option> HTML contents
-                $(<li><input name={$(select).attr('name')} type="hidden" 
value={$(this).val()}/><span>{XML($(this).html())}</span></li>.toXMLString())
-                  .click(function ()
-                    {
-                      // On click, remove <li>
-                      $(this).hide('fast', function ()
-                        {
-                          $(this).remove();
-                        });
-                    })
-                  .appendTo(ul);
-              });
-          }
-          else
-          {
-            // If single <select>, make one hidden <input> with <option> value,
-            var hidden = $(<input name={$(this).attr('name')} type="hidden" 
value={$(this).val()}/>.toXMLString()).insertAfter(this)[0];
+                // Unbind submit listeners to avoid triggering again
+                .unbind('submit')
 
-            // - and copy <option> value to autocomplete <input>
-            $(input).val($('option:selected', this).text());
+                .submit();
+            }
           }
 
-          // A following sibling with class .list and a value specifies that
-          // autocomplete items can be requested dynamically from the specified
-          // URI
-          var value = $('~ .list', this).val();
-          if (value)
-          {
-            // Split into URI and selector like jQuery load()
-            var [src, selector] = value.split(' ', 2);
-
-            var dataSource = new YAHOO.util.XHRDataSource(src);
-
-            // Cache at least one query so autocomplete items are only
-            // requested if the value of the autocomplete <input> changes
-            dataSource.maxCacheEntries = 1;
+          $('select.form-autocomplete', this).each(function ()
+            {
+              // Share <select> with nested scopes
+              var select = this;
 
-            dataSource.responseType = YAHOO.util.DataSourceBase.TYPE_HTMLTABLE;
+              // Make autocomplete <input>, copy @class from <select>, copy @id
+              // from <select> so <label for="..."> is correct
+              var input = $(<input class={$(this).attr('class')} 
id={$(this).attr('id')}/>.toXMLString()).insertAfter(this)[0]
 
-            // Overriding doBeforeParseData() and doBeforeCallback() not
-            // powerful enough, override parseHTMLTableData() and skip
-            // isArray(fields) check
-            dataSource.parseHTMLTableData = function (request, response)
+              if ($(this).attr('multiple'))
               {
-                var results = [];
-                $('tbody tr', response).each(function ()
+                // If multiple <select>, make <ul> of selected <option>s
+                var ul = $(<ul/>.toXMLString()).insertAfter(this)[0];
+
+                $('option:selected', this).each(function ()
                   {
-                    // For each item, select HTML contents and @href of <a> in
-                    // first cell
-                    results.push([$('td a', this).html(), $('td a', 
this).attr('href')]);
+                    // Make <li> of hidden <input> with <option> value, and
+                    // <span> with <option> HTML contents
+                    $(<li><input name={$(select).attr('name')} type="hidden" 
value={$(this).val()}/><span>{XML($(this).html())}</span></li>.toXMLString())
+                      .click(function ()
+                        {
+                          // On click, remove <li>
+                          $(this).hide('fast', function ()
+                            {
+                              $(this).remove();
+                            });
+                        })
+                      .appendTo(ul);
                   });
+              }
+              else
+              {
+                // If single <select>, make one hidden <input> with <option>
+                // value,
+                var hidden = $(<input name={$(this).attr('name')} 
type="hidden" value={$(this).val()}/>.toXMLString()).insertAfter(this)[0];
 
-                return { results: results };
-              };
-          }
-          else
-          {
-            // Otherwise add each enabled <option> to static list of items
-            var dataSource = new YAHOO.util.LocalDataSource();
+                // - and copy <option> value to autocomplete <input>
+                $(input).val($('option:selected', this).text());
+              }
 
-            $('option:enabled', this).each(function ()
+              // A following sibling with class .list and a value specifies
+              // that autocomplete items can be requested dynamically from the
+              // specified URI
+              var value = $('~ .list', this).val();
+              if (value)
               {
-                if ($(this).val())
-                {
-                  // For each item, select HTML contents and value of <option>
-                  //
-                  // Selecting HTML contents is important for <em>Untitled</em>
-                  dataSource.liveData.push([$(this).html(), $(this).val()]);
-                }
-              });
-          }
+                // Split into URI and selector like jQuery load()
+                var [src, selector] = value.split(' ', 2);
 
-          // Can't figure out how to get access to the DOM event which
-          // triggered a custom YUI event, so bind a listener to the
-          // interesting DOM event before instantiating the YUI widget, to save
-          // the DOM event before triggering custom YUI events
-          //
-          // TODO File YUI issue for this
-          var event;
-          $(input).keydown(function ()
-            {
-              event = arguments[0];
+                var dataSource = new YAHOO.util.XHRDataSource(src);
+
+                // Cache at least one query so autocomplete items are only
+                // requested if the value of the autocomplete <input> changes
+                dataSource.maxCacheEntries = 1;
+
+                dataSource.responseType = 
YAHOO.util.DataSourceBase.TYPE_HTMLTABLE;
+
+                // Overriding doBeforeParseData() and doBeforeCallback() not
+                // powerful enough, override parseHTMLTableData() and skip
+                // isArray(fields) check
+                dataSource.parseHTMLTableData = function (request, response)
+                  {
+                    var results = [];
+                    $('tbody tr', response).each(function ()
+                      {
+                        // For each item, select HTML contents and @href of <a>
+                        // in first cell
+                        results.push([$('td a', this).html(), $('td a', 
this).attr('href')]);
+                      });
 
-              // Tab key down
-              if (9 == event.keyCode)
+                    return { results: results };
+                  };
+              }
+              else
               {
-                autoComplete._onTextboxKeyDown(event, autoComplete);
+                // Otherwise add each enabled <option> to static list of items
+                var dataSource = new YAHOO.util.LocalDataSource();
 
-                // Call _onTextboxBlur() to trigger item select or unmatched
-                // item select custom YUI events
-                autoComplete._onTextboxBlur(event, autoComplete);
+                $('option:enabled', this).each(function ()
+                  {
+                    if ($(this).val())
+                    {
+                      // For each item, select HTML contents and value of
+                      // <option>
+                      //
+                      // Selecting HTML contents is important for
+                      // <em>Untitled</em>
+                      dataSource.liveData.push([$(this).html(), 
$(this).val()]);
+                    }
+                  });
               }
-            });
 
-          var autoComplete = new YAHOO.widget.AutoComplete(input, 
$(<div/>.toXMLString()).insertAfter(this)[0], dataSource);
+              // Can't figure out how to get access to the DOM event which
+              // triggered a custom YUI event, so bind a listener to the
+              // interesting DOM event before instantiating the YUI widget, to
+              // save the DOM event before triggering custom YUI events
+              //
+              // TODO File YUI issue for this
+              var event;
+              $(input).keydown(function ()
+                {
+                  event = arguments[0];
 
-          // http://developer.yahoo.com/yui/autocomplete/#force
-          autoComplete.forceSelection = true;
+                  // Tab key down
+                  if (9 == event.keyCode)
+                  {
+                    autoComplete._onTextboxKeyDown(event, autoComplete);
 
-          // Show some items even if user types nothing,
-          // http://developer.yahoo.com/yui/autocomplete/#minquery
-          autoComplete.minQueryLength = 0;
-
-          // Give user chance to type something, one second may still be too
-          // little, http://developer.yahoo.com/yui/autocomplete/#delay
-          autoComplete.queryDelay = 1;
-
-          // Start throbbing when first query is sent, stop throbbing when the
-          // last query to be sent is complete
-          //
-          // TODO This binds too many listeners and doesn't actually detect the
-          // last query to be sent : (
-          var id = 0;
-          autoComplete.dataRequestEvent.subscribe(function ()
-            {
-              var thisId = ++id;
+                    // Call _onTextboxBlur() to trigger item select or
+                    // unmatched item select custom YUI events
+                    autoComplete._onTextboxBlur(event, autoComplete);
+                  }
+                });
+
+              var autoComplete = new YAHOO.widget.AutoComplete(input, 
$(<div/>.toXMLString()).insertAfter(this)[0], dataSource);
 
-              $(input).addClass('throbbing');
+              // Show some items even if user types nothing,
+              // http://developer.yahoo.com/yui/autocomplete/#minquery
+              autoComplete.minQueryLength = 0;
+
+              // Give user chance to type something, one second may still be
+              // too little, http://developer.yahoo.com/yui/autocomplete/#delay
+              autoComplete.queryDelay = 1;
 
-              autoComplete.dataReturnEvent.subscribe(function ()
+              // Start throbbing when first query is sent, stop throbbing when
+              // the last query to be sent is complete
+              //
+              // TODO This binds too many listeners and doesn't actually detect
+              // the last query to be sent : (
+              var id = 0;
+              autoComplete.dataRequestEvent.subscribe(function ()
+                {
+                  var thisId = ++id;
+
+                  $(input).addClass('throbbing');
+
+                  autoComplete.dataReturnEvent.subscribe(function ()
+                    {
+                      if (id == thisId)
+                      {
+                        $(input).removeClass('throbbing');
+                      }
+                    });
+                });
+
+              autoComplete.itemSelectEvent.subscribe(function (type, args)
                 {
-                  if (id == thisId)
+                  if ($(select).attr('multiple'))
                   {
-                    $(input).removeClass('throbbing');
+                    // Cancel default action of saved DOM event so as not to
+                    // loose focus when selecting multiple items
+                    if (event)
+                    {
+                      event.preventDefault();
+                    }
+
+                    // If this item is already selected, highlight it,
+                    // otherwise add it to list of selected items
+                    if (!$('li:has(input[value=' + args[2][1] + '])', ul)
+                      .each(function ()
+                        {
+                          // Make background yellow for one second
+                          //
+                          // TODO Use CSS class
+                          var span = $('span', this).css('background', 
'yellow')[0];
+
+                          setTimeout(function ()
+                            {
+                              $(span).css('background', 'none');
+                            }, 1000);
+                        })
+                      .length)
+                    {
+                      // Make <li> of hidden <input> with item value, and
+                      // <span> with item HTML
+                      //
+                      // Use XML() constructor to insert parsed HTML, works for
+                      // strings without an <element> and strings with one root
+                      // <element>, but not, I suspect, for strings with
+                      // multiple root <element>s or text outside the root
+                      // <element>
+                      $(<li><input name={$(select).attr('name')} type="hidden" 
value={args[2][1]}/><span>{XML(args[2][0])}</span></li>.toXMLString())
+                        .click(function ()
+                          {
+                            // On click, remove <li>
+                            $(this).hide('fast', function ()
+                              {
+                                $(this).remove();
+                              });
+                          })
+                        .appendTo(ul);
+                    }
+
+                    // Select autocomplete <input> contents so typing will
+                    // replace it
+                    $(input).select();
+                  }
+                  else
+                  {
+                    // On single <select> item select, simply update the value
+                    // of this input
+                    $(hidden).val(args[2][1]);
                   }
+
+                  // Update the value of the autocomplete <input> here with
+                  // text of parsed HTML, instead of source
+                  //
+                  // Use XML() constructor as with multiple <select>, but use
+                  // toString() to get text of parsed HTML
+                  $(input).val(XML(args[2][0]));
                 });
-            });
 
-          autoComplete.itemSelectEvent.subscribe(function (type, args)
-            {
               if ($(select).attr('multiple'))
               {
-                // Cancel default action of saved DOM event so as not to loose
-                // focus when selecting multiple items
-                if (event)
+                // If multiple <select>, clear autocomplete <input> on blur
+                //
+                // TODO Don't clear if event.preventDefault() was called?
+                autoComplete.textboxBlurEvent.subscribe(function ()
+                  {
+                    $(input).val('');
+                  });
+              }
+
+              // Show autocomplete items, use named function so it can be bound
+              // to click and focus events, use private _nDelayID to cancel
+              // query on e.g. keypress before query delay
+              //
+              // TODO File YUI issue for this
+              function sendQuery()
+              {
+                if (-1 == autoComplete._nDelayID)
                 {
+                  autoComplete._nDelayID = setTimeout(function ()
+                    {
+                      autoComplete._sendQuery(autoComplete.getInputEl().value);
+                    }, autoComplete.queryDelay * 1000);
+                }
+              }
+
+              // Use custom YUI event to avoid DOM focus events triggered by
+              // YUI widget interaction
+              autoComplete.textboxFocusEvent.subscribe(sendQuery);
+
+              // Listen for click to show autocomplete items after selecting
+              // existing item, but not changing focus
+              $(input).click(sendQuery);
+
+              // A following sibling with class .add and a value specifies that
+              // new choices can be added to this input with a form at the
+              // specified URI, by copying the value of the autocomplete
+              // <input> to the element at the specified selector
+              //
+              // Use <iframe>s instead of XHR because I can't figure out how to
+              // get access to the Location: header of redirect responses, and
+              // can't figure out how to get access to the URI of the final
+              // response, http://www.w3.org/TR/XMLHttpRequest/#notcovered
+              var value = $('~ .add', this).val();
+              if (value)
+              {
+                // Split into URI and selector like jQuery load()
+                var [src, selector] = value.split(' ', 2);
+
+                // The following is for single <select>, it could be wrapped
+                // in, if (!$(select).attr('multiple')) ...
+
+                // Add hidden <iframe>, set width, height, and border to zero,
+                // don't use display: none, i.e. hide() because it might get
+                // ignored by some browsers,
+                // http://developer.apple.com/internet/webcontent/iframe.html
+                //
+                // Append to <body> instead of insert after <select> to avoid
+                // interfering with tabbing between inputs
+                var iframe = $(<iframe src={src}/>.toXMLString())
+                  .width(0)
+                  .height(0)
+                  .css('border', 0)
+                  .appendTo('body')[0];
+
+                // One submit handler per single <select>, use named function
+                // so it can be unbound on item select
+                function submit(event)
+                {
+                  // Delay submit till all listeners done
                   event.preventDefault();
+                  count++;
+
+                  $(iframe).one('load', function ()
+                    {
+                      // Update value of this input with URI of new resource
+                      $(hidden).val(this.contentDocument.location);
+
+                      // Decrement count of listeners and submit if all done
+                      done();
+                    });
+
+                  // Apply selector to <iframe> contents, update value of
+                  // selected element with value of the autocomplete <input>,
+                  // and submit selected element's form
+                  $($(selector, 
iframe.contentDocument).val($(input).val())[0].form).submit();
                 }
 
-                // If this item is already selected, highlight it, otherwise
-                // add it to list of selected items
-                if (!$('li:has(input[value=' + args[2][1] + '])', ul)
-                  .each(function ()
+                // Selecting existing item cancels addition of a new choice
+                autoComplete.itemSelectEvent.subscribe(function ()
+                  {
+                    $(form).unbind('submit', submit);
+                  });
+
+                // The following applies to both single and multiple <select>
+
+                autoComplete.unmatchedItemSelectEvent.subscribe(function ()
+                  {
+                    // Stop throbbing
+                    $(input).removeClass('throbbing');
+
+                    if ($(input).val())
                     {
-                      // Make background yellow for one second
-                      //
-                      // TODO Use CSS class
-                      var span = $('span', this).css('background', 
'yellow')[0];
+                      if ($(select).attr('multiple'))
+                      {
+                        // Cancel default action of saved DOM event so as not
+                        // to loose focus when selecting multiple items
+                        if (event)
+                        {
+                          event.preventDefault();
+                        }
 
-                      setTimeout(function ()
+                        // Add hidden <iframe> for each new choice
+                        var iframe = $(<iframe src={src}/>.toXMLString())
+                          .width(0)
+                          .height(0)
+                          .css('border', 0)
+                          .appendTo('body')[0];
+
+                        // One submit handler for each new choice, use named
+                        // function so it can be unbound if choice is removed
+                        function submit(event)
                         {
-                          $(span).css('background', 'none');
-                        }, 1000);
-                    })
-                  .length)
-                {
-                  // Make <li> of hidden <input> with item value, and <span>
-                  // with item HTML
-                  //
-                  // Use XML() constructor to insert parsed HTML, works for
-                  // strings without an <element> and strings with one root
-                  // <element>, but not, I suspect, for strings with multiple
-                  // root <element>s or text outside the root <element>
-                  $(<li><input name={$(select).attr('name')} type="hidden" 
value={args[2][1]}/><span>{XML(args[2][0])}</span></li>.toXMLString())
-                    .click(function ()
-                      {
-                        // On click, remove <li>
-                        $(this).hide('fast', function ()
-                          {
-                            $(this).remove();
-                          });
-                      })
-                    .appendTo(ul);
-                }
+                          // Delay submit till all listeners done
+                          event.preventDefault();
+                          count++;
+
+                          $(iframe).one('load', function ()
+                            {
+                              // Make <input> with URI of new resource as its
+                              // value
+                              $(<input name={$(select).attr('name')} 
value={this.contentDocument.location}/>.toXMLString()).appendTo(li);
+
+                              // Decrement count of listeners and submit if all
+                              // done
+                              done();
+                            });
+
+                          // Apply selector to <iframe> contents, update value
+                          // of selected element with text of the new choice,
+                          // and submit selected element's form
+                          $($(selector, 
iframe.contentDocument).val($(clone).val())[0].form).submit();
+                        }
+
+                        // Make <li>
+                        var li = $(<li/>.toXMLString())
+                          .click(function (event)
+                            {
+                              // On click, remove <li> and cancel addition of
+                              // new choice, unless user clicked on new choice
+                              // <input>
+                              if (clone != event.target)
+                              {
+                                $(this).hide('fast', function ()
+                                  {
+                                    $(this).remove();
+                                  });
+
+                                // Cancel addition of new choice
+                                $(form).unbind('submit', submit);
+                              }
+                            })
+                          .appendTo(ul)[0];
+
+                        // Make new choice <input> by cloning autocomplete
+                        // <input>
+                        var clone = $(input)
+                          .clone()
+
+                          // Remove class to hide throbber
+                          .removeClass('form-autocomplete')
+
+                          .blur(function ()
+                            {
+                              // On blur, remove <li> and cancel addition of
+                              // new choice, if text of the new choice was
+                              // cleared
+                              if (!$(this).val())
+                              {
+                                $(li).hide('fast', function ()
+                                  {
+                                    $(this).remove();
+                                  });
+
+                                // Cancel addition of new choice
+                                $(form).unbind('submit', submit);
+                              }
+                            })
+                          .appendTo(li)[0];
+
+                        // Select autocomplete <input> contents so typing will
+                        // replace it
+                        $(input).select();
+                      }
 
-                // Select autocomplete <input> contents so typing will replace
-                // it
-                $(input).select();
+                      // Listen for form submit
+                      //
+                      // Trick, if single <select>, listener will be from
+                      // parent scope. If multiple <select>, listener will be
+                      // from this scope, where it is wrapped in, if
+                      // ($(select).attr('multiple')) ...
+                      //
+                      // This is because listeners have the same name in each
+                      // scope, and it will get overridden if the if statement
+                      // evaluates
+                      $(form).submit(submit);
+                    }
+                    else
+                    {
+                      // If unmatched item is empty, cancel addition of new
+                      // single <select> choice
+                      $(form).unbind('submit', submit);
+                    }
+                  });
               }
               else
               {
-                // On single <select> item select, simply update the value of
-                // this input
-                $(hidden).val(args[2][1]);
+                // Otherwise new choices can't be added to this input,
+                // http://developer.yahoo.com/yui/autocomplete/#force
+                autoComplete.forceSelection = true;
               }
 
-              // Update the value of the autocomplete <input> here with text
-              // of parsed HTML, instead of source
-              //
-              // Use XML() constructor as with multiple <select>, but use
-              // toString() to get text of parsed HTML
-              $(input).val(XML(args[2][0]));
+              // Finally remove <select> element
+              $(this).remove();
             });
-
-          if ($(select).attr('multiple'))
-          {
-            // If multiple <select>, clear autocomplete <input> on blur
-            //
-            // TODO Don't clear if event.preventDefault() was called?
-            autoComplete.textboxBlurEvent.subscribe(function ()
-              {
-                $(input).val('');
-              });
-          }
-
-          // Show autocomplete items, use named function so it can be bound to
-          // click and focus events, use private _nDelayID to cancel query on
-          // e.g. keypress before query delay
-          //
-          // TODO File YUI issue for this
-          function sendQuery()
-          {
-            if (-1 == autoComplete._nDelayID)
-            {
-              autoComplete._nDelayID = setTimeout(function ()
-                {
-                  autoComplete._sendQuery(autoComplete.getInputEl().value);
-                }, autoComplete.queryDelay * 1000);
-            }
-          }
-
-          // Use custom YUI event to avoid DOM focus events triggered by YUI
-          // widget interaction
-          autoComplete.textboxFocusEvent.subscribe(sendQuery);
-
-          // Listen for click to show autocomplete items after selecting
-          // existing item, but not changing focus
-          $(input).click(sendQuery);
-
-          // Finally remove <select> element
-          $(this).remove();
         });
     } };

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Qubit Toolkit Commits" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.ca/group/qubit-commits?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to