yii CGridView filter with relations - php

I'm using yii for my web application. In one of my view I have CGridView and dataprovider is Mail model. In this model I have relation with with 3 other models. In the grid I show cols from three models. How can I filter the CGridView?
UPDATE:
<?php $dialog = $this->widget('ext.ecolumns.EColumnsDialog', array(
'options'=>array(
'title' => 'Layout settings',
'autoOpen' => false,
'show' => 'fade',
'hide' => 'fade',
),
'htmlOptions' => array('style' => 'display: none'), //disable flush of dialog content
'ecolumns' => array(
'gridId' => 'mails-grid', //id of related grid
'storage' => 'session', //where to store settings: 'db', 'session', 'cookie'
'fixedLeft' => array('CCheckBoxColumn'), //fix checkbox to the left side
'model' => $dataprovider, //model is used to get attribute labels
'columns'=>array(
array(
'name'=>'mailTemplate.name',
'filter'=>CHtml::activeTextField($dataprovider, 'mailTemplate'),
),
'sendDate',
array(
'name'=>'mailTemplate.subject',
'filter'=>CHtml::activeTextField($dataprovider, 'mailTemplate'),
),
array(
'name'=>'client.email',
'filter'=>CHtml::activeTextField($dataprovider, 'client'),
),
array(
'name'=>'client.name',
'filter'=>CHtml::activeTextField($dataprovider, 'client'),
),
array(
'name'=>'operator.username',
'filter'=>CHtml::activeTextField($dataprovider, 'operator'),
),
array(
'name'=>'status',
'value'=>array('MailHelper', 'getEmailStatus'),
'filter'=> CHtml::activeDropDownList($dataprovider, 'status', Mail::getEmailStatuses()),
),
array(
'class'=>'CButtonColumn',
'template'=>'{update}',
'buttons'=>array(
'update' => array(
'url'=>'$this->grid->controller->createUrl("/email/editTemplate", array("templateId"=>$data->id))',
),
),
)
),
)
));
?>
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id' => 'mails-grid',
'dataProvider'=>$dataprovider->search(),
'columns' => $dialog->columns(),
'filter' => $dataprovider,
'template' => $dialog->link()."{summary}\n{items}\n{pager}",
)); ?>

