2009-06-19 3 views
5

Drupal hat eine sehr gut aufgebaute, jQuery-basierte autocomplete.js. Normalerweise müssen Sie sich nicht darum kümmern, da Konfiguration und Ausführung von der Drupal-Formular-API gehandhabt werden.Wie kann Drupal jQuery-basierte Autocomplete zur Laufzeit dynamisch neu konfiguriert werden?

Jetzt brauche ich eine Möglichkeit, es zur Laufzeit (mit JavaScript, das ist) zu rekonfigurieren. Ich habe ein Dropdown-Auswahlfeld mit einem Textfeld daneben. Je nachdem, welche Option im Auswahlfeld ausgewählt ist, muss ich verschiedene URLs für die automatische Vervollständigung aufrufen. Bei einer dieser Optionen sollte die automatische Vervollständigung deaktiviert sein. Ist es möglich, die vorhandene Autocomplete-Instanz neu zu konfigurieren, oder muss ich sie irgendwie zerstören und neu erstellen?

Antwort

3

Nun, als Referenz habe ich einen Hack zusammengewürfelt, der funktioniert, aber wenn jemand an eine bessere Lösung denken kann, würde ich mich freuen, es zu hören.

Drupal.behaviors.dingCampaignRules = function() { 
    $('#campaign-rules') 
    .find('.campaign-rule-wrap') 
     .each(function (i) { 
      var type = $(this).find('select').val(); 

      $(this).find('.form-text') 
      // Remove the current autocomplete bindings. 
      .unbind() 
      // And remove the autocomplete class 
      .removeClass('form-autocomplete') 
      .end() 
      .find('select:not(.dingcampaignrules-processed)') 
      .addClass('dingcampaignrules-processed') 
      .change(Drupal.behaviors.dingCampaignRules) 
      .end(); 

      if (type == 'page' || type == 'library' || type == 'taxonomy') { 
      $(this).find('input.autocomplete') 
       .removeClass('autocomplete-processed') 
       .val(Drupal.settings.dingCampaignRules.autocompleteUrl + type) 
      .end() 
      .find('.form-text') 
       .addClass('form-autocomplete'); 
      Drupal.behaviors.autocomplete(this); 
      } 
     }); 
}; 

Dieser Code stammt aus dem ding_campaign module. Fühlen Sie sich frei, den Code zu überprüfen, wenn Sie etwas Ähnliches tun müssen. Es ist alles GPL2.

1

sollte es so einfach sein, wie dynamisch ändern Sie den "Wert" der "verdeckten" Autovervollständigung Eingabeelement, das neben Autovervollständigen Formularfelder kommt. dh.

$('select#myelement').bind('change', function(e) { 
    if (/* something */) { 
    $('input#myelement-autocomplete').attr('value', '/mycustom/path'); 
    } 
}); 
+0

, die nicht zur Arbeit erscheint. Anscheinend wird die URL irgendwo im JavaScript gespeichert und nicht erneut aus dem Eingabefeld gelesen. – mikl

+1

Sie müssen auch die Klasse "autocomplete-processed" aus dem ausgeblendeten Feld entfernen und dann das Autocomplete-Verhalten durch Aufrufen von 'Drupal.behaviors.autocomplete (document);'. – sepehr

+0

es funktioniert, aber eine neue URL wird bei jeder Änderung registriert, wenn 2 mal es wieder angeschlossen wird, werden insgesamt 3 Anrufe an Server –

4

Werfen Sie einen Blick auf misc/autocomplete.js.

/** 
* Attaches the autocomplete behavior to all required fields 
*/ 
Drupal.behaviors.autocomplete = function (context) { 
    var acdb = []; 
    $('input.autocomplete:not(.autocomplete-processed)', context).each(function() { 
    var uri = this.value; 
    if (!acdb[uri]) { 
     acdb[uri] = new Drupal.ACDB(uri); 
    } 
    var input = $('#' + this.id.substr(0, this.id.length - 13)) 
     .attr('autocomplete', 'OFF')[0]; 
    $(input.form).submit(Drupal.autocompleteSubmit); 
    new Drupal.jsAC(input, acdb[uri]); 
    $(this).addClass('autocomplete-processed'); 
    }); 
}; 

