Action redirect() not reset the Model filters - yii2

How to make my ACTION actionPosvenda redirect() not reset the filters that the user made in Gridview previously?
public function actionIndex()
{
$searchModel = new DailyproductivitySearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
public function actionPosvenda($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['index']);
} else {
return $this->renderAjax('posvenda', [
'model' => $model,
]);
}
}

Related

Yii2 insert data from CheckBoxList

In my Form:
<?= GridView::widget([
'id' => 'griditems',
'dataProvider' => $dataProvider,
'columns' => [
'receiver_name',
'receiver_phone',
'item_price',
'shipment_price',
['class' => 'yii\grid\CheckboxColumn'],
],
]); ?>
In my Controller:
public function actionCreate()
{
$model = new Package();
$searchModel = new ShipmentSearch();
$searchModel->shipment_position=1; // الشحنه في مقر الشركة
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
if ($model->loadAll(Yii::$app->request->post())){
$select = Yii::$app->request->post('selection');
foreach($select as $id){
$shipment= shipment::findOne((int)$id);
$model->company_id=1;
$model->shipment_id=$shipment->id;
$model->send_from=$shipment->send_from;
$model->send_to=$shipment->send_to;
$model->save(false);
}
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
'dataProvider'=>$dataProvider,
]);
}
}
I just try this way to insert data as above its works but the data inserted just last one or last CheckBox from the list. I tried to print the id that in foreach and there is more than one id.
That is beacuse you're reusing the same instace for each save() inside of foreach, so you're overwriting the same model over and over. You need to place $model = new Package() inside of foreach:
foreach($select as $id){
$shipment= shipment::findOne((int)$id);
$model = new Package();
$model->company_id=1;
$model->shipment_id=$shipment->id;
$model->send_from=$shipment->send_from;
$model->send_to=$shipment->send_to;
$model->save(false);
}

Many To Many relations Yii2

I need help with this code, I'm new to Yii2.
I'm building a sample project to start, and I don't know why my code gets the right result but doesn't save the ids I need into the many-to-many table for the relationship.
I started from this sample in the wiki: https://www.yiiframework.com/wiki/708/book-has-author-many-to-many-relations-using-kartikselect2
My Model
public function rules()
{
return [
[['anno', 'durata', 'flagdelete', 'categoriaid'], 'integer'],
[['titolo', 'riassunto', 'regista', 'descrizione'], 'string', 'max' => 50],
[['attoriIds'], 'safe'],
];
}
public function attributeLabels()
{
return [
'titolo' => 'Titolo',
'anno' => 'Anno',
'durata' => 'Durata',
'riassunto' => 'Riassunto',
'regista' => 'Regista',
'descrizione' => 'Descrizione',
'categoriaid' => 'Categoria',
'nome' => 'Attori',
];
}
/**
* #var array
*/
public $attoriIds = [];
public function getdropAttori()
{
$data = Attori::find()->asArray()->all();
return ArrayHelper::map($data, 'id', 'nome');
}
/**
* #return mixed
*/
public function getAttoriIds()
{
return $this->attoriIds;
}
/**
* #param $attoriIds
*/
public function setAttoriIds($attoriIds)
{
$this->attoriIds = \yii\helpers\ArrayHelper::getColumn(
$this->getAttdvd()->asArray()->all(),
'attori_id'
);
}
/**
* #param $insert
* #param $changedAttributes
*/
public function afterSave($insert, $changedAttributes)
{
$actualAttoris = [];
$attoriExists = 0;
if (($actualAttoris = Attdvd::find()->andWhere(
"dvd_id = $this->id"
)->asArray()->all()) !== null
) {
$actualAttoris = ArrayHelper::getColumn($actualAttoris, 'attori_id');
$attoriExists = 1;
}
if (!empty($this->despIds)) {
foreach ($this->despIds as $id) {
$actualAttoris = array_diff($actualAttoris, [$id]);
$r = new Attdvd();
$r->dvd_id = $this->id;
$r->attori_id = $id;
$r->save();
}
}
if ($attoriExists == 1) {
foreach ($actualAttoris as $remove) {
$r = Attdvd::findOne(
['attori_id' => $remove, 'dvd_id' => $this->id]
);
$r->delete();
}
}
parent::afterSave($insert, $changedAttributes);
}
/**
* #return mixed
*/
public function getAttdvd()
{
return $this->hasMany(Attori::className(), ['id' => 'attori_id'])->viaTable(
'attdvd', ['dvd_id' => 'id']
);
}
My Controller
public function actionCreate()
{
$model = new Dvd();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('create', [
'model' => $model,
]);
}
public function actionUpdate($id)
{
$model = $this->findModel($id);
//i think the problem is the line below
$model->attoriIds = $model->AttoriIds;
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('update', [
'model' => $model,
]);
}
My form (that work properly):
<?= $form->field($model, 'AttoriIds')->widget(Select2::classname(), ['data'=>$model->dropAttori, 'options' => ['multiple' => true, 'placeholder' => 'Seleziona attori']])->label('Attori') ?>
It's bad way because the making of that code in multiple models will make models dirtier. The better way is usage of a universal component that can manage relations in your models. For example yii2-many-to-many-behavior

Use closures in Yii2 ArrayDataProvider