I have Restaurant, City, Country and User models with relations between them.
Model:
public function search() {
$criteria=new CDbCriteria;
$criteria->together = true;
$criteria->with= array('xCountry','xCity','User');
$criteria->compare('Id',$this->Id,true);
$criteria->compare('Restaurant.Name',$this->Name,true);
$criteria->addSearchCondition('xCountry.Name',$this->Country);
$criteria->addSearchCondition('xCity.Name',$this->City);
$criteria->compare('Zip',$this->Zip,true);
$criteria->compare('Address',$this->Address,true);
$criteria->compare('Description',$this->Description,true);
$criteria->compare('Restaurant.Active',$this->Active,true);
$criteria->addSearchCondition('User.Username',$this->Owner);
$criteria->compare('Lat',$this->Lat);
$criteria->compare('Lon',$this->Lon);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
View:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'restaurant-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'Id',
'Name',
'Zip',
'Address',
'Active',
array(
'name' => 'User.Username',
'header' => 'Username',
'filter' => CHtml::activeTextField($model, 'Owner'),
'value' => '$data->User->Username',
),
array(
'name' => 'xCountry.Name',
'header' => 'Country',
'filter' => CHtml::activeTextField($model, 'Country'),
'value' => '$data->xCountry->Name',
),
array(
'name' => 'xCity.Name',
'header' => 'City',
'filter' => CHtml::activeTextField($model, 'City'),
'value' => '$data->xCity->Name',
),
array(
'class'=>'CButtonColumn',
),
),
));
I hope this can help you.
UPDATE:
What if you try something like this:
...
'columns'=>array(
'mailTemplate.name',
'sendDate',
'mailTemplate.subject',
'client.email',
...
UPDATE #2:
Prepare yourself this will be a bit dirty.
Let's say we've got two classes, A and B. B belongs to A.
B's got a property, let's say "color" and we want to display it in our grid where we list the "A"s.
The first thing you have to do is, manually create a property to your data provider class (what is "A").
This property will be "colorOfB", so you have to add "public $colorOfB;" to your model A.
Add criteria for this property:
$criteria->compare('B.color',$this->colorOfB,true);
Add the column to the grid:
array(
'name' => 'B.color',
'header' => 'Color of B',
'filter' => CHtml::activeTextField($model, 'colorOfB'),
'value' => '$data->B->color'),
The final thing is to set this property manually in A's controller:
$modelA = new A('search');
$modelA->colorOfB = $_GET['A']['colorOfB'];

this will set select list
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'avto-ugon-grid',
'dataProvider'=>$model_data,
'filter'=>$model,
'columns'=>array(
'id',
array(
'name' => 'time',
'value' => 'date("d/m/Y", $data->time)',
'type' => 'html',
),
array(
'name' => 'nomer',
'value' => '$data->nomer',
'type' => 'html',
),
array(
'name' => 'id_marka',
'value' => '$data->idMarka->mark',
'type' => 'html',
'filter'=> CHtml::listData(AvtoUgon::model()->with('idMarka')->findAll(array('group'=> 'id_marka', 'order'=> 'idMarka.mark')), 'id_marka', 'idMarka.mark'),
),
array(
'name' => 'id_model',
'value' => '$data->idModel->model',
'type' => 'html',
'filter'=> CHtml::listData(AvtoUgon::model()->with('idModel')->findAll(array('group'=> 'id_model', 'order'=> 'idModel.model')), 'id_model', 'idModel.model'),
),
array(
'name' => 'color',
'value' => $data->color,
'type' => 'raw',
),
array(
'name' => 'id_street',
'value' => '$data->idStreet->street',
'type' => 'html',
),
array(
'name' => 'publish',
'value' => 'CHtml::link($data->publish ? "Опубликовано" : "Не опубликовано", Yii::app()->controller->createUrl("publish", array("id" => $data->id)))',
'type' => 'html',
),
/*'id_street',
'nomer',
*/
array(
'class'=>'CButtonColumn',
),
),
));

Related

ZF 2.3 displaying form in different modules

