Change limit of queries in Yii2 [closed] - yii2

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I want to create searchModel with Yii2, my query have default limit is 7, and I have an input dropdownlist on the page to switch limit of query between 7 and 30.
How I can do this?
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($modelSearch, 'limit')->dropDownlist([
7 => '7 days',
30 => '30 days',
]); ?>
<?php ActiveForm::end(); ?>
and this is Model
class SearchModel extend \yii\base\Models
{
public $limit;
public function search($params) {
$query = Objects::find()->where(['attribute1'=>'a', 'attribute2'=>b]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort' => ['attributes' => ['attribute1', 'attribute2',]]
]);
$this->load($params);
return $dataProvider;
}
}
and this is controller
public function actionIndex()
{
$searchModel = new ModelSearch();
$dataProvider = $searchModel->search(Yii::$app->request->post());
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
I've tried to add
if(empty($params['limit'])) {
$query->limit(7);
}else {
$query->limit($params['limit']);
}
into the models - it worked but I think it's not a smart way to resolve it.

You may define SearchModel like:
<?php
namespace app\models\search;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\Human;
/**
* Class HumanSearch
*
* #package app\models\search
*/
class HumanSearch extends Model
{
/**
* #var int $limit
*/
public $limit;
/**
* #return array
*/
public function rules(): array
{
return [
[['limit'], 'integer', 'min' => 7, 'max' => 30], // Limit can be between 7 and 30.
[['limit'], 'default', 'value' => 7], // Default query limit is 7 rows.
];
}
/**
* #param array $params
*
* #return ActiveDataProvider
*/
public function search(array $params): ActiveDataProvider
{
// Initialize query.
$query = Human::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
// Load additional params to search model.
if (!$this->load($params) && $this->validate()) {
return $dataProvider;
}
// Set query limit.
$query->limit($this->limit);
return $dataProvider;
}
}
And then use it in actionIndex() in Controller:
<?php
namespace app\controllers;
use Yii;
use yii\rest\Controller;
use yii\data\ActiveDataProvider;
use app\models\search\HumanSearch;
class HumanController extends Controller
{
public function actionIndex(): ActiveDataProvider
{
$params = Yii::$app->getRequest()->getQueryParams();
$search = new HumanSearch;
return $search->search($params);
}
}

Related

Error Calling unknown method: omgdef\multilingual\MultilingualQuery::sort()?

Good afternoon, help me figure it out, using the OmgDef/yii2-multilingual-behavior extension, swears at this line:
public function actionIndex()
{
$data = new ActiveDataProvider([
'query' => FaqLang::find()->multilingual()->sort(), //error here
]);
return $this->render('index', [
'data' => $data
]);
}
My overridden model that stores the sort() method
<?
namespace admin\base;
/**
* Base active query class for models
* #package admin\base
*/
class ActiveQuery extends \yii\db\ActiveQuery
{
/**
* Order by order_num
* #return $this
*/
public function sort()
{
$this->orderBy(['order_num' => SORT_ASC]);
return $this;
}
}
You could try using the sort property of the ActiveDataProvider.
$data = new ActiveDataProvider([
'query' => FaqLang::find()
->multilingual()
->select(['id','question','answer']),
'sort' => [
'defaultOrder' => ['order_num' => SORT_ASC],
],
]);
To select columns use the select() method of the ActiveQuery object.
If you are using GridView to display results, you can also use it's columns property.

Yii2, how to use or operator in rest request

I am trying to use or operator in my rest request Yii2 but I cannot succeed.
Everytime I have this error :
[
{
"field": "filter",
"message": "Operator \"or\" requires multiple operands."
}
]
I tested several things but nothing works.
I want to filter
statut=0 or statut=1
Do you know or I can do it ?
I tried to
http://url/api/tickets/gestions?filter[or][statut][statut]=[0,1]
But it does not work
Here's the method within controller that manage this request :
public function actionIndex()
{
return ActionsHelper::actionIndex(
$this->modelClass,
$this->modelClass . 'Search'
);
}
$this->modelClass is defined above and is equal to 'api\modules\tickets\models\TicketGestion';
Here is ActionsHelper::actionIndex
public function actionIndex($model, $searchModel = null, $moreFilter = null,
$pagination = false)
{
$filterCondition = null;
if ($searchModel) {
$filter = new ActiveDataFilter([
'searchModel' => $searchModel
]);
if ($filter->load(\Yii::$app->request->get())) {
$filterCondition = $filter->build();
if ($filterCondition === false) {
return $filter;
}
}
}
$query = $model::find();
if ($filterCondition !== null) {
$query->andWhere($filterCondition);
}
if ($moreFilter !== null) {
$query->andWhere($moreFilter);
}
if ($pagination !== false) {
$pagination = [
'pageSize' => 100
];
}
return new ActiveDataProvider([
'query' => $query,
'pagination' => $pagination
]);
}
Here's the search model, generated by Gii
<?php
namespace api\modules\tickets\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use api\modules\tickets\models\TicketGestion;
/**
* TicketGestionSearch represents the model behind the search form of `api\modules\tickets\models\TicketGestion`.
*/
class TicketGestionSearch extends TicketGestion
{
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['id', 'priorite', 'quicree', 'quirea', 'statut', 'recurrentid', 'typerea', 'client'], 'integer'],
[['dispatch', 'service', 'type', 'sujet', 'datecrea', 'dateecheance', 'daterea'], 'safe'],
[['duree'], 'number'],
];
}
/**
* {#inheritdoc}
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = TicketGestion::find();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
if ($this->dispatch == 'null') {
$this->dispatch = 1;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'priorite' => $this->priorite,
'quicree' => $this->quicree,
'quirea' => $this->quirea,
'datecrea' => $this->datecrea,
'dateecheance' => $this->dateecheance,
'daterea' => $this->daterea,
'duree' => $this->duree,
'statut' => $this->statut,
'recurrentid' => $this->recurrentid,
'typerea' => $this->typerea,
'client' => $this->client,
]);
$query->andFilterWhere(['like', 'service', $this->service])
->andFilterWhere(['like', 'type', $this->type])
->andFilterWhere(['like', 'sujet', $this->sujet])
->andFilterWhere(['likes', 'dispatch', $this->dispatch]);
return $dataProvider;
}
}
You were on a right track, using ActiveDataFilter, but building arrays from get is done like this (example is from my controller):
http://localhost/ntb/web/index.php?r=assembly%2Findex&filter[or][0][status]=1004&filter[or][1][status]=1005&page=1&per-page=10
so for your example it should be like this:
http://url/api/tickets/gestions?filter[or][0][statut]=0&filter[or][1][statut]=1
This was the way to build a working 'or' filter for me.

How to show only fix records in the yii2 gridview

I am working with yii2 Framework. I want only few records in gridview where status = 1 in databaseenter image description here
This is the screen shot of gridview I want only highlighted records whose status is 1
This Code of view page is -:
<p>All Issued Devices are Highlighted </p>
<?php
use yii\helpers\Html;
use yii\grid\GridView;
/* #var $this yii\web\View */
/* #var $searchModel frontend\models\DeviceTrackerSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
//$this->title = 'Tracked Devices';
//$this->params['breadcrumbs'][] = $this->title;
?>
<b style="font-size: 30px;">ALL ISSUED DEVICES ARE HIGHLIGHTED </b>
<div class="device-tracker-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'rowOptions'=>function($model)
{
if($model->status == '1')
{
return ['class'=>'info'];
}
else
{
return ['class'=>'default'];
}
},
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
'attribute'=>'devices_device_id',
'value'=>'devicesDevice.device_name'
],
//'id',
//'devices_device_id',
'user_first_name',
'user_last_name',
'email_address:email',
// 'user_department',
'assign_date',
'return_date',
//'status',
//'Issued_by',
[
'attribute'=>'Issued_by' ,
'value'=>'issuedBy.first_name'
],
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
Please Tell me how to solve the problem?
Controller action is-
public function actionReturn()
{
// echo "welcome";die;
if(isset(Yii::$app->user->identity->user_type))
{
$status = Yii::$app->user->identity->user_type;
if($status == 1)
{
$this->layout = 'headerLayoutSuperadmin';
$searchModel = new DeviceTrackerSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index1', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
else
{
$this->layout = 'headerLayout';
$searchModel = new DeviceTrackerSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index1', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
}
else
{
return $this->redirect(array('site/login'));
}
}
sql search models-:
<?php
namespace frontend\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use frontend\models\DeviceTracker;
/**
* DeviceTrackerSearch represents the model behind the search form about `frontend\models\DeviceTracker`.
*/
class DeviceTrackerSearch extends DeviceTracker
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['id', 'status', 'Issued_by'], 'integer'],
[['user_first_name', 'devices_device_id', 'user_last_name', 'email_address', 'user_department', 'assign_date', 'return_date'], 'safe'],
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = DeviceTracker::find();
//$query = DeviceTracker::findAll('status=>1');
// print_r($query);die;
//echo $query;die;
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
$query->joinWith('devicesDevice');
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
//'devices_device_id' => $this->devices_device_id,
'assign_date' => $this->assign_date,
'return_date' => $this->return_date,
'status' => $this->status,
'Issued_by' => $this->Issued_by,
]);
$query->andFilterWhere(['like', 'user_first_name', $this->user_first_name])
->andFilterWhere(['like', 'user_last_name', $this->user_last_name])
->andFilterWhere(['like', 'email_address', $this->email_address])
->andFilterWhere(['like', 'user_department', $this->user_department])
->andFilterWhere(['like', 'devices.device_name', $this->devices_device_id]);
return $dataProvider;
}
}
in your search model, update the query to suit the output you want to pass to view.
something like this for the current condition i.e. you want to display only those rows whose status is 1
so,
$query->andFilterWhere([
'id' => $this->id,
//'devices_device_id' => $this->devices_device_id,
'assign_date' => $this->assign_date,
'return_date' => $this->return_date,
'status' => 1, // **this is where you are filtering the data with status == 1**
'Issued_by' => $this->Issued_by,
]);
and brief explanation of flow is
your controller which calls the dataProvider, gives you data that you pass to view and then eventually to gridView
the data is stored in mysql tables, so whatever data you want to send to view you need to query it in the searchModel in dataProvider's query
return dataProvide to controller > view > gridWidget

