Access advanced search result - yii

I am building a Yii application and I followed a tutorial to enable the Advanced search in the index file of a table like this:
<?php
/* #var $this TakeController */
/* #var $dataProvider CActiveDataProvider */
$this->breadcrumbs=array(
'Takes',
);
$this->menu=array(
array('label'=>'Create Take', 'url'=>array('create')),
array('label'=>'Manage Take', 'url'=>array('admin')),
);
Yii::app()->clientScript->registerScript('search', "
$('.search-button').click(function(){
$('.search-form').toggle();
return false;
});
$('.search-form form').submit(function(){
$.fn.yiiListView.update('takelistview', {
data: $(this).serialize()
});
return false;
});
");
?>
<h1>Takes</h1>
<?php echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>
<div class="search-form" style="display:none">
<?php $this->renderPartial('_search',array(
'model'=>$model,
)); ?>
</div>
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
'id'=>'takelistview',
'sortableAttributes'=>array('id', 'data'')
)); ?>
I would like to know if there is a way to process the output of the advanced search. I know that with $dataprovider I can access all the records for this table, but I want to access only the filtered ones. In particular, I want to get the attribute "data" for each record in order to enable the download for all filtered records. I took a look at $.fn.yiiListView and CListView but I don't understand what to do. Can you help me? Thanks!

the $dataProvider variable belongs to the CDataProvider class, you can access the data using the getdata Function as below.
$data = $dataProvider->getData($refresh);
Set the $refresh flag to true if you want to reload the data from data source
Refer to full data provider documentation for more dataProvider methods

Related

ClientValidation In Form not showing When I Send Id Variable To Jquery in YII