I'm trying to create a simple application with Zend Framework 2 and now stacked at the point of adding comments form.
I have two modules "Book" and "Comment". I want to show a form for adding comments that is disposed in module "Comment" from "Books" module controller.
The problem appears when I'm trying to open forms tag.
I'm having this error : " Fatal error: Call to undefined method Comment\Form\CommentForm::openTag()".
I tried to check $this->addComment - with var_dump and everything looks great.
Can anybody help me to solve this problem ?
<div class="row">
<div class="col-xs-12 commentBlock">
<?php
if($this->addComment){
$this->addComment->prepare();
$commentFieldset = $this->addComment->get('comment');
print $this->addComment()->openTag($this->addComment);
}
?>
</div>
</div>
Here is 'Comment' module files :
Comment\Form\CommentFieldset
<?php
namespace Comment\Form;
use Comment\Entity\Comment;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\Stdlib\Hydrator\ClassMethods as ClassMethodsHydrator;
class CommentFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct()
{
parent::__construct('comment');
$this->add(
array(
'name' => 'commentTitle',
'attributes' => array(
// 'required' => 'required',
'class' => 'form-controll',
'placeholder' => 'Введите заголовок комментария'
),
'options' => array(
'label' => 'Заголовок комментария',
'label_attributes' => array(
'class' => 'text-center col-sm-3 control-label',
),
),
)
);
$this->add(
array(
'name' => 'commentText',
'type' => 'Zend\Form\Element\Textarea',
'attributes' => array(
'required' => 'required',
'class' => 'form=-controll',
'palceholder' => 'Введите текст комментария',
),
'options' => array(
'label' => 'Текст комментария',
'label_attributes' => array(
'class' => 'text-center col-sm-3 control-label',
),
),
)
);
$this->add(
array(
'name' => 'commentType',
'type' => 'Zend\Form\Element\Radio',
'attributes' => array(
'required' => 'required',
),
'options' => array(
'label' => 'Тип комментария',
'label_attributes' => array(
'class' => 'text-center col-sm-3 control-label',
),
'value_options' => array(
'positive' => 'postive',
'neutral' => 'neutral',
'negative' => 'negative',
),
),
)
);
}
public function getInputFilterSpecification()
{
return array(
'commentTitle' => array(
'required' => FALSE,
'filters' => array(
array(
'name' => 'Zend\Filter\StripTags',
),
array(
'name' => 'Zend\Filter\HtmlEntities'
),
array(
'name' => 'Zend\Filter\StringTrim',
),
),
'validators' => array(
array(
'name' => 'Zend\Validator\StringLength',
'options' => array(
'min' => 1,
'max' => 250,
),
),
),
),
'commentText' => array(
'required' => TRUE,
'filters' => array(
array(
'name' => 'Zend\Filter\StripTags',
),
array(
'name' => 'Zend\Filter\HtmlEntities'
),
array(
'name' => 'Zend\Filter\StringTrim',
),
),
'validators' => array(
array(
'name' => '\Zend\Validator\StringLength',
'options' => array(
'min' => 1,
'max' => 1000,
),
),
),
),
'commentType' => array(
'required' => true,
'validators' => array(
array(
'name' => 'Zend\Validator\InArray',
'options' => array(
'haystack' => array(
'positive',
'neutral',
'negative',
),
'strict' =>\Zend\Validator\InArray::COMPARE_STRICT,
),
),
),
),
);
}
}
Comment\Form\CommentFieldset
<?php
namespace Comment\Form;
use Zend\Form\Form;
use Zend\InputFilter\InputFilter;
use Zend\Stdlib\Hydrator\ClassMethods as ClassMethodsHydrator;
class CommentForm extends Form
{
public function __construct()
{
parent::__construct('comment');
$this
->setAttribute('method', 'POST')
->setHydrator(new ClassMethodsHydrator())
->setInputFilter(new InputFilter())
;
$this->add(
array(
'type' => 'Comment\Form\CommentFieldset',
'options' => array(
'use_as_base_fieldset' => true,
),
)
);
$this->add(
array(
'name' => 'csrf',
'type' => 'Zend\Form\Element\Csrf',
)
);
$this->add(
array(
'name' => 'captcha',
'type' => 'Zend\Form\Element\Captcha',
'options' => array(
'label' => 'А вы точно-приточно не робот ? ',
'captcha' => new \Zend\Captcha\Figlet(),
'attributes' => array(
'required' => true,
)
),
)
);
$this->add(
array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Добавить комментарий',
'class' => 'bigSubmit btn btn-pink',
),
)
);
$this->setValidationGroup(
array(
'csrf',
'captcha',
'comment' => array(
'commentTitle',
'commentText',
'commentType',
),
)
);
}
}
Comment\View\Helper\DisplayAddCommentForm
<?php
namespace Comment\View\Helper;
use Zend\Form\View\Helper\AbstractHelper;
class DisplayAddCommentForm extends AbstractHelper
{
public function __invoke()
{
return new \Comment\Form\CommentForm();
}
}
Book\Controller\BookController
<?php
namespace Book\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\View\Model\JsonModel;
use Comment\Form\CommentForm;
class BookController extends AbstractActionController
{
protected $bookModel;
protected $commentsModel;
public function showAction()
{
$isbn = $this->params()->fromRoute('num');
$book = $this->bookModel->getU(array($isbn));
$comments = $this->commentsModel->getBookComments(array($isbn));
if($_SESSION['user']){
$commentForm = new CommentForm();
} else {
$commentForm = NULL;
}
return new ViewModel(
array(
'book' => $book,
'comments' => $comments,
'addComment' => $commentForm,
)
);
}
**************
}
openTag() is method from form view helper not from your helper. In your view script change this line : print $this->addComment()->openTag($this->addComment); to this one print $this->form()->openTag($this->addComment);