In an ActiveDataProvider you can use closures as values, like:
$dataprovider = new ArrayDataProvider([
'allModels' => $array
]);
$gridColumns = [
'attrib_1',
[
'attribute' => 'attrib_2',
'label' => 'Label_2',
'value' => function($model) {
return Html::encode($model->value_2);
}
],
'attrib_3'
];
echo GridView::widget([
'dataProvider'=> $dataprovider,
'columns' => $gridColumns
]);
Is it possible to do the same or something like this, in an ArrayDataProvider?
Yes. Only difference is that $model is not an object but array so:
'value' => function($model) {
return Html::encode($model['value_2']);
}
For this purpose, I have created an extended version of ActiveDataProvider, that for each model got from provider I call a callback.
This is the custom ActiveDataProvider, put in common\components namespace in this case.
<?php
namespace common\components;
class CustomActiveDataProvider extends \yii\data\ActiveDataProvider
{
public $formatModelOutput = null;
public function getModels()
{
$inputModels = parent::getModels();
$outputModels = [];
if($this->formatModelOutput != null)
{
for($k=0;$k<count($inputModels);$k++)
{
$outputModels[] = call_user_func( $this->formatModelOutput, $k , $inputModels[$k]);
}
}
else
{
$outputModels = $inputModels;
}
return $outputModels;
}
}
This is the action in controller that uses it. For reusability, I call a model method instead calling a clousure, but you can call also a clousure.
public function actionIndex()
{
$query = Model::find();
$dataProvider = new \common\components\CustomActiveDataProvider([
'query' => $query,
'pagination' => ['pageSize' => null],
'formatModelOutput' => function($id, $model) {
return $model->dataModelPerActiveProvider;
}
]);
return $dataProvider;
}
At last, this is the method getDataModelPerActiveProvider in model:
public function getDataModelPerActiveProvider()
{
$this->id = 1;
// here you can customize other fields
// OR you can also return a custom array, for example:
// return ['field1' => 'test', 'field2' => 'foo', 'field3' => $this->id];
return $this;
}

calculate average in yii2

I am making a cost accounting application.
I want to find the average price over 3 months.
The summary produced in Kartik GridView shows initial share price not the total.
this is my controller
<?php
namespace backend\controllers;
use Yii;
use backend\models\Triwulan;
use backend\models\TriwulanSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* TriwulanController implements the CRUD actions for Triwulan model.
*/
class TriwulanController extends Controller
{
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all Triwulan models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new TriwulanSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Triwulan model.
* #param string $id
* #return mixed
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Triwulan model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new Triwulan();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->rm_code]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
/**
* Updates an existing Triwulan model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param string $id
* #return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->rm_code]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
/**
* Deletes an existing Triwulan model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param string $id
* #return mixed
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the Triwulan model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param string $id
* #return Triwulan the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Triwulan::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
this is my view
<?php
use yii\helpers\Html;
use yii\widgets\DetailView;
use kartik\grid\GridView;
/* #var $this yii\web\View */
/* #var $model backend\models\Triwulan */
$this->title = $model->rm_code;
$this->params['breadcrumbs'][] = ['label' => 'Triwulans', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="triwulan-view">
<h1><?= Html::encode($this->title) ?></h1>
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'rm_code',
'deskripsi_barang',
],
]) ?>
</div>
<?= GridView::widget([
'dataProvider'=>new yii\data\ActiveDataProvider([
'pagination'=>false,
'query'=>$model->getPenerimaans(),
]),
'columns'=>[
['class' => 'kartik\grid\SerialColumn'],
'rm_code',
'bulan',
// 'price',
[
'label' => 'Price',
//'attribute' => 'idDhs.idMatakuliah.jam',
'pageSummary' => true,
// 'pageSummary' => 'Total',
'value' => function ($model) {
if ($model)
return $model->price / 3;
}
],
// ['class' => 'kartik\grid\ActionColumn'],
// 'product',
// 'qty'
],
'showPageSummary' => true,
]) ?>
</div>
Correcting some syntax errors from scaisEdge's answer
public function actionIndex()
{
$searchModel = new TriwulanSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
// calc the average
$myAverage = 0;
$myTot =0;
$myCnt = 0;
foreach ($dataProvider->models as $key => $value) {
$myTot += $value['price'];
$cnt++; // This should be $myCnt
}
if ($cnt>0){ // inside if use $myCnt
$myAverage = myTot/$myCont // here use $myTot/$myCnt
}
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
// render the avegare too
'myAverage' => $myAverage,
]);
}

How to save multiple models in one form in Yii2

I'm doing a form where I enter the data in two models in a single form. My question is how to record data entry in actionCreate () and call these models in a single form.
These are my inscritoController.php
public function actionCreate()
{
$model = new Inscrito();
$modelEmpresa = new Empresa();
if ($model->load(Yii::$app->request->post()) && $model->load(Yii::$app->request->post()) && $modelEmpresa->save() && $modelEmpresa->save())
{
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
'modelEmpresa' => $modelEmpresa,
]);
}
}
And Error:
PHP Notice – yii\base\ErrorException
Undefined variable: modelEmpresa
add this line in your controller
use app\models\Empresa;
Load Yii::$app->request->post() to $modelEmpresa and confirm model call in your controller use app\models\Empresa;
public function actionCreate()
{
$model = new Inscrito();
$modelEmpresa = new Empresa();
if ($model->load(Yii::$app->request->post()) && $modelEmpresa->load(Yii::$app->request->post()) && $model->save() && $modelEmpresa->save())
{
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
'modelEmpresa' => $modelEmpresa,
]);
}
}