I have created a extension acSelect.
http://www.yiiframew…nsion/acselect/
acSelect (autocomplete Select) uses the CAutocomplete class to have a quick selection of entries and displays some selected data of the selected entry.
It useful on administration forms when you have to select a id from a foreign key.
e.g if you have a address list where you have company connected to each address, or a user table where a field address_id is associated with a address table with lots of entries.
If you click on the change button a searchfield will be displayed.
On enter a ajax request will be sent to a widget action class which generates the result and use the cautocomplete class to create a select field.
On select of on entry the search input field will be hided and the key of the selected entry will be set in a hidden value for further actions like saving into the database.
The "info" will display some fields of the selected entry.
The widget selects the columns defined via the colModel property (only the columns given) and make a ajax call to an action class which generates the select, queries and return the requested values via json.
This is then used together with CAutocomplete to generate the select field.
It supports the usage of searchpatterns e.g. like google usage of 'site:wwwyiiframework.com'.
the following search string would result in these sql where clauses(colmodel form the example below):
input => generated sql query where part
'test' => where default_column like '%test%' (e.g. lastname)
'lastname:mayer' => where lastname like '%mayer%'
'lastname:mayer firstname:bernhard' => where lastname like '%mayer%' and firstname like '%bernhard%'
'mayer firstname:bernhard' => where lastname like '%mayer%' and firstname like '%bernhard%'
'mayer vorfelder' => where lastname like '%mayer%' and lastname like '%vorfelder%'
‘“mayer vorfelder”’ => where lastname like ‘%mayer vorfelder%’ (quotes! used " ")
'id:2' => where id = 2 (id column is of type integer)
Each searchpart is divided with blank ' '. Multiple search parts will be connected with ' and ' in the searchquery. For strings table columns the like operator is used, for columns of type integer '=' to search for values.
If you want to search in multiple columns with one searchpattern you can just add the same pattern to multiple columns in the colModel property.
e.g.
$colModel['Company'] = array('Name','name','name',2); // searchable and default $colModel['Address1'] = array('Address1','address1','street',1); // searchable $colModel['Address2'] = array('Address2','address2','street',1); // searchable $colModel['Address3'] = array('Address3','address3','street',1); // searchable
with 'street:streetname' would create the query:
where (Address1 like '%streetname%' or Address2 like '%streetname%' orAddress3 like '%streetname%' )
Possibilities like to search for 'Lastname:mayer street:"streetname with blank" country:france' are possible.
This would create
where lastname like '%mayer%' and street like '%streetname with blank%' and country like '%france%'
The usage of the widget is quite easy:
<div class="simple"> <?php echo CHtml::activeLabel($userlist,'AddressID'); /* * which fields should be displayed in the info part * label => columns of model to display */ $info_fields=array( 'Name'=>array('FirstName','LastName'), 'EMail'=>array('EMail'), 'Country'=>array('Country'), ); /* * glue for multiple columns if no glue value is given <br /> is used */ $info_glues=array( 'Name'=>' ', ); /* js list pattern for the drop down list */ $list_pattern="'<small>'+i + '/' + max + ':</small> <b>' + row.lastname +' '+row.firstname+ '</b><br /><small>'+ row.email+ ' '+ row.country+ '</small>'"; /* * set colModel (columns to select for display and return) * tablecolumn => options * 0 - display name ( not used yet maybe for generated js info pattern etc. * 1 - datafield * 2 - searchpattern eg. name: country: * 3 - searchable (2 -> yes and default, 1 -> yes, 0 -> no.) */ $colModel=array(); $colModel['ID'] = array('ID','id','id',1); // searchable $colModel['LastName'] = array('LastName','lastname','lastname',2); // searchable and default $colModel['FirstName'] = array('FirstName','firstname','firstname',1); // searchable $colModel['EMail'] = array('EMail','email','email',1); // searchable $colModel['Country'] = array('Country','country','country',1); // searchable $ac_select_options=array( 'model' =>$userlist, // your model object of the admin form 'select_model'=> addresslist::model(), // model class of the selection 'attribute' => "AddressID", // which attribute 'actionPrefix'=>'pro.', // has to be the same as in the controller 'name'=>'AddressID', // name 'colmodel'=>$colModel, 'buttonLabel'=>'User', // label of the change button 'change ...' 'default_search_data_field'=>'lastname', // default data field for setting in the search field 'default_data_field'=>'id', // default data field for setting the value of the hidden field on selection 'info_fields'=>$info_fields, 'info_glues'=>$info_glues, 'list_pattern'=>$list_pattern, ); $ACSelectobj=$this->createWidget('application.extensions.acselect.ACSelect',$ac_select_options); $ACSelectobj->run(); ?> </div>
The only thing you must add to your controller is
public function actions() { return array( 'pro.'=>'application.extensions.acselect.ACSelect', ) }
There are some more settings and properties which are currently only commented in the widget source code.
Qtip is currently in the extension and is used to create a help tip for the user, to display the available searchpatterns.
This widget requires Sessions ! It doesn’t work without, because the action classes have no other options to get variables set in the widget class.
Updates:
08.04.2009 fixed a small bug where a firephp instance was used in ACSelectAction class if not found.