I've create button view profile at gridview. When user click the button view profile, it will go to profile based on user_id. Here is the code.
<?= GridView::widget([
'dataProvider' => $dataProvider,
'id' => 'mygrid',
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'user_id',
'project_name',
['class' => 'yii\grid\ActionColumn'],
[
'label' => 'View Profile',
'format' => 'raw',
'content' => function($model) {
return Html::a('View', ['projectstudent/viewprofile', 'id' => $model->user_id],
['class' => 'btn btn-primary']);
}
],
]
]); ?>
At controller
public function actionViewprofile($id)
{
return $this->render('profile', [
'model' => $this->findModel($id),
]);
}
The requested page is not found. How can i fix the code? Thanks.
Here may be problem of controller name that u are specified, there is no need to define controller name if you want to call the action of same controller.
So replace so your code with this and try again
return Html::a('View', ['viewprofile', 'id' =>$model->user_id],
['class' => 'btn btn-primary']);
Related
I'm using the Nav widget in Yii2. I have a dropdown menu as part of the nav menu but the dropdown is very long and extends beyond the bottom of the page and doesn't scroll. To solve this I am trying to add the pre-scrollable class to the submenu container. Try as I might I can't seem to make it work.
In the Yii manual for the Nav widget (https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/api/2.0/yii-bootstrap-nav) under the $Items public property it says:
dropDownOptions: array, optional, the HTML options that will passed to
the yii\bootstrap\Dropdown widget.
I've also looked at the man page for the Dropdown widget (https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/api/2.0/yii-bootstrap-dropdown).
The code I have for my Nav widget is like:
echo Nav::widget([
'options' => ['class' => 'navbar-nav ml-auto'],
'items' => [
['label' => 'Home', 'url' => ['/site/index']],
['label' => 'About', 'url' => ['/site/about']],
[
'label' => 'Dropdown menu',
//'dropDownOptions' => ['options' => ['class' => 'pre-scrollable']],
//'dropDownOptions' => ['class' => 'pre-scrollable'],
//'dropDownOptions' => ['submenuOptions' => ['class' => 'pre-scrollable']],
//'submenuOptions' => ['class' => 'pre-scrollable'],
//'submenuOptions' => ['options' => ['class' => 'pre-scrollable']],
//'submenuOptions' => ['dropDownOptions' => ['class' => 'pre-scrollable']],
//'dropDownOptions' => ['dropDownOptions' => ['class' => 'pre-scrollable']],
//'submenuOptions' => ['submenuOptions' => ['class' => 'pre-scrollable']],
//'options' => ['submenuOptions' => ['class' => 'pre-scrollable']],
//'options' => ['class' => 'pre-scrollable'],
//'options' => ['dropDownOptions' => ['class' => 'pre-scrollable']],
'items' => [
['label' => 'Dropdown menu item 1', 'url' => '#'],
['label' => 'Dropdown menu item 2', 'url' => '#'],
...
],
],
['label' => 'Contact', 'url' => ['/site/contact']],
],
]);
The commented out lines are some of the different ways I've tried to 'pass the HTML options to the yii\bootstrap\Dropdown widget' (in order of increasing desperation).
Please can someone put me right?
Thanks in anticipation!
The option dropDownOptions is tested successfully on Yii version 2.0.11.2 and Bootstrap v3.3.7:
'dropDownOptions' => ['class' => 'pre-scrollable'],
The result is additional class of tag contained submenu items
<ul id="w4" class="pre-scrollable dropdown-menu">
If you are using yii2-bootstrap4 - that options apparently renamed to dropdownOptions.
See Nav::renderDropdown() in the sources:
/**
* Renders the given items as a dropdown.
* This method is called to create sub-menus.
* #param array $items the given items. Please refer to [[Dropdown::items]] for the array structure.
* #param array $parentItem the parent item information. Please refer to [[items]] for the structure of this array.
* #return string the rendering result.
* #throws \Exception
*/
protected function renderDropdown($items, $parentItem)
{
/** #var Widget $dropdownClass */
$dropdownClass = $this->dropdownClass;
return $dropdownClass::widget([
'options' => ArrayHelper::getValue($parentItem, 'dropdownOptions', []),
'items' => $items,
'encodeLabels' => $this->encodeLabels,
'clientOptions' => false,
'view' => $this->getView(),
]);
}
https://github.com/yiisoft/yii2-bootstrap4/blob/219d19fba47b5499f01764789c3cd3ce7306e0f9/src/Nav.php#L207
Trying to set up kratik grid export in Yii after doing everything I keep getting
Call to undefined method app\models\User::instance()
here is my code
$exportedValues = [['class' => 'kartik\\grid\\SerialColumn'], ['attribute' => 'deduction_date'], ['attribute' => 'deduction_amount'], ['attribute' => 'deduction_remark'], ['class' => 'kartik\\grid\\ActionColumn']];
$export = ExportMenu::widget(['dataProvider' => $dataProvider, 'columns' => $exportedValues, 'noExportColumns' => [0, 3], 'columnSelectorOptions' => ['label' => 'Columns', 'class' => 'btn btn-danger'], 'target' => '_blank', 'fontAwesome' => true, 'dropdownOptions' => ['label' => 'Export', 'class' => 'btn btn-success']]);
echo GridView::widget(['dataProvider' => $dataProvider, 'filterModel' => $searchModel,
'columns' => [['class' => 'yii\\grid\\SerialColumn'],
'first_name', 'last_name', 'email_id', 'phone', ['class' => 'yii\\grid\\ActionColumn']]]); ?>
Try to install kartik, or check your kartik version
php composer.phar require kartik-v/yii2-widgets "*"
Had the same issue.
on the source code of ExportMenu.php I replaced:
$model = $modelClass::instance();
by:
$model = new $modelClass;
solved it for me.
I'm new to Yii2 and currently I'm working on the admin section in which admin could update a typical webpage, in this case, the "About us" page. The application will check if there's already an existing row in the "About" table. If so, an "Update" button will be shown right in the view's index page as only one content is allowed in the "About us" section. Else, a "create" button will be shown. The update in the gridview works well but I wonder how to pass the "id" value in the table into the update button because I keep getting the error message "missing required parameters id". I've spent a whole day but stil stuck. Thank you in advance for your kind help.
This is how my Index looks like :
<?php
if(!$dataProvider)
{
echo Html::a('Create', ['create'], ['class' => 'btn btn-success']) ;
}
else
{
echo Html::a('Update-about', ['update'], ['class' => 'btn btn-success']);
}
?>
</p>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'Tite',
'Content:ntext',
'Date',
'ImageID',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
And this is the controller:
public function actionIndex()
{
$searchModel = new aboutSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->ID]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
Link should be
Html::a('Update-about', ['update', 'id' => $id], ['class' => 'btn btn-success']);
And you should pass ID of the row to index view:
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'id' => $id,
]);
So the main question is - what row of table About you want to change by update action? If this is the first available record then:
public function actionIndex()
{
$searchModel = new aboutSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$about = About::find()->one(); // get first record found
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'id' => $about->id, // pass record id to view
]);
}
Or find the row you need by passing some condition to where method: About::find()->where(...)->one();
I'm using 2 widgets in one page, Both are using listview, one is for blogs and another one is for pages and both are using ScrollPager. I want to show more button in each separately. The problem is the show more button is shown only for pages but not for blog, if I remove the page widget it will display for blogs. I'm trying to display show more for pages and show more for blogs. I tried by pageParam but the problem still exist.
widget:
class UserPagesWidget extends \yii\base\Widget
{
public $usr_id;
public function run()
{
$dataProviderContent = new ActiveDataProvider([
'query' => Post::find()->Where(['user_id' => $this->usr_id])
->orderBy(['post_crdate' => SORT_DESC]),
'pagination' => [
'pageParam' => 'contentPagination',
'pageSize' => 5,
],
]);
return $this->render('/user/widget/pstList', [
'dataProviderContent' => $dataProviderContent,
]);
}
}
Render file:
<?= ListView::widget([
'dataProvider' => $dataProviderContent,
'summary'=>'',
'itemOptions' => ['class' => 'item'], // LY - FOR ( LOAD MORE )
'emptyText' => 'No Content',
'itemView' => function ($model, $key, $index, $widget) {
return $this->render('/user/profileContent/usr-pst-content',['model' => $model]);
},
'pager' => ['class' => \kop\y2sp\ScrollPager::className()],
]);
?>
Blog Widget:
class UserBlogsWidget extends \yii\base\Widget
{
public $usr_id;
public function run()
{
$dataProviderBlog = new ActiveDataProvider([
'query' => Blog::find()->Where(['user_id' => $this->usr_id])
->orderBy(['blog_update' => SORT_DESC]),
'pagination' => [
'pageParam' => 'blogPagination',
'pageSize' => 6,
],
]);
return $this->render('/user/widget/blgList', [
'dataProviderBlog' => $dataProviderBlog,
]);
}
}
Blog render file:
<?= ListView::widget([
'dataProvider' => $dataProviderBlog,
'summary'=>'',
'itemOptions' => ['class' => 'item'], // LY - FOR ( LOAD MORE )
'emptyText' => 'No Blogs',
'itemView' => function ($model, $key, $index, $widget) {
return $this->render('/user/profileContent/usr-blg-content',['model' => $model]);
},
'pager' => ['class' => \kop\y2sp\ScrollPager::className()],
]);
?>
Both widgets are called in one view file.
<div class="row chn-row">
<div class="col-sm-12" style="padding:15px">
<!-- separing -->
<?= UserPagesWidget::widget(['usr_id' => $model->user_id]) ?>
<!-- separing -->
</div>
<div class="col-sm-12" style="padding:15px">
<?= UserBlogsWidget::widget(['usr_id' => $model->user_id]) ?>
</div>
</div>
The problem is the show more button is displayed only for pages.
You need to adjust selectors to distinguish between two widgets. By default ScrollPager uses some generic selector (.list-view) that will match all list views. You should explicitly set ID for ListView widgets and use it in ScrollPager config as selector for widget initialization.
<?= ListView::widget([
// ...
'dataProvider' => $dataProviderBlog,
'options' => ['id' => 'blog-list-view'],
'pager' => [
'class' => \kop\y2sp\ScrollPager::className(),
'container' => '#blog-list-view',
'paginationSelector' => '#blog-list-view .pagination',
],
]) ?>
<?= ListView::widget([
// ...
'dataProvider' => $dataProviderContent,
'options' => ['id' => 'content-list-view'],
'pager' => [
'class' => \kop\y2sp\ScrollPager::className(),
'container' => '#content-list-view',
'paginationSelector' => '#content-list-view .pagination',
],
]) ?>
See https://kop.github.io/yii2-scroll-pager/#general-options
I'm trying to use fill my listView using an ArrayDataProvider. However the dataProvider consists of Arrays, not objects. I ran into this problem because the category in the model is an id, where I need the name corresponding to that id from another table. Hence I created an Array where the id is the corresponding name.
private function getDataProvider()
{
return new ArrayDataProvider([
'allModels'=>$this->getFaqs(), // returns array of faqs
'sort'=>[
'attributes'=>['id','category','question','answer']],
'pagination'=>[
'pageSize'=>10,
],
]);
}
Here is my ListView widget
echo ListView::widget([
'dataProvider' => $dataProvider,
'itemView' => function($dataProvider, $key, $index, $widget)
{
return Html::a($dataProvider->question,
Url::toRoute(['faq/view', 'id' => $dataProvider->primaryKey]));
}
]);
It works, I use it like this
$dataProvider = new ArrayDataProvider([
'allModels' => [['name' => '0am - 6am'], ['name' => '6am - 9pm'], ['name' => '9am - 12pm'], ['name' => '12pm - 3pm'], ['name' => '3pm - 6pm']],
]);
<?= ListView::widget([
'dataProvider' => $dataProvider,
'layout' => "{items}",
'itemOptions' => ['class' => 'item', 'style' => 'margin-bottom: 5px;'],
'itemView' => function ($model, $key, $index, $widget) use ($transportRun) {
//return print_r($model, true);
return Html::a(Html::encode($model['name']), ['delivery/index', 'DeliverySearch' => ['transport_run' => $transportRun, 'timeslot' => $key]], ['class' => 'btn btn-lg btn-primary btn-block']);
},
]) ?>
ListView and GridView can use any class that implements yii\data\DataProviderInterface. You can take a look here http://www.yiiframework.com/doc-2.0/yii-data-dataproviderinterface.html to see who implements it, so you can use any of those classes on both ListView and GridView.
You should also be able to do a
'allModels'=>$this->faqs, // returns array of faqs