I have a inventory table. Now, using this table, I want to show the data on Pharmacy module in a Tbgridview such that it only displays those inventories from the Pharmacy store. i.e. row with category_id=2.
How, can I do this on the drug's index page. This is the code for index page of Pharmacy.
<?php
$this->menu=array(
array('label'=>'Add Drug', 'icon'=>'icon-plus', 'url'=>Yii::app()->controller->createUrl('create'), 'linkOptions'=>array()),
array('label'=>'List Drugs', 'icon'=>'icon-th-list', 'url'=>Yii::app()->controller->createUrl('index'),'active'=>true, 'linkOptions'=>array()),
array('label'=>'List Orders', 'icon'=>'icon-th-list', 'url'=>Yii::app()->controller->createUrl('PhOrder/index'), 'linkOptions'=>array()),
array('label'=>'List Distributors', 'icon'=>'icon-th-list', 'url'=>Yii::app()->controller->createUrl('PhDistributor/index'), 'linkOptions'=>array()),
);
?>
<div>
<?php ?>
<?php
$model= new Inventory;
$this->widget('bootstrap.widgets.TbGridView',array(
'id'=>'ph-drug-grid',
'dataProvider'=>$model->search(),
'type'=>'bordered condensed',
'template'=>'{summary}{pager}{items}{pager}',
'columns'=>array(
array(
'header'=>'S. N. ',
'value'=>'$data->inventory_code',
'type'=>'raw',
),
'description',
'manufacturer',
'minimum_order_level',
'store_id',
'stock_quantity',
array(
'header'=>'<a>Actions</a>',
'class'=>'bootstrap.widgets.TbButtonColumn',
'template' => '{dispose}',
'buttons' => array(
'dispose' => array(
'label'=>'Dispose',
'options'=>array(
'class'=>'btn btn-small',
'onclick'=>'return confirm("Are you sure, you want to dispose this drug?")'
),
)
),
'htmlOptions'=>array('nowrap'=>'nowrap'),
)
),
)); ?>
</div>
set attributes of your model, then if they are filtered in search() function of model Inventory, then result will get filtered
$model= new Inventory;
$model->category_id = 2;
you can also use CSqlDataProvider in your controller
$sql='select * from inventory where category_id=2';
$count=Yii::app()->db->createCommand('select count(*) from inventory where category_id=2')->queryScalar();
$dataProvider = new CSqlDataProvider($sql, array(
'totalItemCount'=>$count,
'keyField' => 'id',
'pagination'=>array(
'pageSize'=>10,
),
));
more info
Related
Background
I have used Gii Crud Generator with my "Category" model, and I want to modify the admin form.
I look inside "protected/views/Category/admin.php,
I found the table is render by a widget('zii.widgets.grid.CGridView'),
and it using a data Provider for it's data.
I suppose I can find some where to input the SQL query in the data Provider, but I don't understand about how's it works.
these is the code In the Model->relations(), but I don't know what to do next.
public function relations(){
return array(
'cateLang' => array(self::HAS_MANY, 'CategoryLang', 'cate_id')
);
}
where the data provider is generated :
public function search(){
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('status',$this->status,true);
$criteria->compare('createDate',$this->createDate,true);
$criteria->compare('updateDate',$this->updateDate,true);
$criteria->compare('remark',$this->remark,true);
return new CActiveDataProvider($this->with('cateLang'), array(
'criteria'=>$criteria,
));
}
Target
I want to add two more columns at the table of "protected/views/Category/admin.php,
which will show French Title & English Title of the row.
To get data in SQL, it will be :
SELECT
cate.id,
lang1.name as "FrenchTitle",
lang2.name as "EnglishTitle",
cate.updateDate,
cate.createDate,
cate.remark
FROM `category` cate
LEFT JOIN `categorylang` lang1
ON `lang1`.`cate_id` = `cate`.id
AND `lang1`.`lang_id`= 1
LEFT JOIN `categorylang` lang2
ON `lang2`.`cate_id` = `cate`.id
AND `lang2`.`lang_id`= 2
WHERE cate.status = 'live'
If I can done with data Provider, the CGridView parameter may be like this :
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'category-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'FrenchTitle',
'EnglishTitle',
'createDate',
'updateDate',
'remark',
array(
'class'=>'CButtonColumn',
),
),
));
You could try the following:
public function search(){
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('status',$this->status,true);
$criteria->compare('createDate',$this->createDate,true);
$criteria->compare('updateDate',$this->updateDate,true);
$criteria->compare('remark',$this->remark,true);
$criteria->with = array('cateLang' => array(
'condition' => 'cateLang.id = 1 OR cateLang.id = 2',
'order' => 'cateLang.id ASC'
));
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'category-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
array(
'name' => 'FrenchTitle'
'value' => '(isset($data->cateLang[0])) ? $data->cateLang[0]->name : "no Title"',
),
array(
'name' => 'EnglishTitle'
'value' => '(isset($data->cateLang[1])) ? $data->cateLang[1]->name : "no Title"',
),
'createDate',
'updateDate',
'remark',
array(
'class'=>'CButtonColumn',
),
),
));
In the search I specify that I want only cateLang object with the id 1 or 2 and then in the cgridview I display a relational object.
I am unable to figure out how to set the filter dropdown's id attribute.
Here is the view code that defines the widget.
$this->widget('bootstrap.widgets.TbGridView',array(
'id'=>'view-grid',
'enableHistory'=>true,
'dataProvider'=>$model->search(),
'summaryText'=>"",
'filter'=>$model,
'columns'=>array(
array('name'=>'v_id','htmlOptions'=>array('style'=>'width: 60px')),
array('name'=>'v_parent_view','htmlOptions'=>array('style'=>'width: 20%'),'value'=>'$data->vParent->v_name'),
array('name'=>'v_name','type'=>'raw','value'=>function($data,$row) {
if(isset($data->vLatestVersion[0]->vv_id) && $data->vLatestVersion[0]->vv_id) {
return CHtml::link($data->v_name,array("viewVersion/update","id"=>$data->vLatestVersion[0]->vv_id));
} else {
return CHtml::link($data->v_name,array("viewVersion/create","vid"=>$data->v_id));
}
}),
array('name'=>'v_date_modified', 'type'=>'raw', 'htmlOptions'=>array('style'=>'width: 110px'), 'value'=>function($data, $row) {
return $data->modified_since . '<br/><span class="timeago">'.$data->vUserModified->username.'</span>';
}),
array(
'name'=>'v_status',
'value'=>'$data->getStatusName()',
'filter'=>Yii::app()->params['globalDmpLookups']['generalStatus'],
'filterHtmlOptions'=>array('id'=>'sel_status'),
'htmlOptions'=>array('style'=>'width: 60px'),
)
),
));
The line of code near the end that has 'filterHtmlOptions' is what I tried, but it is not working. Any help would be greatly appreciated.
The rendered html of my dropdown should look like this:
<select id="sel_status" name="View[v_status]">...</select>
But sadly it looks like this:
<select name="View[v_status]">...</select>
I found that I was trying to use a dropdown list incorrectly in my list filter for status = Active/Disabled. Doing this the Yii way is a simple matter of setting up the model like this...
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->with = array('ggUserModified'); // specify relationship
$criteria->compare('gg_id',$this->gg_id);
$criteria->compare('gg_class',$this->gg_class,true);
$criteria->compare('gg_name',$this->gg_name,true);
$criteria->compare('gg_title',$this->gg_title,true);
$criteria->compare('gg_description',$this->gg_description,true);
$criteria->compare('gg_date_modified',$this->gg_date_modified,true);
$criteria->compare('gg_status',$this->gg_status);
$criteria->compare('User.username',$this->gg_user_modified_rel,true); // use table alias name and specify relationship field property
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'sort'=>array(
'attributes'=>array(
'gg_user_modified_rel' => array( // specify relationship field property
'asc'=>'User.username', // specify table alias name
'desc'=>'User.username DESC', // specify table alias name
),
'*',
),
),
));
}
... and setting up the view like this...
<?php $this->widget('bootstrap.widgets.TbGridView',array(
'id'=>'gallery-group-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'gg_id',
'gg_name',
array(
'name'=>'gg_user_modified_rel', // specify relationship field property
'value'=>'$data->ggUserModified->username' // specify relationship name
),
'gg_date_modified',
array(
'name'=>'gg_status',
'value'=>'$data->getStatusName()',
'filter'=>Yii::app()->params['globalDmpLookups']['generalStatus'],
'htmlOptions'=>array('style'=>'width: 120px'),
),
array('header'=>'Item Count','value'=>'$data->ggChildCount'),
array(
'class'=>'bootstrap.widgets.TbButtonColumn',
),
),)); ?>
filterHtmlOptions is the HTML options for the table row element, not for the input.
what is the value of Yii::app()->params['globalDmpLookups']['generalStatus']?
if you want to set the filter dropdown's id attribute, set the HTML attributes on the dropdown.
for example :
// ..
'columns'=>array(
array(
'name' => 'majorId',
'filter' => CHtml::activeDropDownList($model, 'majorId', CHtml::listData(
Major::model()->findAll(), "id", "name"),
array(
'empty' => '=== Pilih Jurusan ===',
'id' => 'YOUR_ID'
)
),
),
),
// ..
I have this search using joins. The results are correct but yii grid does not show all of the results even if the pagesize selected is greater than number of result.
here's my code :
if($_GET['BaseIar']['description'] !='empty'){
$criteria->with = array('class','classSi',);
$this->description=$_GET['BaseIar']['description'];
$criteria->compare('class.description', $this->description, true);
$criteria->compare('classSi.description', $this->description, true, 'OR');
}
here are the relations:
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(
'class' => array(self::HAS_ONE, 'BaseEiEquipItem', 'iar_no'),
'classSi' => array(self::HAS_ONE, 'BaseSiReceivedItem','iar_no'),
);
}
here's the grid:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'base-iar-grid',
'dataProvider'=>$searchModel->search(),
'columns'=>array(
array(
'class'=>'CCheckBoxColumn',
'id'=>'base-iar-id',
'selectableRows'=>2, // multiple rows can be selected
),
'iar_id',
'dateInspected',
array(
'name'=>'inspectedBy',
'value'=>'(!empty($data->inspectedBy))?$data->inspectedBy0->person->lastName.", ".$data->inspectedBy0->person->firstName." ".$data->inspectedBy0->person->middleName:"---"',
),
array(
'name'=>'endUser',
'value'=>'(!empty($data->endUser))?$data->endUser0->person->lastName.", ".$data->endUser0->person->firstName." ".$data->endUser0->person->middleName:"---"',
),
'dateReceived',
array(
'name'=>'receivedBy',
'value'=>'(!empty($data->receivedBy))?$data->receivedBy0->person->lastName.", ".$data->receivedBy0->person->firstName." ".$data->receivedBy0->person->middleName:"---"',
),
array(
'name'=>'requisitionOffice',
'value'=>'(!empty($data->requisitionOffice))?$data->requisitionOffice0->code:"---"',
'value'=>'$data->requisitionOffice0->code'
),
'prNo',
'poNo',
array(
'class'=>'InfosysButtonColumn',
'template'=>'{view}',
'afterDelete'=>'function(link,success,data){
if(success){
jSuccess("Delete completed successfully!");
}
}',
'buttons'=>array(
'view' => array(
'label' => 'View details',
'url' => 'Yii::app()->createUrl("pims/IAR/BaseIar/view", array("id"=>$data["id"]))'
),
),
'header'=>CHtml::activeDropDownList($model,'pageSize',array('10'=>'10','20'=>'20','30'=>'30','50'=>'50','100'=>'100','ALL'=>'All'),array('onchange'=>'$.fn.yiiGridView.update("base-iar-grid", {data:{pageSize:$(this).val()}});')),
),
)
));
What might be the correct way to declare multiple relations in $criteria->with?
Hey I found this piece of example code in the docs for with(), maybe it'll help you:
Post::model()->with(array(
'author'=>array('select'=>'id, name'),
'comments'=>array('condition'=>'approved=1', 'order'=>'create_time'),
))->findAll();
I have a problem that I have solved for all but one of the cgridview filters, which is a related field.
I am using a solution Seenivasan has supplied but the related field status does not get added to the string.
here is the cgridview :-
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'tbl-orders-grid',
'dataProvider'=>$dataProvider,
'afterAjaxUpdate'=>"function() {
jQuery('#Orders_date_first').datepicker(jQuery.extend({showMonthAfterYear:false}, jQuery.datepicker.regional['id'], {'showAnim':'fold','dateFormat':'yy-mm-dd','changeMonth':'true','changeYear':'true','constrainInput':'false'}));
jQuery('#Orders_date_last').datepicker(jQuery.extend({showMonthAfterYear:false}, jQuery.datepicker.regional['id'], {'showAnim':'fold','dateFormat':'yy-mm-dd','changeMonth':'true','changeYear':'true','constrainInput':'false'}));
}",
'filter'=>$model,
'columns'=>array(
array(
'name'=>'id',
'type'=>'raw',
'value'=>'str_pad($data->id,8-strlen($data->id),"0",STR_PAD_LEFT)',
'htmlOptions'=>array('style' => 'text-align: right;width: 60px;')
),
array(
'name'=>'date_order_placed',
'filter'=>$dateisOn,
'value'=>'date("d-m-Y",strtotime($data->date_order_placed))',
),
array(
'name'=>'status',
'type'=>'raw',
//'htmlOptions'=>array('id' => 'order_status_search'),
'value'=>'CHtml::value($data,"status.orders_status_name")',
'filter'=>CHtml::listData(OrderStatus::model()->findAll(
array(
'select'=>array('orders_status_name'),
'distinct'=>true
)),"orders_status_name","orders_status_name")//this is the focus of your code
),
array(
'class'=>'EButtonColumnWithClearFilters',
'clearVisible'=>true,
'template'=>'{view}{email}',
'buttons'=>array
(
'email' => array
(
'label'=>'Reprint invoice and email to yourself',
'imageUrl'=>Yii::app()->request->baseUrl.'/images/email.png',
'url'=>'Yii::app()->createUrl("orders/ureprint", array("id"=>$data->id))',
),
),
),
),
)); ?>
here is the php and js that adds the current filter values to the url.
echo CHtml::button('List Orders',array('id'=>'listelement'));
Yii::app()->clientScript->registerSCript('test','
$("body").on("click","#listelement",function(){
var str="&";
$.each($("#tbl-orders-grid input").serializeArray(),function(i,j){
str=str+j.name+"="+j.value+"&";
});
window.location="'.CHtml::normalizeUrl(array('orders/index')).'"+str;
});
');
The other filters, dates and id, work perfectly. They are added to the url above. Status is not.
1- you need to define new filters in your model serach() methode for example like
$criteria->compare('Restaurant.Name',$this->Name,true);
Restaurant is your relation key , name : value from another table related to this fk
2- you have to add value of gridview column like :
view:
array(
'name' => 'Restaurant.Name',
'header' => 'Username',
'filter' => CHtml::activeTextField($model, 'name'),
'value' => '$data->Restaurant->Name',
This link will help you
yii CGridView filter with relations
I am trying to include a Datepicker inside the CGridView as follows, the datepicker widget is used within the Grid View.
this->widget('zii.widgets.grid.CGridView', array(
'id'=>'order-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'order_id',
'customer.address.firstname',
'customer.address.lastname',
/*array('name' => 'ordering_date',
'value' => 'date("M j, Y", $data->ordering_date)'),
*/
array('name'=>'ordering_date',
'value'=>'$data->ordering_date',
'filter'=>$this->widget('zii.widgets.jui.CJuiDatePicker', array(
'model'=>$model,
'attribute'=>'ordering_date',
'options'=>array(
'showButtonPanel'=>true,
'changeYear'=>true,
)
),
true),
'htmlOptions'=>array('width'=>'80','style'=>'text-align:center'),
),
array(
'class'=>'CButtonColumn',
'template' => '{view} {rollback} {receive}{pack} {dispatch}{delivered}',
'htmlOptions'=>array('width'=>'250px'),
'buttons'=>array(
'receive'=>array(
'id'=>'receive',
'name'=>'receive',
'url'=>'$this->grid->controller->createUrl("/shop/order/admin&received=true", array("id"=>$data->order_id,"asDialog"=>1,"gridId"=>$this->grid->id))',
'type'=>'submit',
'imageUrl'=>'/mdg/images/Receive1.png',
'visible'=>'($data->status=="pending")?true:false;'
),
'pack'=>array(
'id'=>'pack',
'name'=>'pack',
'type'=>'submit',
'url'=>'$this->grid->controller->createUrl("/shop/order/admin&packed=true", array("id"=>$data->order_id,"asDialog"=>1,"gridId"=>$this->grid->id))',
'click'=>'',
'imageUrl'=>'/mdg/images/pack1.png',
'visible'=>'($data->status=="received")?true:false;'
),
'dispatch'=>array(
'id'=>'dispatch',
'name'=>'dispatch',
'url'=>'$this->grid->controller->createUrl("/shop/order/admin&dispatched=true", array("id"=>$data->order_id,"asDialog"=>1,"gridId"=>$this->grid->id))',
'click'=>'',
'imageUrl'=>'/mdg/images/dispatch.png',
'visible'=>'($data->status=="packed")?true:false;'
),
'delivered'=>array(
'id'=>'delivered',
'name'=>'delivered',
'url'=>'',
'click'=>'',
'imageUrl'=>'/mdg/images/delivered1.png',
'visible'=>'($data->status=="dispatched")?true:false;'
),
'rollback'=>array(
'id'=>'rollback',
'name'=>'rollback',
'url'=>'$this->grid->controller->createUrl("/shop/order/admin&rollback=true", array("id"=>$data->order_id,"asDialog"=>1,"gridId"=>$this->grid->id))',
'click'=>'',
'imageUrl'=>'/mdg/images/rollback.jpg',
'visible'=>'($data->status=="pending")?false:true;'
),
),
),
'status',
),
'afterAjaxUpdate'=>'function(){
jQuery("#'.CHtml::activeId($model, 'ordering_date').'").datepicker({showButtonPanel:true, changeYear:true});
}',
)); ?>
This Code was taken from a suggestion given in the yiiframework forum. But it doesnt do anything.
Any idea why that is?
Thanks!
In this case I would put the date picker in the _search view. If you used Gii to generate your CRUD, it should already be there, available from the admin view:
<?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><!-- search-form -->