Discussion and Questions on EJuiAutoCompleteFkField
#1
Posted 05 April 2011 - 01:34 PM
#2
Posted 05 April 2011 - 02:28 PM
My tables:
CREATE TABLE school ( idschool INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(40) NOT NULL, PRIMARY KEY(idschool) ); CREATE TABLE student ( idstudent INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, idschool INTEGER UNSIGNED NOT NULL, name VARCHAR(40) NOT NULL, PRIMARY KEY(idstudent), FOREIGN KEY(idschool) REFERENCES school(idschool) );
Relation:
A school has many students
A student belongs to a school
Steps
1)unzip extension - checked
2)make sure config/main.php has - checked
import=>array(
'application.extensions.*',
...
),
3)ensure the relationship exists in the model - checked
student.php (Model) - checked
public function relations()
{
return array(
'schoolx' => array(self::BELONGS_TO, 'School', 'idschool'),
);
}
4) optionally - I'll use the normal attribute (name)
5)in the _form.php (student)
echo $form->labelEx($model, 'idschool');
$this->widget('EJuiAutoCompleteFkField', array(
'model'=>$model,
'attribute'=>'idschool',
'sourceUrl'=>'findSchool',
'showFKField'=>true,
'FKFieldSize'=>15,
'relName'=>'schoolx',
'displayAttr'=>'name',
'autoCompleteLength'=>40,
));
echo $form->error($model,'idschool');
6)in controller the method to return the autoComplete data. (StudentController.php)
public function actionFindSchool() {
$q = $_GET['term'];
if (isset($q)) {
$criteria = new CDbCriteria;
$criteria->condition = 'name like :q';
$criteria->order = 'name asc';
$criteria->limit = 10;
$criteria->params = array(':q' => trim($q) . '%');
$schools = school::model()->findAll($criteria);
if (!empty($schools)) {
$out = array();
foreach ($schools as $p) {
$out[] = array(
'label' => $p->name,
'value' => $p->name,
'id' => $p->idschool,
);
}
echo CJSON::encode($out);
Yii::app()->end();
}
}
}
7) in the Controller loadModel() method. (StudentController.php)
public function loadModel()
{
if($this->_model===null)
{
if(isset($_GET['id']))
$this->_model=student::model()->with('schoolx')->findbyPk($_GET['id']);
if($this->_model===null)
throw new CHttpException(404,'The requested page does not exist.');
}
return $this->_model;
}
<?php while(!($succeed=try())); ?>
#4
Posted 05 April 2011 - 03:29 PM
jeremy, on 05 April 2011 - 03:18 PM, said:
The text field is not receiving data for autocompletion.
<?php while(!($succeed=try())); ?>
#5
Posted 05 April 2011 - 03:34 PM
to debug this problem you should use several tools:
1) in Firefox browser, install Firebug. Enable firebug. When you type in the auto-Complete field, watch the POST data and the response. See if an error is generated
2) you need a programming editor with debugger installed. I use NetBeans 6.9.1 and Xdebug. Installing and configuring Xdebug for apache is beyond the scope of help I can offer; but there are plenty of tips in the forum and you can google it.
after xdebug is installed and working properly then you should set a breakpoint in the actionFindSchool() method and step-through to see if any data is selected and returned.
Another option is to trace the SQL commands generated in yii. in config/main, for the 'log' component, change 'levels'=>'error,warning,trace',
add 'categories'=>'system.db.*',
then tail the application.log and see if the SQL being generated makes sense. If it does, paste the generated SQL into whatever db front-end tool you use and see what results you get.
#6
Posted 06 April 2011 - 03:56 PM
The requested URL was with the status: 404 Not Found.
Observe an example of a call: http://localhost/for...School?term=anh
Solution:
In the _form.php (student)
echo $form->labelEx($model, 'idschool');
$this->widget('EJuiAutoCompleteFkField', array(
'model'=>$model,
'attribute'=>'idschool',
'sourceUrl'=>'index.php?r=student/findSchool',
'showFKField'=>true,
'FKFieldSize'=>15,
'relName'=>'schoolx',
'displayAttr'=>'name',
'autoCompleteLength'=>40,
));
Thanks Jeremy! His answer was very helpful.
Excuse my english, I am a brazilian with bad english. The post was based on the translator.
<?php while(!($succeed=try())); ?>
#7
Posted 06 June 2011 - 10:03 PM
Q. By the way, what is the expected behavior of the widget on UPDATE ?
I mean it works great for CREATE, but on Update although it shows the correct data, when it is changed the autocomplete is not triggered
Is there something else that I have missed that is needed to allow same functionality on UPDATE to work ?
thanks much !
Mac OS X 10.6.7 - PHP Version 5.3.2 - PHPUnit 3.5.13 - Yii 1.1.7
#8
Posted 06 June 2011 - 10:21 PM
- Jeremy
1661design, on 06 June 2011 - 10:03 PM, said:
Q. By the way, what is the expected behavior of the widget on UPDATE ?
I mean it works great for CREATE, but on Update although it shows the correct data, when it is changed the autocomplete is not triggered
Is there something else that I have missed that is needed to allow same functionality on UPDATE to work ?
thanks much !
#9
Posted 06 June 2011 - 10:32 PM
I did notice the [x] to remove the value, but when typing again the term request is not being triggered at all
Mac OS X 10.6.7 - PHP Version 5.3.2 - PHPUnit 3.5.13 - Yii 1.1.7
#10
Posted 06 June 2011 - 10:35 PM
<?php echo $form->hiddenField($model,'ubicacion', array('readonly'=>'readonly')); ?>
<?php $this->widget('EJuiAutoCompleteFkField',array(
'model'=>$model,
'attribute'=>'ubicacion', //the FK field (from CJuiInputWidget)
// controller method to return the autoComplete data (from CJuiAutoComplete)
'sourceUrl'=>'buscaUbicacion',
// defaults to false. set 'true' to display the FK field with 'readonly' attribute.
'showFKField'=>false,
// display size of the FK field. only matters if not hidden. defaults to 10
'FKFieldSize'=>11,
'relName'=>'LocatedIn', // the relation name defined above
'displayAttr'=>'descripcionYUbicacion', // attribute or pseudo-attribute to display
// length of the AutoComplete/display field, defaults to 50
'autoCompleteLength'=>50,
// 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,
),
)); ?>
Mac OS X 10.6.7 - PHP Version 5.3.2 - PHPUnit 3.5.13 - Yii 1.1.7
#11
Posted 06 June 2011 - 10:42 PM
Mac OS X 10.6.7 - PHP Version 5.3.2 - PHPUnit 3.5.13 - Yii 1.1.7
#12
Posted 07 June 2011 - 06:58 AM
[edit]
I tried again - actually the extension *does* work properly when over-typing. Please try again now that you have the controller method set correctly, and see if it works.
[/edit]
One other question: why are you putting a hidden field of the model attribute, before the autocompleter? It renders such a hidden field on its own....
1661design, on 06 June 2011 - 10:42 PM, said:
#13
Posted 07 June 2011 - 09:15 PM
Sorry I didn't update, in fact I removed the hidden field in the final working solution. But the working solution has IMHO two important elements:
- sourceUrl should not use 'controller/action' notation alone since in update the rendered URL is corrupted
- validation rule for the attribute should NOT use: array('attribute','exist') for some reason that I don't understand such validation fails on UPDATE even though the value exist. It shows a message: <attribute> "<value>" is invalid. Not sure if it's a bug in the CExistValidator implementation or the EJuiAutoCompleteFkField or I misunderstood the 'exist' validation concept.
<div class="row">
<?php echo $form->labelEx($model,'ubicacion'); ?>
<?php $this->widget('EJuiAutoCompleteFkField',array(
'model'=>$model,
'attribute'=>'ubicacion', //the FK field (from CJuiInputWidget)
// controller method to return the autoComplete data (from CJuiAutoComplete)
'sourceUrl'=>Yii::app()->createUrl("/banco/buscaUbicacion"),
// defaults to false. set 'true' to display the FK field with 'readonly' attribute.
'showFKField'=>false,
// display size of the FK field. only matters if not hidden. defaults to 10
'FKFieldSize'=>11,
'relName'=>'LocatedIn', // the relation name defined above
'displayAttr'=>'descripcionYUbicacion', // attribute or pseudo-attribute to display
// length of the AutoComplete/display field, defaults to 50
'autoCompleteLength'=>50,
// 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,
),
)); ?>
<?php echo $form->error($model,'ubicacion'); ?>
</div>
thanks again Jeremy for this extension, it is really useful.
Mac OS X 10.6.7 - PHP Version 5.3.2 - PHPUnit 3.5.13 - Yii 1.1.7
#14
Posted 09 June 2011 - 07:57 AM
I updated the documentation in the extension to use createUrl().
I've never used the "exist" validator. Did you follow the example given in CExistValidator documentation, at the bottom? You need something like this:
array('FkFieldName','exist','allowEmpty'=>true, 'attributeName'=>'fieldName','class'=>'FkTableName'),
Quote
- sourceUrl should not use 'controller/action' notation alone since in update the rendered URL is corrupted
- validation rule for the attribute should NOT use: array('attribute','exist') for some reason that I don't understand such validation fails on UPDATE even though the value exist. It shows a message: <attribute> "<value>" is invalid. Not sure if it's a bug in the CExistValidator implementation or the EJuiAutoCompleteFkField or I misunderstood the 'exist' validation concept
#15
Posted 25 July 2011 - 05:19 PM
Thank you for the excellent extension.
I got a problem though, in my case, sometimes I add the option '*' for all values. Especially, during development time, I used mock data, I could not remember what would be the name, so I need some kind of magic term to display all options. How could I do this?
I tried this but not working as expected
/**
* Data provider for EJuiAutoCompleteFkField for categoryFk field
*/
public function actionFindCategory() {
$q = $_GET['term'];
if ($q == '**') {
$q = '*';
}
if (isset($q)) {
$criteria = new CDbCriteria;
//condition to find your data, using q as the parameter field
$criteria->condition = 'name like :txt OR code like :txt';
$criteria->order = 'name ASC'; // correct order-by field
$criteria->limit = 10; // probably a good idea to limit the results
// with trailing wildcard only; probably a good idea for large volumes of data
$criteria->params = array(':txt' => '%' . trim($q) . '%');
$categories = Category::model()->findAll($criteria);
if (!empty($categories)) {
$out = array();
foreach ($categories as $cat) {
$out[] = array(
// expression to give the string for the autoComplete drop-down
'label' => $cat->name,
'value' => $cat->name,
'id' => $cat->id, // return value from autocomplete
);
}
echo CJSON::encode($out);
Yii::app()->end();
}
}
}
#16
Posted 25 July 2011 - 07:09 PM
If you want to use the * character, you still have minLength to contend with. Personally I don't see how typing ** is any easier than %%, but if you want, change the code to substitute % for *. You might want to bracket this logic with IF (defined('YII_DEBUG')) so it only works in a dev environment.
- Jeremy
Daniel, on 25 July 2011 - 05:19 PM, said:
Thank you for the excellent extension.
I got a problem though, in my case, sometimes I add the option '*' for all values. Especially, during development time, I used mock data, I could not remember what would be the name, so I need some kind of magic term to display all options. How could I do this?
I tried this but not working as expected
/**
* Data provider for EJuiAutoCompleteFkField for categoryFk field
*/
public function actionFindCategory() {
$q = $_GET['term'];
if ($q == '**') {
$q = '*';
}
if (isset($q)) {
$criteria = new CDbCriteria;
//condition to find your data, using q as the parameter field
$criteria->condition = 'name like :txt OR code like :txt';
$criteria->order = 'name ASC'; // correct order-by field
$criteria->limit = 10; // probably a good idea to limit the results
// with trailing wildcard only; probably a good idea for large volumes of data
$criteria->params = array(':txt' => '%' . trim($q) . '%');
$categories = Category::model()->findAll($criteria);
if (!empty($categories)) {
$out = array();
foreach ($categories as $cat) {
$out[] = array(
// expression to give the string for the autoComplete drop-down
'label' => $cat->name,
'value' => $cat->name,
'id' => $cat->id, // return value from autocomplete
);
}
echo CJSON::encode($out);
Yii::app()->end();
}
}
}
#17
Posted 28 July 2011 - 08:30 AM
$_GET['term'].
someone can explain it to me plz.
thx
#18
Posted 28 July 2011 - 08:37 AM
shizo971, on 28 July 2011 - 08:30 AM, said:
$_GET['term'].
someone can explain it to me plz.
thx
#19
Posted 01 August 2011 - 06:15 AM
jeremy, on 25 July 2011 - 07:09 PM, said:
If you want to use the * character, you still have minLength to contend with. Personally I don't see how typing ** is any easier than %%, but if you want, change the code to substitute % for *. You might want to bracket this logic with IF (defined('YII_DEBUG')) so it only works in a dev environment.
- Jeremy
Hi Jeremy,
Did not think of "%%" before.....
Now, new problem, I had a multiple modules, here is my view
...
<table id="details" style="width: auto; margin-left: 15px; float: left;">
<thead>
<tr>
<th style="width: 100px; text-align: center;">Gudang</th>
<th style="width: 250px; text-align: center;">Produk</th>
<th style="width: 100px; text-align: center;">Kode bets</th>
<th style="width: 100px; text-align: center;">Jumlah</th>
<th style="width: auto"><?php echo CHtml::link(CHtml::image(Yii::app()->request->baseUrl . '/images/add_ico.png'), '', array('onClick' => 'addDetail($(this))', 'class' => 'add')); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($details as $id => $detail): ?>
<?php $this->renderPartial('_formDetail', array('id' => $id, 'model' => $detail, 'form' => $form), false, true); ?>
<?php endforeach; ?>
</tbody>
</table>
...
here is in _formDetail
<tr>
<td>
<?php echo $form->textField($model, "[$id]warehouseFk", array('style' => 'width: 100px;')); ?>
</td>
<td>
<?php echo $form->textField($model, "[$id]productFk", array('style' => 'width: 250px;')); ?>
</td>
<td>
<?php echo $form->textField($model, "[$id]batchNo", array('style' => 'width: 100px; text-align: center;')); ?>
</td>
<td>
<?php echo $form->textField($model, "[$id]quantity", array('style' => 'width: 100px; text-align: right;')); ?>
</td>
<td>
<?php echo CHtml::link(CHtml::image(Yii::app()->request->baseUrl . '/images/remove_ico.png'), '', array('class' => 'delete', 'onClick' => 'deleteDetail($(this))')); ?>
</td>
</tr>
I want to substitute the textfield for warehouse with
<?php
$this->widget('EJuiAutoCompleteFkField', array(
'model' => $model,
'attribute' => '[$id]warehouseFk', //the FK field (from CJuiInputWidget)
// controller method to return the autoComplete data (from CJuiAutoComplete)
'sourceUrl' => Yii::app()->createUrl('/transaction/findWarehouse'),
// 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' => 'warehouse', // the relation name defined above
'displayAttr' => 'warehouseName', // 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,
),
));
?>
but the autocomplete is never called, any hints?
Cheers,
Daniel

Help













