Currently Browsing: Yii

Yii custom update for GridView widget

Hooking into the ajax functions in Yii’s GridView and ListView widgets can be a bit tricky and the documentation isn’t always that clear. To do a simple custom filter, you can use something like this:

<?php echo CHtml::dropDownList('Holidays[date]', $model->date, 
  array(
    '2011'=>2011,
    '2012'=>2012,
  ), array('onchange'=>"$.fn.yiiGridView.update('holidays-grid', {data: $(this).serialize()});") ); ?>

Where “Holiday” is the name of the model used to populate the widget and “holidays-grid” is the html ID of the widget. (In real code I would fetch the drop-down values dynamically, but this shows how simple it can be.)

One somewhat undocumented issue is that you must have a particular URL manager rule set or you will get unpredictable results when combining this with sorting and paging:

see: www.yiiframework.com/…/19738-filter-after-sorting-problem-at-gridview/
According to Qiang, “for gridview to work properly in ajax mode, you have to add a URL rule like the following if you use “path” format:”

<controller:\w+>/<action:\w+>' => '<controller>/<action>

This will put all filter conditions into the query string part instead of the pathinfo part.

I spent a bit of time coming up with regex work-around until I found that :/

Yii auto-complete example

I didn’t see any concise examples of Yii autocomplete, particularly showing data fetched via a server request, so here is one:

widget function in view:

$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
	'name'=>'person',
	'value'=>$model->person,
//	'source'=>$people, // <- use this for pre-set array of values
	'source'=>'/site/getNames',// <- path to controller which returns dynamic data
	// additional javascript options for the autocomplete plugin
	'options'=>array(
		'minLength'=>'1', // min chars to start search
		'select'=>'js:function(event, ui) { console.log(ui.item.id +":"+ui.item.value); }'
	),
	'htmlOptions'=>array(
		'id'=>'person',
		'rel'=>'val',
	),
));

controller function to filter and return data:

	function actionGetNames() {
	  if (!empty($_GET['term'])) {
		$sql = 'SELECT people_id as id, CONCAT(first_name," ",last_name) as value, first_name as label FROM people WHERE first_name LIKE :qterm ';
		$sql .= ' ORDER BY first_name ASC';
		$command = Yii::app()->db->createCommand($sql);
		$qterm = $_GET['term'].'%';
		$command->bindParam(":qterm", $qterm, PDO::PARAM_STR);
		$result = $command->queryAll();
		echo CJSON::encode($result); exit;
	  } else {
		return false;
	  }
	}

sample data output when user types an “r”, looks like:

[{"id": 1,"value": "Rachel Hammond","label": "Rachel"}, {"id": 18,"value": "Ross King","label": "Ross"}]

This is obviously a simple example but one that can easily be extended. In the example above the optional ‘select’ param is the js function once the user selects a value.

More info see CJuiAutoComplete and jqueryui.com/demos/autocomplete

Using your own jQuery file with Yii

(and have them play nice)

A common issue and one that I knew there was a Yii solution for but didn’t see clearly documented is how to include your own jQuery file, particularly on a site that has mixed pages where Yii includes it’s own version on some pages and not on others — which can result in jQuery loading twice and causing problems that are not always immediately obvious as to the cause.

In any case, this should do the trick. If you don’t need jQuery on every page, you can leave off or wrap the registerScriptFile line in a conditional and Yii will use your jQuery file when it needs it.

$cs=Yii::app()->clientScript;
$cs->registerScriptFile(Yii::app()->getBaseUrl() . '/js/libs/jquery.min.js', CClientScript::POS_HEAD);
$cs->scriptMap=array(
    'jquery.js'=>Yii::app()->getBaseUrl() . '/js/libs/jquery.min.js',
);

Yii AJAX form validation on submit

From: YII ยป How to use AJAX form validation

One potentially confusing thing about Yii’s AJAX form validation is that it works when you tab out of a field, but the default code doesn’t do the AJAX validation when you hit the submit button.

While you are going to be validating on the server anyway, but if it’s a particularly large page, you might want to avoid the page reload.

To enable AJAX validation in Yii:

In your view (_form.php):

<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'myformname-form',
    'enableAjaxValidation'=>true,
        'clientOptions'=>array('validateOnSubmit'=>true),
)); ?>

And in your controller, in actionCreate and actionUpdate, uncomment these lines:

//$this->performAjaxValidation($model);

Optgroup drop-downs with Yii

Sometimes frameworks make things simple and just work so well you want to kick yourself for having written it out the long way first. A recent example is where I had to use optgroups for an HTML drop-down and didn’t even think to check the Yii spec to see if it could do this for me. Turns out it can and is super-simple:

listData(array $models, string $valueField, string $textField, string $groupField='')

You simply pass the field name of the group field as the 4th argument of the listData function, and add that field to the query if need be. A lot easier to write and maintain than a complex do/while loop.

« Previous Entries Next Entries »