I need to add a datepicker in Gridview columns

[SOLVED]
What im trying to accomplish is to put a date picker in the gridview columns and on change update mysql table.
I've got the update functions i just need help to add the datepicker in the column
THE ANSWER:
'columns' =>array(
array(
'name'=>'due_date',
'value'=>'$data->datePicker()',
'filter'=>CHtml::activeDateField($model,'due_date',array('id'=>$id,'class'=>'form-control','data-id'=> $this->id)),
'type'=>'raw',
),
),
And then the datepicker function in my model
public function datePicker(){
return CHtml::activeDateField($this,'due_date',array('id'=>$id,'class'=>'form-control updateableDate','data-id'=> $this->id));
}
Any Questions feel free
You can use this code :-
<div id="orderdiv">
<?php
$this->widget('zii.widgets.jui.CJuiDatePicker', array(
//'model' => $model,
'name'=>'test',
'attribute' => 'created',
'language' => 'en-AU',
'i18nScriptFile' => 'jquery.ui.datepicker-en.js',
'htmlOptions' => array(
'id' => 'created',
'size' => '10',
),
'defaultOptions' => array(
//'showOn' => 'focus',
'dateFormat' => 'dd/mm/yy',
'showOtherMonths' => true,
'selectOtherMonths' => true,
'changeMonth' => true,
'changeYear' => true,
'showButtonPanel' => true,
)
));
?>
</div>
let me know is it working or not.
Try this code :-
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'orders-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'afterAjaxUpdate'=>"function(){jQuery('#due_date_search').datepicker({'dateFormat': 'yy-mm-dd'})}",
'columns'=>array(
array(
'name' => 'due_date',
'type' => 'raw',
'filter'=>$this->widget('zii.widgets.jui.CJuiDatepicker', array('model'=>$model, 'attribute'=>'due_date', 'htmlOptions' => array('id' => 'due_date_search'), 'options' => array('dateFormat' => 'yy-mm-dd')), true)
),
),
));

beforeAjaxUpdate on delete cgridview yii

Here is my code
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'dsfsd',
'dataProvider' => $model->search(),
'filter' => $model,
'cssFile' => false,
'itemsCssClass' => 'table table-striped',
'beforeAjaxUpdate'=>'js:function(id,options){$.blockUI({
message: "Please wait",
//showOverlay: false,
css: {
border: "none",
padding: "15px",
"-webkit-border-radius": "10px",
"-moz-border-radius": "10px",
opacity: 1,
"z-index": "9999"
}
});}',
'columns' => array(
array(
'header' => '#',
'name' => 'id',
'type' => 'raw',
'value' => 'CHtml::link(CHtml::encode($data->id),array("abc/m/".CHtml::encode($data->id)."/info"))',
'htmlOptions' => array('width' => '40px'),
'filter' => CHtml::activeTextField($model, 'id', array('placeholder' => 'search by id')),
), array(
'header' => 'First name',
'name' => '$data.user.f_name',
'type' => 'raw',
'value' => 'CHtml::encode($data->user->f_name)',
), array(
'header' => 'Last name',
'name' => '$data.user.l_name',
'type' => 'raw',
'value' => 'CHtml::encode($data->user->l_name)'
),
array(
'class' => 'CButtonColumn',
'template' => '{update} {delete}',
//'updateButtonUrl' => 'Yii::app()->createUrl("abc/xyz?id=".$data->id."&c_id=".$data->c_id)',
'deleteButtonUrl' => 'Yii::app()->createUrl("xyv/abc",array("uid"=>$data->id))',
),
),
));
Well, what I want is that the operations under beforeAjaxUpdate will work only when delete button is clicked, not for any other ajax actions like on search or update. How is it possible?
You can add callback function to delete button:
http://www.yiiframework.com/doc/api/1.1/CButtonColumn#buttons-detail
You should set click option in buttons config array:
'columns' => array(
...
'buttons'=>array(
'class'=>'CButtonColumn',
'template'=>'{delete}{update}',
'buttons'=>array(
'delete'=>array(
'click'=>'function(){/*your code here*/}'
)
)
)
...
)
You can return false from callback function to prevent deleting.

