Yii2 - Searching Gridview submits form - php

I have a form that uses selected rows in a Gridview as form input. The problem is that when I try searching the Gridview, it submits the form. I have tried enclosing the Gridview in Pjax and checking whether the request isPjax in the controller. It does not seem to be working, maybe I am missing something.
What I would like to be able to do is have users search the form for the relevant data, select it, select an item from the dropdownlist and then submit the form. Any suggestions?
This is my view:
<?php $form = ActiveForm::begin([]) ?>
<?php \yii\widgets\Pjax::begin() ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
['class' => 'yii\grid\CheckboxColumn'], //to select rows for the form
'name',
[
'attribute' => 'manager.name',
'label' => 'Manager',
],
],
]); ?>
<?php \yii\widgets\Pjax::end() ?>
<?= $form->field($model, 'id_questionnaire')->dropDownList($questionnaireItems) ?>
<div class="form-group">
<?= Html::submitButton(Yii::t('app', 'Submit'), ['class' => 'btn btn-success btn-block']) ?>
</div>
<?php ActiveForm::end() ?>
In my controller, I check for Pjax first but this does not work:
if(Yii::$app->request->isPjax){
//search
}
if($model->load(Yii::$app->request->post())) {
if (Yii::$app->request->post('selection')) {
foreach (Yii::$app->request->post('selection') as $id) {
//save the model
}
}
return $this->redirect(['questionnaire/index']);
}

Related

Send id chosen in dropdown list to action Yii2