Trying to get property of non-object in action column in yii2

I've customized the query in FrameSearch Model and build my query with findbysql. I'm also trying to customize the action column. My gridview looks fine except the action Column.
Getting error -
FrameSearch Model Code -
<?php
namespace frontend\modules\framestock\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use frontend\modules\framestock\models\Frame;
use frontend\modules\framestock\models\Poitemframe;
use yii\db\Query;
use yii\db\Command;
/**
* FrameSearch represents the model behind the search form about `frontend\modules\framestock\models\Frame`.
*/
class FrameSearch extends Frame
{
public $purchase;
/**
* #inheritdoc
*/
public function rules()
{
return [
[['f_id'], 'integer'],
[['f_brand', 'f_name','purchase'], 'safe'],
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$subQuery1 = (new Query())->select(['poi_framename','sum(poi_qty) as purchased'])->from ('poitemframe')->join('LEFT JOIN','Frame','frame.f_name = poitemframe.poi_framename')->groupby('poi_framename');
$subQuery2 = (new Query())->select(['o_frame','count(o_frame) as sold'])->from ('orders')->join('LEFT JOIN','Frame','frame.f_name = orders.o_frame')->groupby('o_frame');
$query = (new Query())->select(['f_brand','f_name','COALESCE(pt.purchased,0)as purchased' , 'COALESCE(st.sold,0) as sold', '(COALESCE(pt.purchased,0) - COALESCE(st.sold,0)) as stock'])->from ('frame')->leftJoin(['pt' => $subQuery1],'pt.poi_framename = frame.f_name')->leftJoin(['st' => $subQuery2],'st.o_frame = frame.f_name');
// ->joinWith(['purchase']);
// $items = $query
// ->select([
// 'f_brand',
// 'f_name',
// 'sum(poitemframe.poi_qty) as purchased',
// ])
// //->where(['stock.product_id'=>3])
// ->groupBy('f_name')
// ->all();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'f_id' => $this->f_id,
]);
$query->andFilterWhere(['like', 'f_brand', $this->f_brand])
->andFilterWhere(['like', 'f_name', $this->f_name]);
return $dataProvider;
}
}
index.php
<?php
use yii\helpers\Html;
use yii\grid\GridView;
use yii\db\Query;
use yii\db\Command;
/* #var $this yii\web\View */
/* #var $searchModel frontend\modules\framestock\models\FrameSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Frames';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="frame-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'f_brand',
'f_name',
'purchased',
'sold',
'stock',
[
'class' => 'yii\grid\ActionColumn',
'template' => '{ledger}',
'buttons' => [
'ledger' => function ($url, $model) {
return Html::a(
'<span class="glyphicon glyphicon-eye-open"></span>',
['/frame/ledger', 'f_name' => $model->f_name],
[
'title' => 'Ledger',
'data-pjax' => '0',
]
);
},
],
],
],
]); ?>
</div>
update
After adding exit;
Please tell me how to resolve this. I want to get the f_name from the action column button which I'll pass to another page to filter a grid.
I usually recommend to use ArrayHelper::getValue .
For example:
ArrayHelper::getValue($model, 'f_name')
will work when $model is some object (Model or ActiveRecord), array or empty (=null).
Moreover, it has 3nd argument for default value:
ArrayHelper::getValue($model, 'f_name', 'value that returned when attribute not found in $model')

Filter gridview with select2 widget outside of the grid in yii2

I'm trying to filter gridviews by select2 widget. But the select2 widget should not be within the gridview. It would be like in the screenshot -
And when I select the select2 widget the data is filtered.
My index.php code is -
<?php
use yii\helpers\Html;
use yii\grid\GridView;
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use frontend\modules\productstockbook\models\Productnames;
use yii\helpers\Json;
/* #var $this yii\web\View */
/* #var $searchModel frontend\modules\productstockbook\models\ProductionSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Product Stock Book';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="production-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<?php
echo Select2::widget([
'model' => $model,
'attribute' => 'productnames_productname',
'data' => ArrayHelper::map(Productnames::find()->all(),'productnames_productname','productnames_productname'),
'options' => ['placeholder' => 'Select Product', 'id' => 'catid'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<div class="row-fluid">
<div class="form-group">
<div class="col-xs-3 col-sm-3 col-lg-3" >
<input type="text" class="form-control" id="production" readonly placeholder ="Production">
</div>
<div class="col-xs-3 col-sm-3 col-lg-3" >
<input type="text" class="form-control" id="sell" readonly placeholder ="Sell">
</div>
<div class="col-xs-3 col-sm-3 col-lg-3" >
<input type="text" class="form-control" id="stock" readonly placeholder ="Stock">
</div>
<div class="col-xs-3 col-sm-3 col-lg-3" >
<button type="button" id="search" class="btn btn-primary"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></button>
</div>
</div>
</div>
<div class= 'col-md-6'>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'productionid',
'productiondate',
//'itemid',
'productname',
//'batchno',
'prodqty',
//['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
<div class='col-md-6'>
<?php
echo GridView::widget([
'dataProvider' => $dataProvider2,
'filterModel' => $searchModel2,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'billdate',
'productsales_partyname',
'productname',
'total',
],
]);
?>
</div>
</div>
<?php
/* start getting the textboxes */
$script = <<< JS
$(function(){
//$(document).ready(function(e) { getTotalproduction(); });
$('#catid').change(function(){
getIndexpage();
//getTotalproduction();
//getTotalsell();
//getTotalstock();
});
var catid = $(this).val();
var getIndexpage = function(){
var catid = String($('#catid').val());
window.onbeforeunload = function(e) {return getTotalproduction();};
window.location.href = 'index.php?r=productstockbook/production/index&catid='+catid;
} ;
var getTotalproduction = function(){
var catid = String($('#catid').val());
$.get('index.php?r=productstockbook/production/get-for-production',{ catid : catid }, function(data){
//alert(data);
var data = $.parseJSON(data);
$('#production').attr('value',data.totalproduction);
});
} ;
var getTotalsell = function(){
var catid = String($('#catid').val());
$.get('index.php?r=productstockbook/production/get-for-sales',{ catid : catid }, function(data){
//alert(data);
var data = $.parseJSON(data);
$('#sell').attr('value',data.totalsell);
});
};
var getTotalstock = function(){
var totalproduction = parseInt($('#production').val());
var totalsell = parseInt($('#sell').val());
var totalstock = Math.round(totalproduction - totalsell)
//alert(totalstock);
if (isNaN(totalstock) || totalstock < -10000000 || totalstock > 1000000) {
totalstock = '';
}
$('#stock').val(totalstock);
};
// var getTotalstock = function(){
// var catid = String($('#catid').val());
// $.get('index.php?r=productstockbook/production/get-for-stock',{ catid : catid }, function(data){
// alert(data);
// var data = $.parseJSON(data);
// $('#stock').attr('value',data.stock);
// });
// };
});
JS;
$this->registerJs($script);
/* end getting the textboxes */
?>
My Controller code is -
<?php
namespace frontend\modules\productstockbook\controllers;
use Yii;
use frontend\modules\productstockbook\models\Production;
use frontend\modules\productstockbook\models\ProductionSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use frontend\modules\productstockbook\models\ProductsalesSearch;
use yii\helpers\Html;
use frontend\modules\productstockbook\models\Productnames;
use frontend\modules\productstockbook\models\Productsales;
use yii\helpers\Json;
use yii\db\Query;
use yii\db\Command;
/**
* ProductionController implements the CRUD actions for Production model.
*/
class ProductionController extends Controller
{
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all Production models.
* #return mixed
*/
public function actionIndex()
{
$catid = yii::$app->request->get('catid');
$searchModel = new ProductionSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams, $catid);
$searchModel2 = new ProductsalesSearch();
$dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams, $catid);
$model = new Productnames();
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'searchModel2' => $searchModel2,
'dataProvider2' => $dataProvider2,
'model' => $model,
]);
}
/**
* Displays a single Production model.
* #param integer $id
* #return mixed
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Production model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new Production();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->productionid]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
/**
* Updates an existing Production model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $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->productionid]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
/**
* Deletes an existing Production model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the Production model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Production the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Production::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
public function actionGetForProduction($catid)
{
$production = Production::find()->select('sum(prodqty) as totalproduction')->where(['productname'=>$catid])->asArray()->one();
echo Json::encode($production);
}
public function actionGetForSales($catid)
{
$sell = Productsales::find()->select('sum(total) as totalsell')->where(['productname'=>$catid])->asArray()->one();
echo Json::encode($sell);
}
// public function actionGetForStock($catid)
// {
// //$stock = Productsales::find()->joinWith('Production')->select('sum(production.prodqty) - sum(productsales.total) as stock')->where(['productname'=>$catid])->asArray()->one();
// //echo Json::encode($stock);
// //$subQuery1 = (new Query())->select(['productname,sum(prodqty) as totalproduction'])->from('production')->where(['productname'=>$catid]);
// $subQuery2 = (new Query())->select(['productname,sum(total) as totalsell'])->from('productsales')->where(['productname'=>$catid]);
// $subQuery3 = (new Query())->select(['productname,(sum(prodqty) - sell.totalsell) as totalstock'])->from('production')->leftJoin(['sell' => $subQuery2],'sell.productname = productname')->where(['productname'=>$catid]);
// echo Json::encode($subQuery3);
// }
}
ProductionSearch Model code -
<?php
namespace frontend\modules\productstockbook\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use frontend\modules\productstockbook\models\Production;
/**
* ProductionSearch represents the model behind the search form about `frontend\modules\productstockbook\models\Production`.
*/
class ProductionSearch extends Production
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['productionid', 'itemid', 'prodqty'], 'integer'],
[['productiondate', 'productname', 'batchno'], 'safe'],
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params,$catid)
{
$query = Production::find()
//->select(['productionid', 'productiondate', 'itemid', 'productname', 'batchno', 'prodqty'])
->orDerBy([
'productiondate'=>SORT_DESC,
])
->andWhere(['productname' => $catid]);
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'productionid' => $this->productionid,
'productiondate' => $this->productiondate,
'itemid' => $this->itemid,
'prodqty' => $this->prodqty,
]);
$query->andFilterWhere(['like', 'productname', $this->productname])
->andFilterWhere(['like', 'batchno', $this->batchno]);
return $dataProvider;
}
}
ProductsalesSearch Model Code -
<?php
namespace frontend\modules\productstockbook\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use frontend\modules\productstockbook\models\Productsales;
/**
* ProductsalesSearch represents the model behind the search form about `frontend\modules\productstockbook\models\Productsales`.
*/
class ProductsalesSearch extends Productsales
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['id', 'productsales_ebillid', 'discount'], 'integer'],
[['year', 'console', 'billno', 'billdate', 'productsales_partyname', 'itemid', 'productname', 'batchno', 'expdate', 'productiondate', 'prodqty', 'qty', 'free', 'total'], 'safe'],
[['mrp', 'rate'], 'number'],
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params,$catid)
{
$query = Productsales::find()
->orDerBy([
'billdate'=>SORT_DESC,
])
->andWhere(['productname' => $catid]);
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'productsales_ebillid' => $this->productsales_ebillid,
'billdate' => $this->billdate,
'expdate' => $this->expdate,
'mrp' => $this->mrp,
'rate' => $this->rate,
'productiondate' => $this->productiondate,
'discount' => $this->discount,
]);
$query->andFilterWhere(['like', 'year', $this->year])
->andFilterWhere(['like', 'console', $this->console])
->andFilterWhere(['like', 'billno', $this->billno])
->andFilterWhere(['like', 'productsales_partyname', $this->productsales_partyname])
->andFilterWhere(['like', 'itemid', $this->itemid])
->andFilterWhere(['like', 'productname', $this->productname])
->andFilterWhere(['like', 'batchno', $this->batchno])
->andFilterWhere(['like', 'prodqty', $this->prodqty])
->andFilterWhere(['like', 'qty', $this->qty])
->andFilterWhere(['like', 'free', $this->free])
->andFilterWhere(['like', 'total', $this->total]);
return $dataProvider;
}
// public function gettotalProduction()
// {
// return $this->c_name.' - '.$this->c_address.' - '.$this->c_mobileno;
// }
}
My point is that in the javascript in index.php file the following code is being used -
window.location.href = 'index.php?r=productstockbook/production/index&catid='+catid;
I don't want the page to be relocated. Because if it relocates I cannot get sum(prodqty) and sum(total) in the textboxes as you can see in the page beaceuse the page is being relocated. How can I achieve this without relocating the page? This is same question as Filter data with kartik Select2 widget in gridview
Update
Currently after working on Edvin's solution - I'm facing the following error -
Since I see it already filters data (but with page reload), I moved to part 2 where you asked for sum of specific column.
I couldn't think of better solution at the moment but this should work for now. Note that it might be only temporary solution because this code is "fragile" (adding an additional column, changing tables' ID, etc.) will break this and you will forced to modify this code. Also please note it takes the sum of all printed rows (meaning only the visible (1st by default) is counted).
I have used something similar before and since IDs are somewhat static, it rarely breaks for me.
$(document).on('ready', function(e) {
var row0 = $('#w0')[0]['childNodes'][2]['childNodes'][2]['children'];
var row1 = $('#w1')[0]['childNodes'][2]['childNodes'][2]['children'];
var total0 = 0;
var total1 = 0;
for (var i = 0; i < row0.length; i++) {
total0 += parseInt(row0[i]['children'][3]['textContent'], 10);
}
for (var i = 0; i < row1.length; i++) {
total1 += parseInt(row1[i]['children'][4]['textContent'], 10);
}
// ^ This number takes (n+1)th column
console.log('First table total value: ' + total0);
console.log('Second table total value: ' + total1);
console.log('Difference between 1st and 2nd total values: ' + (total0 - total1));
})
This will work, assuming your tables' IDs are "w0" (first table) and "w1" (second table) and there are exactly that amount of columns in your represented picture.
In case there are a lot of records, you can increase the size of how many rows to print in table by adding additional lines in Model:
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 30,
]
]);