Drupal 7 tip: Hoe verander je de jquery autocomplete callback bij een gebeurtenis

Posted by: 
Dominique De Cooman

In deze post zal ik uitleggen hoe je de autocomplete callback kunt veranderen bij een gebeurtenis. We moeten scholen selecteren. Deze scholen zijn getagged met een taxonomy term divisie. In ons zoekveld hebben we een tekstveld dat een autocomplete callback doet en suggesties voor scholen geeft tijdens het typen. Dit is slechts een kernfunctie. Hieronder hebben we een select welke de divisie selecteert waar onze scholen zich bevinden. Nu moeten we onze autocomplete resultaten beperken tot deze geselecteerde divisie. Om dat te doen moeten we de jquery autocomplete callback bij het wisselen van de divisie dynamisch veranderen.

<?php  
    $form
['school_name'] = array(
      
'#type' => 'textfield',
      
'#placeholder' => t('School name'),
      
'#size' => 25,
      
'#default_value' => isset($_GET['search_api_views_fulltext']) ? $_GET['search_api_views_fulltext'] : '',
      
'#autocomplete_path' => 'so_search/school_name/autocomplete/' $division,      
    );
    
    
$divisions so_search_get_divisions();
    
$form['divisions'] = array(
      
'#type' => 'select',
      
'#title' => '',
      
'#options' => $divisions,
    );

    
drupal_add_js(drupal_get_path('module''so_search') . '/js/dynamicautocomplete.js');
    
drupal_add_js(array('dynamicAutocomplete' => array('autocompleteUrl' => 'http://' $_SERVER['HTTP_HOST'] . '/so_search/school_name/autocomplete/')), 'setting');

?>

Dit bevat een basisvorm definitie en bevestigd het javascript.

<?php
function _so_search_schoolname_autocomplete($tid 0$string) {
  
$matches = array();
  
$query db_select('node''n');
  
$query->fields('n', array('title''nid'));
  
$query->condition('type''school');
  
$query->condition('title''%' check_plain($string) . '%''LIKE');

  
//If a division is set limit list on division
  
if ($tid) {
    
$query->innerJoin('taxonomy_index''ti''ti.nid = n.nid');
    
$query->condition('ti.tid'$tid);
  }
  
$query->range(018);
  
$return $query->execute();

  
// add matches to $matches 
  
foreach ($return as $row) {
    
$matches[$row->title] = check_plain($row->title);
  }

  
// return for JS
  
drupal_json_output($matches);
}
?>

Dit is de callback voor de autocomplete. Het is slechts hier als voorbeeld.

Dit is de benodigde jquery om het te laten werken.

    (function ($) {
 
    /**
     * Attaches the autocomplete behavior to all required fields.
     */
    Drupal.behaviors.dynamicAutocomplete = {
      attach: function (context, settings) {
        $('#edit-divisions').change(function(i) {
          var str = $('#edit-divisions_child a.selected').attr('id');
          var n = str.replace("edit-divisions_msa_",""); 
          Drupal.behaviors.dynamicAutocompleteAttach(n);
        });
      }
    };
 
    Drupal.behaviors.dynamicAutocompleteAttach = function (division) {    
      $('#edit-school-name').unbind().val('');
      $('#edit-school-name').each(function(i) {
      //Get the (hidden) *-autocomplete input element
      var input_autocomplete = $('#edit-school-name-autocomplete');
      // Update autocomplete url
      input_autocomplete.val(Drupal.settings.dynamicAutocomplete.autocompleteUrl + division);
      // Mark as not processed.
      input_autocomplete.removeClass('autocomplete-processed');
      //Call autocomplete
 
    });  
      Drupal.behaviors.autocomplete.attach(document);
    };
 
    })(jQuery);

Wat we doen is het volgende. We nemen de edit-divisions element en we koppelen een jquery change event handler eraan. We krijgen de juisten divisie van de id en geven het aan onze functie die de bestaande callback zal ontbinden. Vervolgens krijgen we de verborgen autocomplete element en stellen we het in met onze nieuwe url die de nieuwe waardes bevat. Nu moeten we de element als unprocessed markeren. Het enige wat nog gedaan moet worden is de Drupal.behaviors.autocomplete.attach callback oproepen en het zal alle elements opnieuw verwerken en de nieuwe callback oppikken.

Met gebruik van deze flow zou je in staat moeten zijn om de callback van elke autocomplete form element bij elke gebeurtenis te veranderen.

Reactie toevoegen