I have been searching for hours on the internet on trying to remove the initial filter on yii2 gridview. All the options point on setting a default value in the search. I would like when the index page loads, that no data is shown in the gridview only when user search. Any assistance is highly appreciated.
https://github.com/yiisoft/yii2/issues/5668
https://stackoverflow.com/questions/33608796/default-filter-in-gridview-with-yii2
<?php
use yii\helpers\Html;
use yii\grid\GridView;
/* #var $this yii\web\View */
/* #var $searchModel frontend\models\AnimalSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Animal and Animal Products Search';
$this->params['breadcrumbs'][] = $this->title;
?>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
//////prevent the dropdown from being populated when the user click back
$(window).bind("pageshow", function() {
$("#commodity").val('');
$("#species").val('');
$("#finality").val('');
$("#origin").val('');
});
</script>
<div class="animal-index">
<h1 align="center"><?= Html::encode($this->title) ?></h1>
<br>
<?php echo $this->render('_search', ['model' => $searchModel]); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
// 'filterModel' => $searchModel,
// 'showHeader'=> false,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
// 'id',
'commodity',
'species',
'finality',
'origin',
// 'intendeduse',
// 'risk',
// 'conditions',
// 'scu',
// 'maf',
// 'cities',
// 'fisheries',
// 'forestry',
// 'comments',
['class' => 'yii\grid\ActionColumn',
'visibleButtons' => [
'update' =>false, // or whatever condition
'delete' => false,
],
],
],
]); ?>
</div>
You need to add a condition that would yield no results whenever no search params are present
update your search model to something like this
public function search($params)
{
$query = Model::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
// this ensures no rows are returned if nothing was submitted
if (is_null($params) || empty($params)) {
$query->where('0 = 1');
return $dataProvider;
}
// ....
}
Related
I am quite new to Yii 2 and I am currently trying to display data from the Teams model in the User view in a GridView. In Yii1 I used a function with the $data variable. In Yii2 it does not seem to work that way.
I have tried the following in the /user/index.php
<?php
use yii\helpers\Html;
use yii\grid\GridView;
/* #var $this yii\web\View */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = Yii::t('app', 'Users');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="user-index">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a(Yii::t('app', 'Create User'), ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
// ['class' => 'yii\grid\SerialColumn'],
// 'iduser',
'username',
'surname',
'givenname',
'email:email',
'mobile',
'admin:boolean',
'language',
// Below is what I have been trying to do so far...
['class' => 'yii\grid\DataColumn',
'label' => 'Teams',
'value' => 'getTeams($data-teams)'
],
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
<?php
// And this is the function I use. In Yii1 it worked just fine.
function getTeams($data) {
$tmp = "";foreach ($data as $team) {
$tmp .=$team['name'].", ";
}
return trim($tmp, ", ");
}
?>
EDIT
In the User model this is what I have set the relation as followed:
public function getTeamIdteams()
{
return $this->hasMany(Team::className(), ['idteam' => 'team_idteam'])->viaTable('user_has_team', ['user_iduser' => 'iduser']);
}
While in the Team model I have set following relations:
public function getUserIdusers()
{
return $this->hasMany(User::className(), ['iduser' => 'user_iduser'])->viaTable('user_has_team', ['team_idteam' => 'idteam']);
}
I have been looking around but can't seem to find a solution for this one. Basically I simply want the Team to be displayed in which the user is a part of. There is a table called UserHasTeam in which the id's of the teams and users are saved.
I am a little lost on how to go about the entire thing. Any help is greatly appreciated.
I assume you have properly set relation to Team model in User model. See the Relations via Junction Table part of guide if you don't know how to set the relation.
You can use closure in $value property of DataColumn to control what value is used for column.
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
// ... other columns ...
[
'label' => 'Teams',
'value' => function($model) {
$tmp = "";
foreach ($model->teams as $team) {
$tmp .= $team->name .", ";
}
return trim($tmp, ", ");
}
],
],
]); ?>
You might also want to consider using eager loading to load all related at once instead of running query for each user in grid.
in view/index file where showing all data of model i used
'filter'=>ArrayHelper::map(Mobile::find()->asArray()->all(),'id', 'mobile'),
it works truely but not display values . and it has just some empty fields .
here is my view/index code:
<?php
use yii\helpers\Html;
use yii\grid\GridView;
use yii\helpers\ArrayHelper ;
use app\models\Mobile;
/* #var $this yii\web\View */
/* #var $searchModel app\models\MobileSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Mobiles';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="mobile-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<p>
<?= Html::a('Create Mobile', ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'id',
[
'attribute'=>'id',
'value'=>'id',
//'filter'=>array("1"=>"open","2"=>"in progress","3"=>"closed")
'filter'=>ArrayHelper::map(Mobile::find()->asArray()->all(),'id', 'mobile'),
],
'sim_num',
'network',
'twog_network',
'threeg_network',
// 'fourg_network',
// 'technology',
// 'gps',
// 'gateway_connection',
// 'super_id',
// 'camera',
// 'resolusion_camera',
// 'automatic_focus',
// 'camera_flash',
// 'video:ntext',
// 'camera_others:ntext',
// 'camera_selfie:ntext',
// 'username',
// 'body:ntext',
// 'title:ntext',
// 'state',
// 'imageFile',
// 'size',
// 'weight',
// 'inner_memory',
// 'screen_size',
// 'screen_type',
// 'wifi_desc',
// 'bluetooth',
// 'batery',
// 'bady_struct',
// 'process',
// 'other:ntext',
// 'os',
// 'gesture',
// 'items',
// 'speaker',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
where
<?php
'attribute'=>'id',
'value'=>'id',
'filter'=>ArrayHelper::map(Mobile::find()->asArray()->all(),'id', 'mobile'),
],
?>
i repeat it shows number of fields and search correct when click on each fields and a little problem that it does not display values ...
in inspect element of site we have:
<option value="2"></option>
and i wanna shows '2' between option tags..
Please help me.
As from the comments, here's the solution to your problem:
ArrayHelper::map(Mobile::find()->asArray()->all(),'id', 'id');
Hi I have 2 tables and models for them. First of them is
User
and second
News
I want to take user id from table News and draw her name and surname. There is printscreen of table News:
I am trying to use the function:
public function getUrUser()
{
$q= News::find()->where(['urUser_Id' =>'Id'])->one();
$RoyalUserData=User::findOne($q);
//$RoyalUserData= User::find()->where(['Id' => $q])->one();
return $RoyalUserData->Name;
}
But this doesnt work. Only when I prescribe to q value 3 for egzample then it work. I know that is the wrong code in my first line of my function probably. I know that is easy but I am a beginner and I've fought with the code for about 1 hour. Can anyone help me?
In my view I use this:
<?=$model->getUrUser();?>
And I use this in ListView.
My controller:
public function actionIndex()
{
$model = new NewsForm();
$searchModel = new NewsSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$dataProvider->setSort(['defaultOrder' => ['Id'=>SORT_DESC]]);
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$model->saveNews();
return $this->redirect(['/content/news']);
} else {
return $this->render('index', [
'model' => $model,
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
}
My index where i use _item:
echo ListView::widget( [
'dataProvider' => $dataProvider,
'itemView' => '_item',
], $options = ['class' => 'sorter'] ); ?>
And content of _item
<?php
use yii\helpers\Html;
?>
Treść Newsa:
<?=$model->Text;?> <br>
Autor:
<?=Yii::$app->user->identity->Name?>
<?=Yii::$app->user->identity->Surname?> <br>
Status Newsa:
<?=$model->cnNewsContentType_Id;?> <br>
<?= Html::a('Update', ['update', 'id' => $model->Id], ['class' => 'btn btn-primary']) ?>
<?= Html::a('Delete', ['delete', 'id' => $model->Id], [
'class' => 'btn btn-danger',
'data' => [
'confirm' => 'Are you sure you want to delete this item?',
'method' => 'post',
],
]) ?><br><br><br>
The News::find()->where(['urUser_Id' =>'Id'])->one() return a model not a field
then you must get the id field by the model this way
public function getUrUser($id)
{
// you already have the news model so don't need retrieve it
// it's enough pass the urUser_Id by $id
$RoyalUserData=User::findOne($id);
return $RoyalUserData->Name;
}
Then if you want show the ($RoyalUserData) Name in _item
<?=$model->getUrUser($model->urUser_Id);?>
public function getUrUser()
{
$q = News::find()->where(['urUser_Id' =>'Id'])->one();
return $q->user->name;
}
In user model you should create relation:
class News extends ActiveRecord
{
// ...
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
}
Ok, ill explain what i have first,
--A database table called cases.
This holds all of the cases to i need to display in a gridview
--Three tables called Category, Subcategory and ChildCategory
The cases from table case will be linked to a childcategory.
So i have made three DropDownLists that are populated from the individual category tables in the database. For example:
_categories.php
yii\widgets\Pjax::begin(['id' => 'categories']);
$form = ActiveForm::begin();
echo $form->field($searchModel, 'category')
->dropDownList(
ArrayHelper::map($allCategory, 'id', 'name'),
[
'onchange'=>'getSubcategory()',
]
);
//To stop errors, if first category not chosen make subcategory and empty drop down.
$subcategory = array(
"empty" => ""
);
echo $form->field($searchModel, 'subcategory')
->dropDownList(
ArrayHelper::map($subcategory, 'id', 'name'),
[
'onchange'=>'getChildcategory()',
]
);
//To stop errors, if second category not chosen make childcategory and empty drop down.
$childcategory = array(
"empty" => ""
);
echo $form->field($searchModel, 'childcategory')
->dropDownList(
ArrayHelper::map($childcategory, 'id', 'name'),
[
//'onchange'=>'getChildCategory()',
'onchange'=>'submitNow()',
]
);
ActiveForm::end();
yii\widgets\Pjax::end();
So what happens is when the first category is selected it runs "onchange" => getSubcategory. This will basically send an Ajax request to my controller with the value of the selected option. It will then pull back the subcategories where the subcategory_id = the value of the selected option. It then populated the subcategory drop down with this information.
this function is on _categories.php with the category drop downlists above
function getSubcategory(){
//#casesearch-category is the first drop down list
var firstcategory = $('#casesearch-category').val();
var childcategory = document.getElementById('casesearch-childcategory');
childcategory.options.length = 0;
$.ajax({
url: '<?php echo \Yii::$app->getUrlManager()->createUrl('cases/subcategories') ?>',
type: 'POST',
dataType: 'json',
data: {
firstcategory: firstcategory
},
success: function(data) {
var subcategory = document.getElementById('casesearch-subcategory');
//if select is changed again, make the options length 0 so that it gets rid of previous appends.
subcategory.options.length = 0;
for(var i=0; i<data.length; i++){
subcategory.options[i] = new Option (data[i].name);
subcategory.options[i].value = data[i].subcategory_id;
}
subcategory.options.selectedIndex = -1;
if(subcategory.options.length === 1){
getChildcategory();
}
}
});
}
So when this ajax request reaches my controller it does this:
CasesController.php
public function actionSubcategories()
{
if(isset($_POST['firstcategory'])){
$firstcategory = $_POST['firstcategory'];
// SELECT * FROM `subcategory` WHERE `parent_id` = $firstcategory
$subcategory = Subcategory::findSubcategory($firstcategory);
}
return \yii\helpers\Json::encode($subcategory);
}
Okay so that was just a little bit to help you understand the category side of things. Now i have a gridview that is populated from the database when the page is submitted. However as i have done ajax to get my categories i need the gridview to change with pjax when ever the categories are changed.
So in my controller actionIndex is sends through the searchModel and dataprovider for the gridview like so:
CasesController.php
public function actionIndex()
{
$model = new Cases;
$searchModel = new CaseSearch();
$allCategory = Category::find()->all();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'allCategory' => $allCategory,
'model' => $model
]);
}
Then on my index page where it displays the grid view is here::
NOTE::Index.php renders the category dropdownlists seen above _categories.php
<?= $this->render('_categories', [
'model' => $model,
'searchModel' => $searchModel,
'allCategory' => $allCategory
]) ?>
<?php Pjax::begin(['id' => 'cases']) ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
'case_id',
'name',
'judgement_date',
'year',
'neutral_citation',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
<?php Pjax::end() ?>
Ok So here is the part where i am stuck! I assume what i am meant to do is somehow update the searchModel and dataProvider for the gridview but i am unsure how to do this. As if i send an ajax request to controller to change it it will then have to render the page again which defeats the objective.
at the top of _categories.php
function submitNow(){
$.pjax.reload({container:"#cases"}); //Reload GridView
}
This function is called when the last childcategory is selected.I know something will have to happen here to do this but i do not know what.
Can anyone help?
<?php use yii\widgets\Pjax; ?>
<?php Pjax::begin() ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
'case_id',
'name',
'judgement_date',
'year',
'neutral_citation',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
<?php Pjax::end() ?>
Following this Wiki Yii 2.0: Pjax on ActiveForm and GridView - Yii2
I have tried to use my gridview to update on Ajax without page-reload, but couldn't succeed.
code of my _form.php
<?php
$this->registerJs(
'$("document").ready(function(){
$("#new_medicine").on("pjax:end", function() {
$.pjax.reload({container:"#medicine"}); //Reload GridView
});
});'
);
?>
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\grid\GridView;
//use yii\grid\Gridview;
use yii\data\ActiveDataProvider;
/* #var $this yii\web\View */
/* #var $model app\models\Medicine */
/* #var $form yii\widgets\ActiveForm */
?>
<!-- <div class="row">
<div class="col-lg-6 col-lg-offset-3"> -->
<div class="medicine-form">
<?php yii\widgets\Pjax::begin(['id' => 'new_medicine']) ?>
<?php $form = ActiveForm::begin(['options' => ['data-pjax' => true ]]); ?>
<?= $form->field($model, 'medicine_id')->textInput(['maxlength' => 10]) ?>
<?= $form->field($model, 'medicine_name')->textInput(['maxlength' => 50]) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
<?= Html::submitButton($model->isNewRecord ? 'Save & New' : '',$option=['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary','name'=>'save_and_new']) ?>
</div>
<?php ActiveForm::end(); ?>
<?php yii\widgets\Pjax::end() ?>
</div>
Code in my controller
public function actionIndex()
{
$model = new Medicine();
if ($model->load(Yii::$app->request->post()) && $model->save())
{
$model = new Medicine(); //reset model
}
$searchModel = new MedicineSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'model' => $model,
]);
}
code in index.php
<?php
use yii\helpers\Html;
use yii\grid\GridView;
/* #var $this yii\web\View */
/* #var $searchModel app\models\MedicineSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Medicines';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="medicine-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<p>
<?= Html::a('Create Medicine', ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?php \yii\widgets\Pjax::begin(['id' => 'medicine']); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'medicine_id',
'medicine_name',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
<?php \yii\widgets\Pjax::end(); ?>
</div>
I think I have followed the instructions very carefully, but surely I am missing something as the grid-view is not showing the new records added without page-reload.
Any help will be greatly appreciated.
Thanks.
try to explain how to do it as a widget; it's a generic solution, so contact me in case of troubles:
Controller (#your-alias/controllers/yourController):
...
public function actionManage($param=''){
$model = new YourModel();
if (Yii::$app->request->isPjax && $model->load(Yii::$app->request->post()) && $model->save())
{
$model = new YourModel(); //reset model
}
$model->paramId = $param;
$queryParams = Yii::$app->request->getQueryParams();
$queryParams['YourModelSearch']['param'] = $param;
$searchModel = new YourModelSearch();
$dataProvider = $searchModel->search($queryParams);
return $this->renderAjax('#your-alias/widgets/views/index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'model' => $model,
]);
}...
widgets (#your-alias/widgets/) [form, view]:
_form:
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\widgets\Pjax;
/**
* #var yii\web\View $this
* #var yourModule/models/YourModel $model
* #var yii\widgets\ActiveForm $form
*/
?>
<?php
$js = <<<JS
// get the form id and set the event
$('form#{$model->formName()}').on('beforeSubmit', function(e) {
var \$form = $(this);
// do whatever here, see the parameter \$form? is a jQuery Element to your form
console.log(\$form);
console.log("MODEL CODE = " + $("#yourmodel-code").val());
}).on('submit', function(e){
e.preventDefault();
});
JS;
//$this->registerJs($js);
$this->registerJs(
'$("#new-your-model").on("pjax:end", function() {
commonLib.divAction("#div_new_model", "hide"); //hide form
$.pjax.reload({container:"#models"}); //Reload GridView
});', \yii\web\View::POS_READY
);
?>
<div class="model-form">
<?php Pjax::begin(['id' => 'new-model', 'timeout' => false, 'enablePushState' => false]) ?>
<?php $form = ActiveForm::begin([
'id' => $model->formName(),
//'method' => 'post',
'action' => ['/module/controller/manage?param='.$model->code],
'options' => ['data-pjax' => true ],
//'layout' => 'default',
]); ?>
<?= $form->field($model, 'code')->textInput(['maxlength' => 255]) ?>
...
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
<?php yii\widgets\Pjax::end() ?>
</div>
index view (grid view):
use yii\helpers\Html;
use yii\grid\GridView;
use yii\widgets\Pjax;
/**
* #var yii\web\View $this
* #var yii\data\ActiveDataProvider $dataProvider
* #var yourModule\models\search\YourModelSearch $searchModel
*/
?>
<div class="model-index">
<!--h1><!--?= Html::encode($this->title) ?></h1-->
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<p>
<?= Html::button(Yii::t('bp', 'Add ...'), [
'class' => 'btn btn-success',
'onclick'=>'js:commonLib.divAction("#div_new_model", "show")'
])?>
</p>
<div id="div_new_model" style="display:none">
<?= Html::button(Yii::t('common', 'Cancel'), [
'class' => 'btn btn-success',
'onclick'=>'js:commonLib.divAction("#div_new_model", "hide")'
])?>
<!-- Render create form -->
<?= $this->render('_formModel', [
'model' => $model,
]) ?>
</div>
<?php Pjax::begin(['id' => 'models', 'timeout' => false, 'enablePushState' => false]) ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
...
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
<?php Pjax::end() ?>
</div>
widget call (in view):
echo #your-alias\widgets\YourWidget::widget([
'param' => $model->param,]);
$.pjax.reload('#my-grid-pjax' , {timeout : false});
To update GridView table without page reload using pjax:
use yii\grid\GridView;
use yii\widgets\Pjax;
Pjax::begin(['id' => 'todaysactivity', 'timeout' => false, 'enablePushState' => false])
Use jQuery/JavaScript as follows:
var url = baseurl + '/activity/logging'; // url where the gridview table need to update
$.pjax.reload({container: "#todaysactivity", url: url}); // refresh the grid
I couldn't find a suitable solution to update the grid-view widget using pjax.
I resolved by using a auto-refresh method for the grid-view page. I understand that this is not the best solution and I am still looking for a suitable solution.
The method I have used is like this:
<script>
function autoRefresh()
{
window.location.reload();
}
setInterval('autoRefresh()', 60000); // this will reload page after every 1 minute.
</script>
What you're looking for is
<script type="text/javascript">
$.pjax.defaults.timeout = false;
</script>
The default pjax timeout setting doesn't give the page time to do anything so it reloads.
Reference