I want to put reset button under the action column only one time in GridView widget..
Any solution or suggestions?
Thanks
Set header property of ActionColumn:
[
'class' => 'yii\grid\ActionColumn',
'template' => '<div class="pull-right" >{update}{delete}</div>',
'header' => '<button>Button</button>'
]
Update:
As already answered you can create custom column, and you may add only additional filter property so that you can customize this property for each grid.
class CustomActionColumn extends yii\grid\ActionColumn
{
public $filter = "";
protected function renderFilterCellContent()
{
return $this->filter;
}
}
Then you set filter in grid definition:
[
'class' => 'CustomActionColumn',
'template' => '<div class="pull-right" >{update}{delete}</div>',
'filter' => '<button>Button</button>'
]
To, put button in ActionColumn on header so, follow below steps:
Create a file CustomActionColumn.php in components folder.
Put below code in above file
namespace app\components;
use yii\grid\ActionColumn;
use yii\helpers\Html;
class CustomActionColumn extends ActionColumn
{
protected function renderFilterCellContent()
{
return Html::button('Reset', ['class' => 'btn btn-primary']);
}
}
Now in your Gridview widget use CustomActionColumn instead of ActionColumn
Like as
[
'class' => 'app\components\CustomButton',
],
Done.
Note:- Using these steps you can just display button in header.
To display both a button and ActionColumn label you could override yii\grid\ActionColumn renderFilterCellContent() method with your own class like this:
namespace app\components;
class FilterActionColumn extends ActionColumn
{
public $filterContent;
/**
* Renders the filter cell content.
* The default implementation simply renders a blank space.
* This method may be overridden to customize the rendering of the filter cell (if any).
* #return string the rendering result
*/
protected function renderFilterCellContent()
{
return $this->filterContent;
}
}
Then you able to add both label and button to GridView replace default ActionColumn like this
In your view
use app\components\FilterActionColumn;
Replace default GridView ActionColumn
[
'class' => FilterActionColumn::className(),
// Add your own filterContent
'filterContent' => Html::a('Your button', ['some/url'], [
'class' => 'btn btn-default', 'title' => 'Some btn title',
]),
'header'=> 'Your label',
// Another ActionColumn options
// ..
],
You could see extended example here, i.e. if you need more than one button https://github.com/nick-denry/yii2-filter-action-column
GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'emptyCell' => Html::a('<i class="fa fa-refresh"></i> Reset', ['index'], ['class' => 'btn btn-primary btn-xs', 'style' => 'margin: 2px;']),
]);
use emptyCell to set button...
Related
I want to add Department field in User entity, so I decided to extend the default UserCrudController from this package https://github.com/Laravel-Backpack/PermissionManager.
So I created a custom controller with this command php artisan make:controller Admin\UserController
In file \app\Providers\AppServiceProvider.php I also add this (as instructed)
public function register()
{
$this->app->bind(
\Backpack\PermissionManager\app\Http\Controllers\UserCrudController::class,
\App\Http\Controllers\Admin\UserController::class,
);
}
Then here is the content of \App\Http\Controllers\Admin\UserController
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Backpack\PermissionManager\app\Http\Controllers\UserCrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
class UserController extends UserCrudController
{
public function setupCreateOperation()
{
parent::setupCreateOperation();
$fields['departments'] = [
'label' => 'Departments',
'type' => 'select2_multiple',
'name' => 'tags',
'entity' => 'tags',
'attribute' => 'name',
'model' => "App\Models\Tag",
'pivot' => true,
'wrapper' => ['class' => 'form-group col-6 col-md-4'],
'options' => (function ($query) {
return $query->where('type', 'Department')->get();
}),
];
foreach($fields as $key=>$field) {
CRUD::addField($field);
}
}
public function setupUpdateOperation()
{
parent::setupUpdateOperation();
$this->setupCreateOperation();
}
}
All seems fine, I can see all default information such as: username, email, roles, permission and my custom department fields.
The problem is, when I try to modify an existing user adding some Departments, I got this error
The email has already been taken.
The password field is required.
Somehow it's treated as new user registration. What could be the problems?
Somehow, I solved it by copying setupCreateOperation to setupUpdateOperation.
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Backpack\PermissionManager\app\Http\Controllers\UserCrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
class UserController extends UserCrudController
{
...
public function setupUpdateOperation()
{
parent::setupUpdateOperation();
$fields['departments'] = [
'label' => 'Departments',
'type' => 'select2_multiple',
'name' => 'tags',
'entity' => 'tags',
'attribute' => 'name',
'model' => "App\Models\Tag",
'pivot' => true,
'wrapper' => ['class' => 'form-group col-6 col-md-4'],
'options' => (function ($query) {
return $query->where('type', 'Department')->get();
}),
];
foreach($fields as $key=>$field) {
CRUD::addField($field);
}
}
}
Hopefully there's a shorter way to reduce this duplication.
I developed a custom multi-banner module to display on the header of my prestashop page. When i save my changes on form i would like to display it on header.
My module form:
My table to see all banner inserted:
I tried to use smarty and orm to retrieve all information but i don't know how to display on my header.
Any issues? I hope i can understand my trobles :)
Thanks
Here's the code of some of my files:
//in main file:
public function hookDisplayHeaderBanner($params) {
$banner = Banner::getBannerToDisplay();
// If there is a banner to display
if ($banner) {
$this->context->smarty->assign([
'banner' => $banner
]);
return $this->display(__FILE__, 'views/templates/hook/display-custom-banner.tpl');
}
// Nothing to display
return false;
}
//In classes/Banner.php
class Banner extends ObjectModel
{
public $id;
public $color;
public $background_color;
public $content;
public static $definition = [
'table' => 'custom_banner',
'primary' => 'id_custom_banner',
'multilang' => false,
'fields' => [
'color' => [
'type' => self::TYPE_STRING,
],
'background_color' => [
'type' => self::TYPE_STRING,
],
'content' => [
'type' => self::TYPE_STRING
]
]
];
/*
*
* Return the banner to display
*
* Here we put the logic to select the right banner
*/
public static function getBannerToDisplay()
{
$sql = 'SELECT *
FROM `' . _DB_PREFIX_ . self::$definition['table'] . '`
WHERE active = 1';
return Db::getInstance()->getRow($sql);
}
}
//In display-custom-banner.tpl
<div id="banner" style="background-color:{$banner.background_color}!important;">
<p style="color:{$banner.color}!important;">
{$banner.content}
</p>
</div>
Using:
return Db::getInstance()->getRow($sql);
only retrieve the first row of the result, if you would like to return more than one banner you would like to use Db::getInstance()->executeS($sql); to get all results.
Also check your DB table structure and a var_dump() of the involved variables, this would help understanding if there are more issues.
I'm a newbie in Yii programming.
I'm using boostrap library on Yii via Yiistrap/Yiiwheels
I've created a relation table view
The related view is a Whgridview itself
The first (master grid) has a TbRelationColum clicking it i display the second grid (detail grid).
When I click on the row to display the sub grid, everything appears ok. When I change the sort order or the page of the sub grid disappear both grid.
I understand we should differentiate the css class of the pager and the sort of sub grid from the main grid. How to do this specifically in Yii-Way?
Is This the problem?
This is the view of the main grid:
$this->widget('yiiwheels.widgets.grid.WhGridView',array(
'id'=>'masterGrid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'template' => "{summary}{items}<div class=\"row-fluid\"><div class=\"pull-right\">{pager}</div></div>",
'type' => array(TbHtml::GRID_TYPE_BORDERED, TbHtml::GRID_TYPE_STRIPED),
'columns'=>array(
array(
'class' => 'yiiwheels.widgets.grid.WhRelationalColumn',
//'name' => 'multiMembers.id',
'type' => 'raw',
'header' => 'Sub Items',
'url' => $this->createUrl('multiGroup/ajaxSubItems'),
'cacheData' => false,
'value' => "CHtml::tag('button',array('class'=>'btn btn-primary'),'Sub Items')",
'htmlOptions'=>array('style'=>'width:90px;'),
'cssClass' => 'showSubItems',
),
'id',
'title',
array(
'class'=>'bootstrap.widgets.TbButtonColumn',
),
),
));
This is the sub-grid:
echo CHtml::tag('h3',array(),'Sub Items Group #"'.$id.'"');
$this->widget('yiiwheels.widgets.grid.WhGridView', array(
'id'=>'subGrid_'.$id,
'type'=>array(TbHtml::GRID_TYPE_BORDERED, TbHtml::GRID_TYPE_STRIPED),
'dataProvider' => $gridDataProvider,
'template' => "{summary}{items}<div class=\"row-fluid\"><div class=\"pull-right\">{pager}</div></div>",
'columns' => $gridColumns,
));
This is the controller:
/**
* Manages all models.
*/
public function actionAdmin()
{
$model=new MultiGroup('search');
$model->unsetAttributes(); // clear any default values
if (isset($_GET['MultiGroup'])) {
$model->attributes=$_GET['MultiGroup'];
}
$this->render('admin',array(
'model'=>$model,
));
}
public function actionAjaxSubItems()
{
$id = Yii::app()->getRequest()->getParam('id');
$model = $this->loadModel($id);
if($model->numSubItems > 0) {
$this->renderPartial('_child', array('id' => $id,
'gridDataProvider' => $this->getGridDataProvider($id),
'gridColumns' => $this->getGridColumns()
), false, true);
} else {
echo 'Non ci sono Sub Items.';
}
}
public function getGridDataProvider($id) {
$sql = 'SELECT * FROM multi_member WHERE groupid = :groupid ORDER BY lastname,firstname';
$cmd = Yii::app()->db->createCommand($sql);
$cmd->bindParam(':groupid', $id, PDO::PARAM_INT);
$result = $cmd->queryAll();
$dataProvider = new CArrayDataProvider(
$result, array(
'sort' => array(
'attributes' => array('id','groupid','firstname','lastname','membersince'),
'defaultOrder' => array('lastname' => CSort::SORT_ASC, 'firstname' => CSort::SORT_ASC),
),
'pagination' => array(
'pageSize' => 2,
),
));
return $dataProvider;
}
public function getGridColumns() {
return array('id', 'lastname', 'firstname', 'membersince');
}
How can I do?
thank you ..
If the extensions you're using all extend CGgridView, then you should be able to use option 'ajaxUpdate' (link to documentation).
Try setting 'ajaxUpdate'=>false in one of the grids (or in both of them) to see whether it helps you.
Sometimes setting ajaxUpdate to false is the only way I get get some grids to behave the way I want them to...
I'm new to Yii, and I'm trying to do my initial project the "right" way. I've created a CFormModel class that needs three fields to query for some data, a CForm config to construct the form, and a CController to tie it together (all given below).
The data request needs an account, and this can come from a couple of different places. I think retrieving it should be in the controller. However, I don't know how to get it into the form's hidden "account" field from the controller, so that it makes it to the arguments assigned to the CFormModel after submission. More generally, I know how to pass from CController to view script, but not to CForm. Is the registry (Yii::app()->params[]) my best bet?
I suppose I can just leave it out of the form (and required fields) and wait to populate it in the submit action (actionSummaries). Does that break the intention of CForm? Is there a best practice? Even taking this solution, can someone address the first issue, in case it comes up again?
Any other, gentle critique is welcome.
models/SummariesForm.php
class SummariesForm extends CFormModel
{
public $account;
public $userToken;
public $year;
public function rules () {...}
public function fetchSummary () {...}
static public function getYearOptions () {...}
}
views/account/select.php
<?php
$this->pageTitle=Yii::app()->name;
?>
<div class="form">
<?php echo $form->render(); ?>
</div>
controllers/AccountController.php
class AccountController extends CController
{
public $layout = 'extranet';
public function actionSelect ()
{
$model = new SummariesForm();
// retrieve account
require_once 'AccountCookie.php';
/*
*
* Here, I insert the account directly into the
* model used to build the form, but $model isn't
* available to selectForm.php. So, it doesn't
* become part of the form, and this $model doesn't
* persist to actionSummaries().
*
*/
$model->account = AccountCookie::decrypt();
if ($model->account === false) {
throw new Exception('Unable to retrieve account.');
}
$form = new CForm('application.views.account.selectForm', $model);
$this->render('select', array(
'form' => $form,
'account' => $model->account,
));
}
public function actionSummaries ()
{
$model = new SummariesForm();
if (isset($_POST['SummariesForm'])) {
$model->attributes = $_POST['SummariesForm'];
/*
*
* Should I just omit "account" from the form altogether
* and fetch it here? Does that break the "model"?
*
*/
if ($model->validate() === true) {
try {
$summaries = $model->fetchSummary();
} catch (Exception $e) {
...
CApplication::end();
}
if (count($summaries) === 0) {
$this->render('nodata');
CApplication::end();
}
$this->render('summaries', array('model' => $model, 'summaries' => $summaries));
} else {
throw new Exception('Invalid year.');
}
}
}
}
views/account/selectForm.php
<?php
return array(
'title' => 'Select year',
'action' => Yii::app()->createUrl('Account/Summaries'),
'method' => 'post',
'elements' => array(
'account' => array(
'type' => 'hidden',
'value' => $account,
),
'userToken' => array(
'type' => 'hidden',
'value' => /* get token */,
),
'year' => array(
'type' => 'dropdownlist',
'items' => SummariesForm::getYearOptions(),
),
),
'buttons' => array(
'view' => array(
'type' => 'submit',
'label' => 'View summaries',
),
),
);
The answer is NO to do what you asked. You can see $form variable which acted almost like array when it was passed from controller to view. The solution is you add more property $account into selectForm model and treat it like other elements. I don't think leaving the new field outside the form will be properly way if you want to submit its value also.
Edited:
In my project, i am using cgridview to display some information and using the pagination built with the cgrid view. but now i am facing a usability problem with pagination. that's, consider i have 3 pages and the pagination looks like << < 1 2 3 > >>.
when i clicked the 3rd page the pagination should look like << < 1 2 3 and in case of 1st page the pagination should look like 1 2 3 > >>. how can i do this. please provide me a solution.
my widget looks like.
$widget = $this->widget('zii.widgets.grid.CGridView', array(
'id' => 'request-grid',
'dataProvider' => $model->search(),
'cssFile' => Yii::app()->baseUrl . '/media/css/gridview.css',
'summaryText' => '',
'enablePagination' => true,
'template' => '{items}',
'pager' => array(
'class' => 'LinkPager',
'cssFile' => false,
'header' => false,
'firstPageLabel' => 'First',
'prevPageLabel' => 'Previous',
'nextPageLabel' => 'Next',
'lastPageLabel' => 'Last',
),
'columns' => array(......));
also i am extending the CLinkPager class in the the component LinkPager.
class LinkPager extends CLinkPager
{
public $maxButtonCount=3;
}
in your css file you need to write
.yiiPager .hidden, .yiiPager .first, .yiiPager .last {
display: none;
}