Der VALUE-Attribut des Eingangs wird verwendet ACDB zu schaffen, die ein Cache von Werten für diesen automatischen Vervollständigung Pfad (uri). Das ist in der Drupal.jsAC Funktion des Elements keydown, keyup und Unschärfe Ereignisse binden mit Triggern der automatischen Vervollständigung ajax Betrieb (die für das Element seine Werte in dem Objekt ACDB Caches) öffnet popups usw.

/** 
* An AutoComplete object 
*/ 
Drupal.jsAC = function (input, db) { 
    var ac = this; 
    this.input = input; 
    this.db = db; 

    $(this.input) 
    .keydown(function (event) { return ac.onkeydown(this, event); }) 
    .keyup(function (event) { ac.onkeyup(this, event); }) 
    .blur(function() { ac.hidePopup(); ac.db.cancel(); }); 

}; 

Sie müssen den Wert der Eingabe ändern und das Verhalten erneut festlegen. Sie fügen das Verhalten erneut hinzu, indem Sie die Klasse ".autocomplete-processed" für das Eingabeelement für die Autovervollständigung entfernen und dann Drupal.attachBehaviors (thatInputElement) aufrufen.

Dies funktioniert möglicherweise nicht. Dinge können sehr schlecht gehen, wenn Sie dasselbe Verhalten immer wieder an dasselbe Element anhängen. Es kann sinnvoller sein, verschiedene Autocomplete-Felder zu erstellen und diese basierend auf dem Wert der Auswahl einfach auszublenden und anzuzeigen. Dies würde immer noch den Aufruf von Drupal.attachBehaviors erfordern, wenn Sie das Widget ausblenden und anzeigen. Das gleiche Verhalten bleibt jedoch bestehen, wenn der Wechsel mehr als einmal erfolgt und Sie nicht riskieren, dasselbe Element mehrfach mit demselben Verhalten zu verknüpfen.

+0

gemacht Nun, ich bin keineswegs ein JavaScript-Experte, aber sollte es nicht möglich sein, die Werte zu ändern in JavaScript anstelle der "nuklearen" Option, die Autocomplete jedes Mal zu zerstören und neu zu erstellen? – mikl

+0

Da die URLs im Array abcd [] zwischengespeichert werden, müssen Sie das Verhalten erneut anfügen, um es zu aktualisieren, und wenn Sie das tun, sollten Sie alle vorhergehenden Ereignisse, die zuvor an das Autocomplete-Element gebunden waren, aufheben. – gpilotino

+0

Ich habe es geschafft, die Bindung aufzuheben und das Verhalten wieder zu aktivieren, aber führt das dazu, dass das alte Autocomplete-Objekt als Garbage Collection erfasst wird? Andernfalls wird Speicher verloren gehen. Es ist wahrscheinlich keine große Sache, aber es ist ausgesprochen unpretty :) – mikl

1

Arbeitslösung für Drupal

/* 
* Błażej Owczarczyk 
* [email protected] 
* 
* Name: Autocomplete City Taxonomy 
* Description: Hierarchical city selecting (province select and city autocomplete) 
*/ 

var Act = Act || {}; 

Act.init = function() { 
    $('select.act-province').change(Act.provinceChange);  // select with top taxonomy terms  
} 

/* 
* Change event of select element 
*/ 
Act.provinceChange = function() { 
    var context = $(this).parent().parent();    
    var currentTid = $(this).val(); 
    Act.rewriteURI(context, currentTid); 
    Act.unbind(); 
    Drupal.autocompleteAutoAttach(); 
}; 

/* 
* Changes the value of hidden autocomplete input 
*/ 
Act.rewriteURI = function (context, newTid) { 
    var tempArray; 
    tempArray = $('.autocomplete', context).val().split('/'); 
    tempArray.pop(); 
    tempArray.push(newTid); 
    $('.autocomplete', context).val(tempArray.join('/'));  
}; 

/* 
* Prevents muliple binding of the same events 
*/ 
Act.unbind = function() { 
    $('.form-autocomplete').unbind().parents('form').unbind('submit'); 
}; 

$(document).ready(Act.init); 
Verwandte Themen