I Need Help in Yii, i get problem in my form, the problem is if i put id in textfield then client validation not showing for that field but another field no problem. This is my code in form
<div class="row">
<?php echo $form->labelEx($model,'latar_belakang'); ?>
<?php echo $form->textField($model,'latar_belakang',array('id' => 'latarbelakang','class' => 'input-block-level')); ?>
<?php echo $form->error($model,'latar_belakang'); ?>
<?php echo $form->labelEx($model,'rumusan_masalah'); ?>
<?php echo $form->textField($model,'rumusan_masalah',array('id' => 'rumusanmasalah','class' => 'input-block-level')); ?>
<?php echo $form->error($model,'rumusan_masalah'); ?>
</div>
for your knows i use id in textfield for calculaten field with jquery which i put in form . this is my jquery code in form
Yii::app()->clientScript->registerCoreScript('jquery');
Yii::app()->clientScript->registerScript('totalValues',"
function totalValues()
{
var lb = $('#latarbelakang').val() ;
var rm = $('#rumusanmasalah').val();
var tot = parseInt(lb) + parseInt(rm);
$('#nilaiakhir').val( tot );
}
", CClientScript::POS_HEAD);
Yii::app()->clientScript->registerScript('changeTotals', "
$('#latarbelakang').change( function(){ totalValues(); } );
$('#rumusanmasalah').change( function(){ totalValues();} );
", CClientScript::POS_END);
What i must do ? for solving this problem ?.
Thanks B4..
By default Yii generates ids of fields dynamically using model name and field name.
For example for 'password' field of 'User' model the id would be 'User_password'
You can inspect a field(to which you have not given your custom id) with firebug and see the auto generated id. also yii maps error messages with those auto generated ids in response. that is why your error messages are not showing.
what you can do is to try to call that js function with yii generated id.

Yii/Giix - Standard 2 Column Layout

The code below shows the two column layout in Yii. The $content variable holds a search form and a gridview form.
I'm trying to get the gridview to appear to the right of the Advanced Search Section in this two-column grid format. Kind of brain farting here, where in the standard Giix structure is the variable $content given it's contents? I didn't see it in the basemodel or controller.
Thanks in advance.
<?php /* #var $this Controller */ ?>
<?php $this->beginContent('//layouts/main'); ?>
<div class="span-24">
<div id="content">
<?php echo $content; ?>
</div><!-- content -->
</div>
<div class="span-5 last">
<div id="sidebar">
<?php
$this->beginWidget('zii.widgets.CPortlet', array(
'title'=>'Operations',
));
$this->widget('zii.widgets.CMenu', array(
'items'=>$this->menu,
'htmlOptions'=>array('class'=>'operations'),
));
$this->endWidget();
?>
</div><!-- sidebar -->
</div>
<?php $this->endContent(); ?>
$content is given its content when your controller call $this->render() at the end of its action.
public function actionIndex() {
// renders the view file 'protected/views/site/index.php'
// using the default layout 'protected/views/layouts/main.php'
[some code...]
$this->render('index');
}
The process involved is a bit obfuscated but you can easily trace it down by setting a breakpoint and looking at the stack in your debugger.
You can also read the code :
render() is a method of the CController class :
public function render($view, $data = null, $return = false) {
if ($this->beforeRender($view)) {
$output = $this->renderPartial($view, $data, true); // (1)
if (($layoutFile = $this->getLayoutFile($this->layout)) !== false)
$output = $this->renderFile($layoutFile, array('content' => $output), true); // (2)
[snip...]
}
}
(1) If no error occurs before rendering, the view is populated and its HTML code assigned to $output : $output = $this->renderPartial($view, $data, true);
(2) Then, unless you stated in your action that the view must not be decorated by the layout by colling $this->setLayout(false), the Decorator pattern is applied and the internal view set in the layout :
$output = $this->renderFile($layoutFile, array('content' => $output), true)
Here, you shall notice that the second argument is an array : array('content' => $output)
renderfile() is a method of CBaseController which, at some point, will call
public function renderInternal($_viewFile_, $_data_ = null, $_return_ = false) {
// we use special variable names here to avoid conflict when extracting data
if (is_array($_data_))
extract($_data_, EXTR_PREFIX_SAME, 'data'); // (1)
else
$data = $_data_;
if ($_return_) {
ob_start();
ob_implicit_flush(false);
require($_viewFile_); // (2)
return ob_get_clean();
}
else
require($_viewFile_);
}
And that's where your answer lies :
(1) $data is still our array('content' => $output). The extract function will build and initialize variables from this array, namely your $content variable.
(2) The layout file is now required. $content exists in its scope, as well, of course, as your controller wich lies behind $this
Use a grid layout in the specific view. It should something like
<div class='span-10'>
//search form
</div>
<div class='span-9'>
//grid
</div>

Pass Radio Button Value Onchange

In Yii, the list view used as a search result.
Controller
public function actionSearch()
{
$key=$_GET['Text'];
$criteria = new CDbCriteria();
$criteria->addSearchCondition('username',$key,true,"OR");
$criteria->select = "`username`,`country`";
$data=new CActiveDataProvider('User',
array('criteria'=>$criteria,'pagination'=>array('pageSize'=>5),
));
$this->render('search', array(
'ModelInstance' => User::model()->findAll($criteria),
'dataProvider'=>$data,
));
}
search.php
<?php
//THE WIDGET WITH ID AND DYNAMICALLY MADE SORTABLEATTRIBUTES PROPERTY
$this->widget('zii.widgets.CListView', array(
'id'=>'user-list',
'dataProvider'=>$dataProvider,
'itemView'=>'results',
'template' => '{sorter}{items}{pager}',
));
?>
<?php echo CHtml::radioButtonList('type','',array(
'1'=>'Personal',
'2'=>'Organization'),array('id'=>'type'),array( 'separator' => "<br/>",'style'=>'display:inline')
);
?>
result.php
<?php echo $data->username."<br>"; ?>
<?php echo $data->country; ?>
The user model fields are id, name , country, type, The search result shows the name and country. Now want to filter the results based on the radio button onchange (personal/organisation).
You could try to use $.fn.yiiListView.update method passing list view's id (user-list in your case) and ajax settings as arguments. data property of ajax settings is what can be used to specify GET-parameters that will be passed to your actionSearch to update the list view. So you have to analyze these parameters in the action and alter CDbCriteria instance depending on them.
The following script to bind onchange handler to your radio button list is to be registered in the view:
Yii::app()->clientScript->registerScript("init-search-radio-button-list", "
$('input[name=\"type\"]').change(function(event) {
var data = {
// your GET-parameters here
}
$.fn.yiiListView.update('user-list', {
'data': data
// another ajax settings if desired
})
});
", CClientScript::POS_READY);
You also may consider the following code as an example based on common technique of filtering CGridView results.
By the way, for performance reasons you can render your view partially in the case of ajax update:
$view = 'search';
$params = array(
'ModelInstance' => User::model()->findAll($criteria),
'dataProvider' => $data
);
if (Yii::app()->request->isAjaxRequest)
$this->renderPartial($view, $params);
else
$this->render($view, $params);

ZF2 render form with data from database

I want to edit a record from a database with a Zend Form (Zend Framework 2).
In ZF1 I did in my controller:
$values = $table->getValues();
$form = new MyForm();
$form->populate($values);
$this->view->form = $form;
and in the viewscript:
<?php echo $this->form ?>
In ZF2 I tried in my controller:
$values = $table->getValues();
$form = new MyForm();
$form->populateValues($values); // form->setData($values) does not work either
return array('form' => $form);
and in my viewscript:
<?php echo $this->form()->openTag($form) ?>
<?php echo $this->formCollection($form) ?>
<?php echo $this->form()->closeTag($form) ?>
but that renders the form, without data however.
what is the correct way to do this?
You need to call prepare() on your form before you open it in your view script. For example:
<?php $form->prepare(); ?>
<?php echo $this->form()->openTag($form) ?>
<?php echo $this->formCollection($form) ?>
<?php echo $this->form()->closeTag($form) ?>
See the reference guide here
Note the following point:
the prepare() method. You must call it prior to rendering anything in
the view (this function is only meant to be called in views, not in
controllers).
The issue was that $table->getValues() in my code returns an arrayObject whereas populateValues() expects an array.

Yii: model attribute's comments/hints

I need to have comments/hints for some fields in my Form. My idea is to describe it in model, just like attributeLabels. How can I do it?
And then it would be ideal, if the Gii Model (and Crud) generator would take it directly from mysql column's comment
So I see two questions here:
Describe hints in the model and display on the form.
Get hints from mysql comment
Displaying Hints from Model
Here's a slightly modified version of the default login.php file generated by Yiic
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'login-form',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<div class="row">
<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username'); ?>
<?php echo $form->error($model,'username'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->passwordField($model,'password'); ?>
<?php echo $form->error($model,'password'); ?>
<p class="hint">
Hint: You may login with <kbd>demo</kbd>/<kbd>demo</kbd> or <kbd>admin</kbd>/<kbd>admin</kbd>.
</p>
</div>
<div class="row rememberMe">
<?php echo $form->checkBox($model,'rememberMe'); ?>
<?php echo $form->label($model,'rememberMe'); ?>
<?php echo $form->error($model,'rememberMe'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Login'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
Let's move that password hint into the model by adding a attributeHints() method and a getHint() method to the LoginForm.php model.
/**
* Declares attribute hints.
*/
public function attributeHints()
{
return array(
'password'=>'Hint: You may login with <kbd>demo</kbd>/<kbd>demo</kbd> or <kbd>admin</kbd>/<kbd>admin</kbd>.',
);
}
/**
* Return a hint
*/
public function getHint( $attribute )
{
$hints = $this->attributeHints();
return $hints[$attribute];
}
As you can see, we;ve moved the hint text from the view into the model and added a way to access it.
Now, back in login.php, let's add the hint tag based on data from the model.
<div class="row">
<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->passwordField($model,'password'); ?>
<?php echo $form->error($model,'password'); ?>
<?php echo CHtml::tag('p', array('class'=>'hint'), $model->getHint('password')); ?>
</div>
So now we've changed the hardcoded hint into a generated element populated with data from the model.
Now, moving on to the second question.
Getting hints from mySQL comments
Unforunately, I am not fammiliar enough with Gii to know how to automatically generate the hints from mySQL comments. However, getting the mySQL comment data into the model is fairly easy.
To do this we can use the following mySQL query
SHOW FULL COLUMNS FROM `tbl_user`
So let's add the comment to the password field
ALTER TABLE `tbl_user`
CHANGE `password` `password` VARCHAR( 256 )
CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL
COMMENT 'Hint: You may login with <kbd>demo</kbd>/<kbd>demo</kbd> or <kbd>admin</kbd>/<kbd>admin</kbd>.';
And let's add the code to fetch it into our attributeHints() method.
/**
* Declares attribute hints.
*/
public function attributeHints()
{
$columns= Yii::app()->db->createCommand('SHOW FULL COLUMNS FROM `tbl_user`')->queryAll();
$comments=array();
foreach($columns as $column){
if( isset( $column['Comment'] ) )
{
$comments[ $column['Field'] ] = $column['Comment'];
}
}
//Add any hardcoded hints here
$hints = array(
'username'=>'Enter username above',
);
//Return merged array
return array_merge( $comments, $hints );
}
We now have two ways to set comments, through mySQL comments or through hard coded statements.
Let's update our login.php file quick to include hints of both types.
<div class="row">
<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username'); ?>
<?php echo $form->error($model,'username'); ?>
<?php echo CHtml::tag('p', array('class'=>'hint'), $model->getHint('username')); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->passwordField($model,'password'); ?>
<?php echo $form->error($model,'password'); ?>
<?php echo CHtml::tag('p', array('class'=>'hint'), $model->getHint('password')); ?>
</div>
And that's it!
Now our login page will look like this, with a username hint from the model and a password hint from the mySQL comment.
As of Yii-1.1.13, a new attribute, comment, has been added to CMysqlColumnSchema which is defined in parent CDbColumnSchema:
comment of this column. Default value is empty string which means that no comment has been set for the column. Null value means that RDBMS does not support column comments at all (SQLite) or comment retrieval for the active RDBMS is not yet supported by the framework.
So we can use it to access the comment. Somewhat like this:
$modelObject->tableSchema->columns['column_name']->comment
// or if you are doing this within your model use
$this->tableSchema->columns['column_name']->comment
Note that the tableSchema is already set when any CActiveRecord model is constructed or even if the static model is used, so there are no new queries executed when we access the property.
A sample implementation within your model:
class MyModel extends CActiveRecord {
// hints array will store the hints
public $hints=array();
public function init() {
parent::init();
$this->hints=self::initHints($this);
}
public static function initHints($model) {
$comments=array();
foreach ($model->tableSchema->columns as $aColumn){
if(!empty($aColumn->comment))
$comments["$aColumn->name"]=$aColumn->comment;
}
return $comments;
}
public static function model($className=__CLASS__) {
$model=parent::model($className);
$model->hints=self::initHints($model);
return $model;
}
}
Now you can access hints as:
$model = new MyModel;
$single_column_hint=$model->hints['column_name'];
$model = MyModel::model();
$single_column_hint=$model->hints['column_name'];
For doing this through gii templates, you just need to copy the above code to your custom model code template, read the guide to see how this can be done.
I would recommend having the code in a custom base class, from which you can derive your active records.