yii CGridView dispaly data from relative tbls

I have a small problem. I created user CGridView which is relationship with company and department.
Error : company name is display in the grid view. but department name is not display in gridview.
When I uncomment 'value'=>....., "Trying to get property of non-object" show.
This model relation
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'ranks' => array(self::BELONGS_TO, 'Rank', 'rank_id'),
'companies' => array(self::BELONGS_TO, 'Company', 'company_id'),
'departments' => array(self::BELONGS_TO, 'Department', 'department_id'),
'departmentsdep' => array(self::BELONGS_TO, 'Department', 'department_id'),
'departmentssec' => array(self::BELONGS_TO, 'Department', 'section_id'),
'departmentstea' => array(self::BELONGS_TO, 'Department', 'team_id'),
);
}
this is gridview
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'user-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'login_name',
'first_name',
'last_name',
'email',
array(
'name' => 'company_id',
'value'=>'$data->companies->name',
'filter'=>CHtml::listData($companylist, 'id', 'name'),
),
array(
'name' => 'department_id',
//'value'=>'$data->departmentsdep->name',
'filter' =>
CHtml::listData(
is_numeric($model->company_id) ? Department::model()->findAll(new CDbCriteria(array(
'condition' => 'p_id = 0 AND company_id=:company_id',
'params' => array(':company_id' => $model->company_id),
))) : $department, 'id', 'name'),
),
array(
'name' => 'section_id',
//'value'=>'$data->departmentssec->name',
'filter' =>
CHtml::listData(
is_numeric($model->department_id) ? Department::model()->findAll(new CDbCriteria(array(
'condition' => 'p_id = :pid AND company_id=:company_id',
'params' => array(':company_id' => $model->company_id, ':pid'=>$model->department_id),
))) : $department, 'id', 'name'),
),
array(
'name' => 'team_id',
//'value'=>'$data->departmentstea->name',
'filter' =>
CHtml::listData(
is_numeric($model->department_id) ? Department::model()->findAll(new CDbCriteria(array(
'condition' => 'p_id = :pid AND company_id=:company_id',
'params' => array(':company_id' => $model->company_id, ':pid'=>$model->section_id),
))) : $department, 'id', 'name'),
),
array(
'class'=>'CButtonColumn',
),
),
)); ?>
How can I solve this error
This is my solution
'value' => '($data->department_id == 0) ? "" : $data->departmentsdep->name',
full code
array(
'name' => 'department_id',
'value' => '($data->department_id == 0) ? "" : $data->departmentsdep->name',
'filter' =>
CHtml::listData(
is_numeric($model->company_id) ? Department::model()->findAll(new CDbCriteria(array(
'condition' => 'p_id = 0 AND company_id=:company_id',
'params' => array(':company_id' => $model->company_id),
))) : $department, 'id', 'name'),
),
You can access relations using a '.' to sign a relation. It would be much easier this way:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'user-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'login_name',
'first_name',
'last_name',
'email',
array(
'name' => 'companies.name',
'filter'=>CHtml::listData($companylist, 'id', 'name'),
),
...

Magento - custom admin grid issue

