I have a form with a CheckboxList generated through a model "Candidates" and I need to make a vote where the voter can select multiple candidates and record.
How do I 'pick up' the selected candidates and write to the votes table / model ??
Form "votos"
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'candidato_id')->checkboxList(ArrayHelper::map(Candidatos::find()->where(['status' => 1])->orderBy("nome ASC")->all(), 'id', 'nome')); ?>
<?= Html::activeHiddenInput($model, 'eleicao_id', ['value' => 1]) ?>
<?= Html::activeHiddenInput($model, 'cargo_id', ['value' => 1]) ?>
<?= Html::activeHiddenInput($model, 'urna_id', ['value' => 1]) ?>
<div class="form-group">
<?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
Model "Votos"
namespace app\models;
use Yii;
class Votos extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'votos';
}
public function rules()
{
return [
[['eleicao_id', 'candidato_id', 'cargo_id', 'urna_id', 'data'], 'required'],
[['eleicao_id', 'candidato_id', 'cargo_id', 'urna_id'], 'integer'],
[['data'], 'safe'],
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'eleicao_id' => 'Eleicao ID',
'candidato_id' => 'Candidato ID',
'cargo_id' => 'Cargo ID',
'urna_id' => 'Urna ID',
'data' => 'Data',
];
}
}
Controller "VotosControllers"
public function actionVotacao()
{
$model = new Votos();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('votacao', [
'model' => $model,
]);
}
Slightly unrelated, but if you haven't already I would strongly suggest making sure you have something like xdebug set up so you can quickly see what your code is doing as you make your changes. Being able to set breakpoints and see what your form has submitted can go a long way to helping you solve a problem like this on your own and the framework becomes less mysterious. With that out of the way, something like the following MIGHT help as far as the controller goes. There is other validation you would want to do as well I should add. Maybe the each validator which you can read up on here. For actionUpdate() you would need to look at deleting all the values that relate to the related id and re-populate with the new ones, checkout deleteAll. Hopefully I don't get smashed too hard for providing this solution which is not a drop in solution.
public function actionVotacao()
{
$model = new Votos();
if (Yii::$app->request->isPost) {
$model->load(Yii::$app->request->post());
if ($model->save()) {
// Save the checkbox values.
if (!empty(Yii::$app->request->post()['Votos']['XXXX'])) { // Your form should give you an idea of what the XXXX should be, xdebug is also your friend.
foreach (Yii::$app->request->post()['Votos']['XXXX'] as $candidato_id) {
$candidato = new Candidato();
$candidato->id = $candidato_id;
if (!$candidato->save()) print_r($candidato->errors);
}
}
}
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('create', [
'model' => $model,
]);
}
Related
I have a voting form and I would like to validate the minimum and maximum number of candidates that each voter can vote for. These max and min values are stored in the logged user's session. What better way to do it?
MODEL Voto.php
public static function tableName()
{
return 'voto';
}
public function rules()
{
return [
[['eleicao_id', 'candidato_id', 'cargo_id', 'urna_id', 'created'], 'required','message'=> 'Selecione no mínimo 1 candidato!'],
[['eleicao_id', 'cargo_id', 'urna_id'], 'integer'],
[['created','candidato_id'], 'safe'],
[['eleitor_hash'], 'string', 'max' => 255],
];
}
FORM _form_votacao.php
<?php $form = ActiveForm::begin(); ?>
<div class="row">
<?php
$candidato = ArrayHelper::map(candidato::find()
->where(['status' => 1])
->Andwhere(['eleicao_id' => Yii::$app->user->identity->eleicao_id])
->orderBy("nome ASC")
->all(), 'id', 'nome'
);
echo $form->field($model, 'candidato_id')->checkboxList($candidato, [
'class' => 'h4',
'data-toggle' => 'button',
'item' => function($index, $label, $name, $checked, $value) {
return "<label class='col-md-5'><input type='checkbox' {$checked} name='{$name}' value='{$value}'> {$label}</label>";
}])->label(false);
?>
</div>
<br>
<div class="row text-center">
<div class="form-group">
<?= Html::submitButton('Confirmar', ['class' => 'btn btn-success']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
Note: This list of candidates is dynamic, loads the candidates according to the parameters of the user logged in.
Rules Test UPDATE:
public function rules()
{
return [
['candidato_id', 'validateCandidates','message'=> 'teste'],
];
}
public function validateCandidates($attribute, $params, $validator){
if(count($this->candidato_id) >= 4){ // test with value 4
$this->addError($attribute, 'Error message');
}
}
Create custom validation. Something like this:
Model Voto.php
public function rules()
{
return [
....
['candidato_id', 'validateCandidates'],
....
];
}
public function validateCandidates($attribute, $params, $validator){
if(count($this->candidato_id) < {session_min} and count($this->candidato_id) > {session_max}){
$this->addError($attribute, 'Error message');
}
}
I have a model called Patientinformation.php and a model called AlternativeInformation.php. I would like to use the two models in the patientinformation_form.php
Patientinformation model:
- id (PK)
- patient_id
- patient_initials
- collection_site
- cancer
- study (FK to study model)
AlternativeInformation model:
- alternative_id (PK)
- patients_patient_id (FK to id of the Patientinformation model)
- alternative_study (FK to study model)
- alternative_patient_id
I have updated the Patientinformation controller as well as the create.php file and the _form.php file.
If I enter values in the Patientinformation form.php, I am redirected to the Patientinformation view site. The values of the Patientinformation model (id, patient_id, patient_initials, collection_site, cancer and study) are saved in the database. However, the values of the AlternativeInformation model (alternative_study and alternative_patient_id) are not saved in the database.
This is the PatientinformationController.php file:
<?php
namespace app\controllers;
use Yii;
use app\models\Patientinformation;
use app\models\AlternativeInformation;
use app\models\PatientinformationSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* Creates a new Patientinformation model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new Patientinformation();
$modelAlternative = new AlternativeInformation();
if ($model->load(Yii::$app->request->post()) && $modelAlternative->load(Yii::$app->request->post())){
$model->save();
$modelAlternative->patients_patient_id = $model->id;
$modelAlternative->save();
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('create', [
'model' => $model,
'modelAlternative' => $modelAlternative,
]);
}
This is the create.php file:
<?php
use yii\helpers\Html;
/* #var $this yii\web\View */
/* #var $model app\models\Patientinformation */
/* #var $modelAlternative app\models\AlternativeInformation */
$this->title = 'Add patient';
$this->params['breadcrumbs'][] = ['label' => 'Patients', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="patientinformation-create">
<h1><?= Html::encode($this->title) ?></h1>
<?= $this->render('_form', [
'model' => $model,
'modelAlternative' => $modelAlternative,
]) ?>
</div>
And this is the _form.php file:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use app\models\CollectionSiteInformation;
use app\models\AlternativeInformation;
use app\models\StudyInformation;
use app\models\CancerInformation;
use unclead\multipleinput\MultipleInput;
use kartik\select2\Select2;
/* #var $this yii\web\View */
/* #var $model app\models\Patientinformation */
/* #var $modelAlternative app\models\AlternativeInformation */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="patientinformation-form">
<?php $form = ActiveForm::begin(); ?>
<p>
Please note that all fields marked with an asterisk (<font color="red">*</font>) are required.
</p>
<?= $form->field($model, 'study')->widget(Select2::classname(), [
'data' => ArrayHelper::map(StudyInformation::find()->all(),'id','study'),
'language' => 'en',
'options' => ['placeholder' => 'Please select a study'],
]);
?>
<?= $form->field($model, 'patient_id')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'patient_initials')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'collection_site')->widget(Select2::classname(), [
'data' => ArrayHelper::map(CollectionSiteInformation::find()->all(),'id','collection_site'),
'language' => 'en',
'options' => ['placeholder' => 'Please select a collection site'],
]);
?>
<?= $form->field($model, 'cancer')->widget(Select2::classname(), [
'data' => ArrayHelper::map(CancerInformation::find()->all(),'id','cancer'),
'language' => 'en',
'options' => ['placeholder' => 'Please select a cancer type'],
]);
?>
<?= $form->field($modelAlternative,'alternative_study')->widget(MultipleInput::class,[
'max' => 6,
'allowEmptyList' => false,
'enableGuessTitle' => true,
'columns' => [
[
'name' => 'alternative_study',
'type' => 'dropDownList',
'title' => 'Alternative Study',
'items' => ArrayHelper::map(studyInformation::find()->asArray()->all (),'id','study'),
'options' => ['prompt' => 'Please select an alternative study if applicable'],
],
]
])
->label(false);
?>
<?= $form->field($modelAlternative,'alternative_patient_id')->widget(MultipleInput::class,[
'max' => 6,
'allowEmptyList' => false,
'enableGuessTitle' => true,
'columns' => [
[
'name' => 'alternative_patient_id',
'title' => 'Alternative patient ID',
'options' => ['prompt' => 'Please select an alternative study if applicable'],
],
]
])
->label(false);
?>
<div class="form-group">
<?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
If I don`t use unclead\multipleinput\MultipleInput in my _form.php, all the values of AlternativeInformation model (alternative_study and alternative_patient_id) are saved into the model/database.
So I assume that I don`t pass any items to the MultipleInput widget.
This is the AlternativeInformation model file:
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['patients_patient_id', 'alternative_study'], 'required'],
[['patients_patient_id', 'alternative_study'], 'integer'],
[['alternative_patient_id'], 'string', 'max' => 265],
[['patients_patient_id'], 'exist', 'skipOnError' => true, 'targetClass' => PatientInformation::className(), 'targetAttribute' => ['patients_patient_id' => 'id']],
[['alternative_study'], 'exist', 'skipOnError' => true, 'targetClass' => StudyInformation::className(), 'targetAttribute' => ['alternative_study' => 'id']],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'alternative_id' => 'Alternative ID',
'patients_patient_id' => 'Patients Patient ID',
'alternative_study' => 'Alternative Study',
'alternative_patient_id' => 'Alternative Patient ID',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getPatientsPatient()
{
return $this->hasOne(PatientInformation::className(), ['id' => 'patients_patient_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getAlternativeStudy()
{
return $this->hasOne(StudyInformation::className(), ['id' => 'alternative_study']);
}
}
Does anyone have any suggestions how this issue can be solved? How will be the values of "alternative_study" and "alternative_patient_id" saved into the AlternativeInformation model if using the MultipleInput widget?
I really need the option in the form to enter no, one or several alternative studies as well as alternative patient ids.
I really appreciate any help how I can solve this issue.
Thanks :)
You are probably getting some validation errors that you can't see because you are redirecting to the view action even if the AlternativeInformation model has validation errors.
The first step towards finding a solution would be making sure that, if AlternativeInformation doesn't save you show the form again, that way you will see the validation errors.
Update your controller code to this:
public function actionCreate()
{
$model = new Patientinformation();
$modelAlternative = new AlternativeInformation();
if ($model->load(Yii::$app->request->post())
&& $modelAlternative->load(Yii::$app->request->post())
&& $model->save()) {
$modelAlternative->patients_patient_id = $model->id;
if ($modelAlternative->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
}
return $this->render('create', [
'model' => $model,
'modelAlternative' => $modelAlternative,
]);
}
That should help you find the problem, it will also give your users information about any future errors that may happen.
The validation problem may be on alternative_patient_id, it seems that you are not passing any items to the MultipleInput widget.
Update your controller with the following code.
public function actionCreate()
{
$model = new Patientinformation();
$modelAlternative = new AlternativeInformation();
if ($model->load(Yii::$app->request->post()) && $modelAlternative->load(Yii::$app->request->post())){
if($model->save()){
$modelAlternative->patients_patient_id = $model->id;
$modelAlternative->save();
return $this->redirect(['view', 'id' => $model->id]);
}
}
return $this->render('create', [
'model' => $model,
'modelAlternative' => $modelAlternative,
]);
}
I need help building a simple protocol form with multiple attachments, where the user can change these attachments (files) later. That is, the attachments must have binding to a protocol.
(In this case I created 2 tables: mod_protocol and mod_files)
How should my code stay so that when I insert a new form, the attachments of this form are written to the mod_files table? (I'm not sure how to build a loop to write the files)
I'm at the beginning of this project, check out my files:
protocol form
<div class="protocol-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'description')->textarea(['rows' => 8]) ?>
<?= $form->field($model, 'files[]')->fileInput(['multiple' => true,]) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Save' : 'Save', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
protocol model
<?php
namespace app\modules\protocol\models;
use Yii;
class Protocol extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'mod_protocol';
}
public function rules()
{
return [
[['name'], 'required'],
[['name','description'], 'string', 'max' => 200],
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Nome',
'description' => 'Descrição'
];
}
}
protocol controlller
public function actionCreate()
{
$model = new Protocol();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
files model
<?php
namespace app\modules\protocol\models;
use Yii;
class Files extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'mod_files';
}
public function rules()
{
return [
[['filename','protoco_id'], 'safe'],
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'filename' => 'Nome do Arquivo',
'protoco_id' => 'Protocolo'
];
}
}
So if file is an array:
use yourapp/model/ModFile;
...
public function actionCreate()
{
$model = new Protocol();
// I would write some logic, verify this saves first.
foreach($model->files as $file) {
$model_file = new ModFile();
$model_file->file = $file;
$model_file->save();
}
// If successful then save the main model.
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
I have two dropDownlist in index, when I select the submit button it will get action in controller, and it performs some operations and again render the index with gridview, but the Selected dropDownList become blank, how can I set the default in dropDownllist??
Any suggestion should be appreciatable...
this is my view
<div class="col-sm-12" align="center">
<?= $form->field($model, 'fk_int_payroll_month')->dropDownList(
ArrayHelper::map(TblPayrollMonth::find()->all(), 'pk_int_payroll_month_id','vchr_month'),
['prompt'=> 'Select...'])
?>
</div>
<div class="col-sm-12" align="center">
<?= $form->field($model, 'fk_int_payroll_year')->dropDownList(
ArrayHelper::map(TblPayrollYear::find()->all(), 'pk_int_payroll_year_id','year'),
['options' => [isset($_POST['fk_int_payroll_year'])?'fk_int_payroll_year':'' => ['Selected'=>true]]],
['prompt'=> 'Seect...'])
?>
</div>
this is my controller
public function actionDisplay()
{
$model = new TblPayroll();
if(Yii::$app->request->post()!=null)
{
$data = Yii::$app->request->post();
// var_dump($data);
// die;
$month = $data['TblPayroll']['fk_int_payroll_month'];
$year = $data['TblPayroll']['fk_int_payroll_year'];
/* Be careful with this! */
$dataProviderSearch = new ActiveDataProvider
([
'query' => TblPayroll::find()->where(['fk_int_payroll_month'=>$month, 'fk_int_payroll_year'=> $year]),
'pagination' => ['pageSize' => 5],
]);
if($dataProviderSearch)
{
return $this->render('index', [
'dataProviderSearch' => $dataProviderSearch,
'model' => $model,
]);
}
}
else{
return $this->render('index', ['model' => $model]);
}
when i select dropdown it will gott actionDisplay, and find the dataprovider, and then it again render to index, so that time how can i show default selected value in dropDownlist?
If you are using an activeRecord then in controllerAction you should assign to the $model->your_fiedl the value you need for default
else{
$model->fk_int_payroll_month = 3
return $this->render('index', ['model' => $model]);
}
if you don't are using an active record you could use
->dropDownList($yourlist ,$selection)
eg
->dropDownList(ArrayHelper::map(TblPayrollMonth::find()->all() ,3)
I used Yii2 multiple selection dropdown , it is working fine at create but not showing me selected values on update!
Form:
$form->field($model, 'categories[]')
->dropDownList($model->CategoryDropdown,
[
'multiple'=>'multiple'
'class'=>'chosen-select input-md required',
]
)->label("Add Categories");
Model:
public function getCategoryDropdown()
{
$listCategory = Category::find()->select('ID,name')
->where(['is_subcategory' => 'Yes'])
->andWhere(['status' => 'active','approved' => 'active'])
->all();
$list = ArrayHelper::map( $listCategory,'ID','name');
return $list;
}
Controller:
public function actionCreate(){
...
$model->categories = implode(",",$_POST['Company']['categories']);
...
return $this->render('create', [
'model' => $model,
]);
}
public function actionUpdate($id)
{
$model = $this->findModel($id);
echo $model->categories; // 1,2,4,5 values already assigned
...
return $this->render('update', [
'model' => $model,
]);
}
Database:
1,2,4,5
How I can show multi selected values in dropdown when I update my recored?
all your code is ok just need echo your $form->...
echo $form->field($model, 'categories[]')
->dropDownList($model->CategoryDropdown,
[
'multiple'=>'multiple',
'class'=>'chosen-select input-md required',
]
)->label("Add Categories");
or use <?= ?> in view!
Here is solution:
Form
<?=
$form->field($model, 'categories')
->dropDownList($model->CategoryDropdown,
[
'class'=>'chosen-select input-md required',
'multiple'=>'multiple'
]
)->label("Add Categories");
?>
Controller:
public function actionCreate(){
...
$model->categories = implode(",",$_POST['Company']['categories']);
...
return $this->render('create', [
'model' => $model,
]);
}
public function actionUpdate($id)
{
$model = $this->findModel($id);
$model->categories = explode(',', $model->categories);
...
if($model->load(Yii::$app->request->post()))
{
$model->categories = implode(",",$_POST['Company']['categories']);
...
$model->save()
}
return $this->render('update', [
'model' => $model,
]);
}
I would highly recommend to use Select2 from krajee it has all the options that you might need, using multiple in dropDownList() will make you able to choose multiple values but by pressing and holding Ctrl and choosing which is not comfortable as choosing them using Select2.
They did an amazing job i highly recommend anyone with this problem to use it.
Please check the documentations.
https://demos.krajee.com/widget-details/select2