ejui-autocomplete-fk-field CJuiAutoComplete widget for FK field of a model

  1. Summary
  2. Requirements
  3. Questions
  4. Usage

Summary

The EJuiAutoCompleteFKField extension renders a CJuiAutoComplete field plus supporting form fields for a FK field. Typically it is used for a model with a foreign key field to a parent table that has too many records for a drop-down list to be practical.

For example it could be used in a Contact table, with a foreign key to a PostCode table with thousands of records, one for each city / postcode combination. The user would type the city name in the AutoCompleter, and the PostCodeId would be stored in the correct model column; while the display attribute (e.g. City, Province) is shown in the form.

The extension renders the following:

  • the model field itself, which may optionally be hidden or visible
  • a hidden field that holds the description field of the FK record, for redisplay if the user fails to choose a value from the autoCompleter
  • the AutoComplete field itself, which also displays the existing value from the related record
  • a 'delete' icon to clear all three fields
  • javascript to tie everything together

Requirements

Yii 1.1+

Questions

Questions can be posted to this Forum Topic

Usage

1) unzip the extension into ../extensions/

2) make sure config/main.php has:

import=>array(
          'application.extensions.*',
          ...
      ),

3) ensure the relationship exists in the model: in Contacts.php (example):

'relations'=>array(
      'Postcode'=>array(self::BELONGS_TO, 'PostCodes', 'PostCodeId'),
      ...
  );

4) in the related table, optionally create a pseudo-attribute for display purposes. For example in PostCodes.php:

public function getPostCodeAndProvince() {
      // presuming PostCode, City and Province are fields
      return $this->City . ', ' . $this->Province . ' (' . $this->PostCode . ')'; 
 }

5) in the _form.php for the main record (e.g. Contacts)

echo $form->labelEx($model, 'PostCodeId');
 $this->widget('EJuiAutoCompleteFkField', array(
      'model'=>$model, 
      'attribute'=>'PostCodeId', //the FK field (from CJuiInputWidget)
      // controller method to return the autoComplete data (from CJuiAutoComplete)
      'sourceUrl'=>Yii::app()->createUrl('/contacts/findPostCode'), 
      // defaults to false.  set 'true' to display the FK field with 'readonly' attribute.
      'showFKField'=>true,
       // display size of the FK field.  only matters if not hidden.  defaults to 10
      'FKFieldSize'=>15, 
      'relName'=>'Postcode', // the relation name defined above
      'displayAttr'=>'PostCodeAndProvince',  // attribute or pseudo-attribute to display
      // length of the AutoComplete/display field, defaults to 50
      'autoCompleteLength'=>60,
      // any attributes of CJuiAutoComplete and jQuery JUI AutoComplete widget may 
      // also be defined.  read the code and docs for all options
      'options'=>array(
          // number of characters that must be typed before 
          // autoCompleter returns a value, defaults to 2
          'minLength'=>3, 
      ),
 ));
 echo $form->error($model, 'PostCodeId');

6) in the Controller for the model, create a method to return the autoComplete data.

NOTE: make sure to give users the correct permission to execute this method, according to your security scheme

in ContactsController.php (for example):

// data provider for EJuiAutoCompleteFkField for PostCodeId field
   public function actionFindPostCode() {
       $q = $_GET['term'];
       if (isset($q)) {
           $criteria = new CDbCriteria;
           //condition to find your data, using q as the parameter field
           $criteria->condition = '...', 
           $criteria->order = '...'; // correct order-by field
           $criteria->limit = ...; // probably a good idea to limit the results
           // with trailing wildcard only; probably a good idea for large volumes of data
           $criteria->params = array(':q' => trim($q) . '%'); 
           $PostCodes = PostCodes::model()->findAll($criteria);

           if (!empty($PostCodes)) {
               $out = array();
               foreach ($PostCodes as $p) {
                   $out[] = array(
                       // expression to give the string for the autoComplete drop-down
                       'label' => $p->PostCodeAndProvince,  
                       'value' => $p->PostCodeAndProvince,
                       'id' => $p->PostCodeId, // return value from autocomplete
                   );
               }
               echo CJSON::encode($out);
               Yii::app()->end();
           }
       }
   }

7) in the Controller loadModel() method, return the related record in ContactsController.php (for example)

public function loadModel() {
      ...
      if (isset($_GET['id']))
               // NOTE 'with()'
               $this->_model=Contacts::model()->with('Postcode')->findbyPk($_GET['id']); 
      ...
 }
17 0
28 followers
2 696 downloads
Yii Version: 1.1
License: BSD-2-Clause
Category: User Interface
Developed by: jeremy
Created on: Mar 7, 2011
Last updated: 13 years ago

Downloads

show all

Related Extensions