I've been writing a custom out of stock module for the magento backend, I have mass actions, export etc working. However when i do any sort of search function (like put something in the product name field) and indeed try to change to the next page (or input a specific page into the field) or how many products appear on a page. It immediately redirects me to the dashboard.
Can anyone point me in the right direction as to where the code is that handles this function? I'm going to assume its part of the controller, but i've been searching for the last hour and is now time to ask for help!!
Thanks for any help you can provide!
Prepare columns function:
protected function _prepareColumns()
{
$this->addColumn('sku',
array(
'header'=> Mage::helper('catalog')->__('SKU'),
'width' => '80px',
'index' => 'sku',
));
$sets = Mage::getResourceModel('eav/entity_attribute_set_collection')
->setEntityTypeFilter(Mage::getModel('catalog/product')->getResource()->getTypeId())
->load()
->toOptionHash();
$this->addColumn('set_name',
array(
'header'=> Mage::helper('catalog')->__('Attrib. Set Name'),
'width' => '60px',
'index' => 'attribute_set_id',
'type' => 'options',
'options' => $sets,
));
$store = $this->_getStore();
if ($store->getId()) {
$this->addColumn('custom_name',
array(
'header'=> Mage::helper('catalog')->__('Name in %s', $store->getName()),
'index' => 'custom_name',
));
}
$this->addColumn('name',
array(
'header'=> Mage::helper('catalog')->__('Name'),
'index' => 'name',
));
$this->addColumn('stock_status',
array(
'header'=> 'Availability',
'width' => '60px',
'index' => 'stock_status',
'type' => 'options',
'options' => array('1'=>'In stock','0'=>'Out of stock'),
));
$this->addColumn('custom_stock_status',
array(
'header' => 'Custom Stock Status',
'width' => '60px',
'index' => 'custom_stock_status',
'type' => 'options',
'editable' => 'true',));
$this->addColumn('eol',
array(
'header'=> Mage::helper('catalog')->__('EoL'),
'width' => '20px',
'type' => 'checkbox',
'index' => 'eol',
'onclick' => 'this.value = this.checked ? 1 : 0;',
'values' => array('1','2'),
'editable' => 'true',
));
$store = $this->_getStore();
$this->addColumn('qty',
array(
'header'=> Mage::helper('catalog')->__('Qty'),
'width' => '25px',
'type' => 'number',
'index' => 'qty',
));
$this->addColumn('status',
array(
'header'=> Mage::helper('catalog')->__('Status'),
'width' => '70px',
'index' => 'status',
'type' => 'options',
'options' => Mage::getSingleton('catalog/product_status')->getOptionArray(),
));
$this->addColumn('action',
array(
'header' => Mage::helper('catalog')->__('Action'),
'width' => '90px',
'type' => 'action',
'getter' => 'getId',
'actions' => array(
array(
'caption' => Mage::helper('catalog')->__('Edit Product'),
'url' => array(
'base'=>'store_admin/catalog_product/edit',
'params'=>array('store'=>$this->getRequest()->getParam('store'))
),
'field' => 'id'
)
),
'filter' => false,
'sortable' => false,
'index' => 'stores',
));
$this->addRssList('rss/catalog/notifystock', Mage::helper('catalog')->__('Notify Low Stock RSS'));
return parent::_prepareColumns();
}
Furthermore i'm trying to filter by an attribute, I need to filter the same attribute twice in order to output both null and no attributes, but not yes. Is there anyway to do this?
->addAttributeToFilter('eol', array('null' => true), 'left')
->addAttributeToFilter('eol', array('No' => true));
This is what i'm trying to do at the moment, however, it doesn't work in the slightest. Both work individually fine!
Mage_Adminhtml_Block_Widget_Grid
has a method
_addColumnFilterToCollection($column)
You can override it to implement filtering logic for your custom grid.
For CE 1.6.2, this worked for me:
1) Copy over app/code/core/Mage/Adminhtml/Block/Catalog/Product/Grid.php to app/code/local/Mage/Adminhtml/Block/Catalog/Product/Grid.php
2) add the code below from app/code/local/Mage/Adminhtml/Block/Catalog/Product/Grid.php inside/under _prepareCollection()
AFTER ->addAttributeToSelect('type_id'); and before if (Mage::helper('catalog')->isModuleEnabled('Mage_CatalogInventory')) {
CODE:
$collection->joinTable( 'cataloginventory/stock_item',
'product_id=entity_id', array("stock_status" => "is_in_stock") )
->addAttributeToSelect('stock_status');
3) Add the below around line 180 after
'index' => 'price', ));
CODE:
$this->addColumn('stock_status',
array(
'header'=> 'Stock Status', // this is the title of the column
'width' => '60px', // this is the width of the column
'index' => 'stock_status',
'type' => 'options',
'options' => array('1'=>'In Stock','0'=>'Out Of Stock'),
)
);

Categories