I have a quick question. I implemented a dropdownList in a _form.php. Now my action crate won't work properly anymore. I am not sure if there is an issue with me sending the request to the action. But it's not really doing the trick anymore.
With the $form->field($model, 'team_idteam')->textInput() it worked just fine. So, this is what I have so far on the _form.php:
<div class="user-has-team-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'team_idteam')->textInput() //<-- This works perfectly. ?>
<?= $form->field($model, 'teamIdteam')->dropDownList(ArrayHelper::map(Team::find()->all(), 'idteam', 'name')) <-- This does not work at all ?>
<?= $form->field($model, 'user_iduser')->textInput() ?>
<?= $form->field($model, 'oncallduty')->checkbox() ?>
<div class="form-group">
<?= Html::submitButton(Yii::t('app', 'Save'), ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
My actionCreate looks like this:
public function actionCreate()
{
$model = new UserHasTeam();
if ($this->request->isPost) {
Yii::info("Test1"); // <-- It get's up to this point.
if ($model->load($this->request->post()) && $model->save()) {
Yii::info("Test2");
return $this->redirect(['view', 'team_idteam' => $model->team_idteam, 'user_iduser' => $model->user_iduser]);
}
} else {
$model->loadDefaultValues();
}
return $this->render('create', [
'model' => $model,
]);
}
The visuals work perfect and I can even chose different teams. If I create new teams, or delete old ones, they are shown or not shown as well. I have to admit I am a bit lost here.
EDIT
I dumped the $_POST array after the $model = new UserHasTeam(); and it gave out the following array:
[
'_csrf' => '0rkl0EAuFwjy9kdJNVQfVTQOkT22Kzo8bdvLAg2X0P_i0Ui-DEAkQ6WxfzsEAkwfBE_1UvNCDlsEjLtOefXmyA==',
'UserHasTeam' => [
'teamIdteam' => '3',
'user_iduser' => '1',
'oncallduty' => '0',
],
]
Yep. I am quite an idiot every now and then.
This is how I solved it:
<?= $form->field($model, 'team_idteam')->dropDownList(ArrayHelper::map(Team::find()->all(), 'idteam', 'name')) ?>

yii2 passing value from view to controller

I have this kind of problem. I have an input text that have template of radio in it.
the problem is that I want to get the value of that radio when I check it and store it to the database field.
my idea is to create a variable from model but i can't pass the radio value to that variable when i save it.
please help me I am stuck with it.
here is the images of view:
Controller action:
public function actionCreate()
{
$model = new QbQuestion();
if ($model->load(Yii::$app->request->post())) {
$answer = $model->answer;
$model->$answer;
$model->save();
return $this->redirect(Url::to(['qb-question/index']));
} else {
return $this->renderAjax('create', [
'model' => $model,
]);
}
}
View:
<div class="qb-question-form">
<?php $form = ActiveForm::begin([
'layout' => 'horizontal',
'fieldConfig' => [
'horizontalCssClasses' => [
'label' => 'col-sm-4',
'offset' => 'col-sm-offset-4',
'wrapper' => 'col-sm-8',
'button' => 'col-sm-8',
'error' => '',
'hint' => '',
],
],
]); ?>
<?php echo $form->errorSummary($model); ?>
<?= $form->field($model, 'q_cat')->dropDownList(
ArrayHelper::map(QbCategory::find()->all(), 'id', 'category'),
[
'prompt' => 'Select Category'
]) ?>
<?= $form->field($model, 'q_date')->dropDownList(
ArrayHelper::map(QbDate::find()->asArray()->all(), 'id',
function($model, $defaultValue) {
return $model['month'].' '.$model['year'];
}),
[
'prompt' => 'Select Date'
]) ?>
<?php echo $form->field($model, 'question')->textarea(['rows' => 5]) ?>
<?= $form->field($model, 'q_c1', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
Html::radio('answer').'</span>{input}</div>',
]); ?>
<?= $form->field($model, 'q_c2', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
Html::radio('answer').'</span>{input}</div>',
]); ?>
<?= $form->field($model, 'q_c3', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
Html::radio('answer').'</span>{input}</div>',
]); ?>
<?= $form->field($model, 'q_c4', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
Html::radio('answer').'</span>{input}</div>',
]); ?>
<?php echo Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>
</div>
thanks in advance.
radio field that you have take will always return 1, So you can't identify selected answer. You can do it normal html as below:
Change in Your Form file :
<?= $form->field($model, 'q_c1', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
'<input type="radio" name="QbQuestion[answer]" value="q_c1">'.'</span>{input}</div>',
]); ?>
<?= $form->field($model, 'q_c2', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
'<input type="radio" name="QbQuestion[answer]" value="q_c2">'.'</span>{input}</div>',
]); ?>
<?= $form->field($model, 'q_c3', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
'<input type="radio" name="QbQuestion[answer]" value="q_c3">'.'</span>{input}</div>',
]); ?>
<?= $form->field($model, 'q_c4', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
'<input type="radio" name="QbQuestion[answer]" value="q_c4">'.'</span>{input}</div>',
]); ?>
Here ,QbQuestion['answer'] return you the selected answer.
Change in controller:
public function actionCreate()
{
$model = new QbQuestion();
if ($model->load(Yii::$app->request->post())) {
// if you have answer attribute in model class than load that attribute
// no need of this line $answer = $model->answer;
// no need of this line $model->$answer;
// you can do it manually as below
$model->answer=$_REQEST['QbQuestion']['answer'];
$model->save();
return $this->redirect(Url::to(['qb-question/index']));
} else {
return $this->renderAjax('create', [
'model' => $model,
]);
}
}
The reason your attributes are not saving is because you haven't tied the field to the model, so incorrect field names are being submitted in the form.
It seems to me as if what you need is a radioList. The Html::radio() method just adds a radio button, not tied to any model. To use a radioList you need to do something like this;
First, create an array of possible answers in your view file;
$answers = array('q_c1' => $model->q_c1, 'q_c2' => $model=>q_c2, 'q_c3' => $model=>q_c3, 'q_c4' => $model=>q_c4);
Now, because it's a radio list, it will only submit data for one of the radio button. It will not allow selection of more than one radio button. Because of the way you are storing your data, you will need a temporary model attribute to store this value oin while the model gets populated and validated. Create this in your model like so;
public $answerToQuestion;
And allow it to be massively assigned;
public function rules() {
return [
[['answerToQuestion'], 'safe]
];
}
Now you can create your form field like this;
echo $form->field($model, 'answerToQuestion')->radioList($answers);
Yii should now generate the list of radio buttons with the correct names to tie them into your model and allow them to be massively assigned.
The attributes submitted by the form will be of the form (assuming your model is called Question;
Question[answerToQuestion] => 'q_c2'
It will pass validation. It's now up to your model logic to decode the selected answer into the relevant fields in your database.

How to use 2 form tag in same page in Yii

In frontend of Yii ,
I have 2 form :
1 Login Form
2 Signup
my signup form is working , but when login is not working ,
i found a error
Call to a member function formName() on null
//Form Code
<!-------signup---------->
<h1>Signup Form</h1>
<?php $form = ActiveForm::begin(['id' => 'form-signup', 'action' => Url::to(['site/signup'])]); ?>
<?= $form->field($modelSignup, 'username')->textInput(['autofocus' => true]) ?>
<?= $form->field($modelSignup, 'email') ?>
<?= $form->field($modelSignup, 'password')->passwordInput() ?>
<?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
<?php ActiveForm::end(); ?>
<!-------// signup---------->
<!-------login---------->
<h1>Login Form</h1>
<?php $form = ActiveForm::begin(['id' => 'form-login', 'action' => Url::to(['site/login'])]); ?>
<?= $form->field($modelLogin, 'username')->textInput(['autofocus' => true]) ?>
<?= $form->field($modelLogin, 'email') ?>
<?= $form->field($modelLogin, 'password')->passwordInput() ?>
<?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
<?php ActiveForm::end(); ?>
<!-------//login---------->
Try this:
Controller:
public function actionIndex() {
$modelSignup = new SignupForm();
$modelLogin = new LoginForm();
return $this->render('index',[ 'modelSignup' => $modelSignup,'modelLogin' => $modelLogin ]);
}
Also remove this check from your code:
if(isset($modelLogin)
In your view file you are using two models, one for signup and the other for login. But from your comment I had note that you are passing only one model at a time it may be the first one or the second one. So you should replace your actionIndex() with the following code:
public function actionIndex() {
$modelSignup = new SignupForm();
$modelLogin = new LoginForm();
if(isset($_POST['SignupForm'])) {
//code for signup process
}
if(isset($_POST['LoginForm'])) {
//code for login process
}
return $this->render('index', [ 'modelSignup' => $modelSignup, 'modelLogin' => $modelLogin ]);
}
This will help you.

Yii2 model with scenarios save all except the password field

In my application i've a model called User Where i've implemented a scenario for validations.
const SCENARIO_RESET_PASSWORD = 'passwordReset';
public function rules()
{
return[
[['name','surname','password','username','id_role'], 'required'],
[['email','email2'], 'email'],
[['username','email'], 'unique'],
['confirmPassword', 'compare', 'compareAttribute'=>'password', 'on' => self::SCENARIO_RESET_PASSWORD]
];
}
With this configuration i can create a new User, delete one and update all fields except for 'password'.
This is the action in my controller:
public function actionUpdate($id)
{
$user = User::findOne($id);
if($user->load(Yii::$app->request->post())&& $user->validate()) {
$user->update();
$this->redirect(\yii\helpers\Url::toRoute('index'));
}
return $this->render('update',[
'user' => $user,
]);
}
i've already checked that the field 'password' is passed on post parameters with success.
and this is my view:
<h1> Edit User </h1>
<?php
$form = ActiveForm::begin([
'id' => 'active-form',
'options' => [
'class' => 'form-horizontal',
'enctype' => 'multipart/form-data'
],
]);
?>
<?= $form->errorSummary($user); ?>
<?= $form->field($user, 'name') ?>
<?= $form->field($user, 'surname') ?>
<?= $form->field($user, 'username') ?>
<?= $form->field($user, 'email') ?>
<?= $form->field($user, 'password')->passwordInput() ?>
<?php if(Yii::$app->user->identity->id_role === User::USER_ADMIN): ?>
<?= $form->field($user, 'id_role')->dropDownList(
Role::find()->select(['name','id'])->indexBy('id')->column(),
['prompt'=>'Select a role']
);
?>
<?php endif; ?>
<div class="form-group">
<?= Html::submitButton('Save the user', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
I really don't know why i'm getting this error
Please remove
'on' => self::SCENARIO_RESET_PASSWORD
or
define your SCENARIO in your controller action as
$user->scenario = 'SCENARIO_RESET_PASSWORD';

Yii2: What is the correct way to include the grid-view widget in form file

I have this code in my _form.php. The problem I am facing is if I am putting the pagination part below it does work, but filter doesn't work. If I am putting the filter part below the pagination part, the filter part work and pagination doesn't work.
Again my netbeans IDE is complaining that I have declared the $dataprovider twice.
here is my code.
Form part:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\grid\GridView;
use yii\data\ActiveDataProvider;
use app\models\State;
use app\models\StateSearch;
use app\models\City;
/* #var $this yii\web\View */
/* #var $model app\models\State */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="row">
<div class="col-lg-3">
<div class="col-lg-4 col-lg-offset-1">
<div class="state-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'state_name')->textInput(['maxlength' => 50]) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
Pagination part
<?php
$dataProvider = new ActiveDataProvider([
'query' => State::find(),
'pagination' => [
'pageSize' => 5,
],
]);
?>
Filter part
<?php
$searchModel = New StateSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
?>
Gridview Widget
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
// 'id',
'state_name',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
</div>
What is the correct approach that my filter and pagination both works.
How to show action column icons inline(that is horizontally), I can do it at view level by setting the width, but thinking if there is a global setting for that.
Can provide the pagination option on the grid-view for user selection like 5,10 or all.
Thanks.

Categories