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']);
}
}
Related
I want to multiply two columns in the yii2 grid the grid view is as follows
<?= GridView::widget([
//'dataProvider' => $dataProvider,
'dataProvider'=>new ActiveDataProvider([
'query' => Adanalytics::find()->
where(['publisher_id' => Yii::$app->user->identity->id ])->
select('id,ad_id,MAX(impression) AS impression, MAX(view) AS view, MAX(clicks) AS clicks,MAX(cpc) AS cpclick,MAX(cpv) AS cpview, (MAX(clicks)*MAX(cpc)) AS totalccost')->
groupBy('ad_id, visitor_ip'),
]),
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'id',
'ad_id',
//'advertiser_id',
//'publisher_id',
//'visitor_ip',
//'type_ad',
'impression',
'view',
'clicks',
//'placed_date',
//'cpc',
//'cpv',
'cpclick',
'cpview',
'totalccost',
//'cpi',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
But it is not giving me the desired output where am I going wrong how can i do this?
If you need the column only as display value in the gridview you can create a calculated column.
'cpview',
[
'label' => 'Totalcost',
'value' => function($model){
return $model->cpclick * $model->clicks;
}
],
Or else you can add at the start of your Adanalytics class
public $totalccost;
if you want to use the calculation anywhere you can do following.
in your model
public function getTotalcost()
{
return $this->clicks * $this->cpclick;
}
and you can label to this attribute
public function attributeLabels()
{
return [
...
'totalcost' => Yii::t('app', 'Total cost'),
];
}
in grid view column
...
'cpview',
'totalcost'
You can use this function anywhere as $model->totalcost
I have solved the problem by using yii2 db query which is like this way.
$subquery = Adanalytics::find()->
select('id,ad_id,date_event,max(cpc) cpclick,max(cpv) cpview,max(impression) impression,max(view) view,max(clicks) clicks,visitor_ip,publisher_id')->
from('ad_analytics')->
where(['publisher_id' => Yii::$app->user->identity->id ])->
groupBy('ad_id,date_event,visitor_ip');
$query=Adanalytics::find()->
select('ad_id,date_event,sum(cpclick) total_click_cost,sum(cpview) total_view_cost,sum(impression) total_impression,sum(view) total_views,sum(clicks) total_clicks,publisher_id')->
from(['t'=>$subquery])->
groupBy('t.ad_id,t.date_event');
And called the column in grid view.
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'ad_id',
'total_impression',
'total_views',
'total_clicks',
'total_click_cost',
'total_view_cost',
'date_event',
['class' => 'yii\grid\ActionColumn'],
],
Defined them in model before calling.
public $total_click_cost;
public $total_view_cost;
public $total_impression;
public $total_views;
public $total_clicks;
I got two related tables(models) [Sub with primary key id] and [Case with foreign key sub_id]. I created Sub with id=4. I want to create data of Case model in view.php(form) of Sub model. I did a "Create Case" Button which refer to the actionCreate of Case model.
This is my "Create Case" button in sub/view.php:
<?= Html::a(Yii::t('app','Create Case'), ['/case/create', 'sub_id' => $model->id], ['class' => 'btn btn-primary']) ?>
It looks like in the
picture
This button referred me to the create form of Case model, where i should get the field sub_id = 4. Now my _form.php has
<?= $form->field($model, 'sub_id')->textInput() ?>
What should i change to get the automatically filled field sub_id with id of parent model?
UPDATE: I added relevant code from the appropriate view, controller files.
I didn't changed model files.
CaseController.php file looks like shown below
class CaseController extends Controller
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
public function actionIndex()
{
$searchModel = new CaseSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
public function actionCreate($sub_id)
{
$model = new Case();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
'parent' => $sub_id
]);
}
}
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
protected function findModel($id)
{
if (($model = Case::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
sub/view.php file:
<?php
use yii\helpers\Html;
use yii\widgets\DetailView;
$this->title = $model->id . ": " . $model->fullname;
$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Subs'), 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="sub-view">
<h3><?= Html::encode($this->title) ?></h3>
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'id',
'address_id',
'address.region.name',
[
'label' => 'address',
'value' => 'Street: ' . $model->address->street . ' House ' . $model->address->house . ' Flat ' . $model->address->flat
],
],
]) ?>
<p>
<?= Html::a(Yii::t('app', 'Create Case'), ['/case/create', 'sub_id'=>$model->id], ['class' => 'btn btn-success']) ?>
</p>
</div>
case/_form.php file:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
<div class="case-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'id')->textInput() ?>
<?php if($model->isNewRecord && isset($parent_id)) {
$model->sub_id = $parent_id;
} ?>
<?= $form->field($model, 'sub_id')->textInput(['readonly' => true, 'value' => $model->sub_id]) ?>
<?= $form->field($model, 'case_date')->textInput() ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
With lack of any further information, to the best of my understanding this is what you are asking -
Taking the example in your picture, if user clicks on Create Case button, then a new form (Create Case) will open. In that Create Case form, among other input fields, there is a field for sub_id and it should be populated by default with the value 4 (since in the picture the ID of the User Harry Potter is 4).
Based on the above you simply need to do the following -
In your action (within the CaseController) for create case, you pass the sub_id like below -
/* ** CaseController ** */
public function actionCreate($sub_id)
{
//....other code
return $this->render('create', ['model' => $model,'parent_id' => $sub_id]);
}
And then inside the _form.php where you are showing the Create Case form you simply do like this -
/* ** _form.php ** */
//... other code
//if you are using _form.php for Edit Form as well,
//this prevents the value from the DB being over-written
if($model->isNewRecord && isset($parent_id)) {
$model->sub_id = $parent_id;
}
<?= $form->field($model, 'sub_id')->textInput() ?>
//... other code
This should be enough to display the value passed from the parent form.
I have a problem on getting all the selected values/data Yii2 Gridview using checkboxColumn.
I can only get one of the value in the grid using this code:
'class' => 'yii\grid\CheckboxColumn',
'checkboxOptions' => function($model, $key, $index, $widget) {
return ['value' => $model['item_id'] ];
},
Need some suggestions on how can I get all the values in the grid...
Here is my Code Code snippet Controller/View:
Controller:
public function actionBulk(){
$action=Yii::$app->request->post('action');
$selection=(array)Yii::$app->request->post('selection');
print_r($selection);
}
View:
<?=Html::beginForm(['transjournal/bulk'],'post');?>
<?=GridView::widget([
'dataProvider' => $dataProvider,
'bordered'=>true,
'striped'=>true,
'condensed'=>true,
'hover'=>true,
'export' => false,
'showOnEmpty' => false,
'panel'=>[
'after'=>Html::submitButton('<i class="glyphicon glyphicon-plus"></i> Posted', ['class' => 'btn btn-success']),
],
'columns' => [
[
'class' => 'yii\grid\CheckboxColumn',
'checkboxOptions' => function($model, $key, $index, $widget) {
return ['value' => $model['item_id'] ];
},
],
'item_id',
'description',
],
]);
?>
<?= Html::endForm();?>
Here is my attachment:
This is the GridView
This is the Result in the GridView (Selected Data only returns item_id)
How can I return both item_id and description?
Issue with your code 'checkboxOptions' =>, can you remove it?
<?=Html::beginForm(['controller/bulk'],'post');?>
<?=Html::dropDownList('action','',[''=>'Mark selected as: ','c'=>'Confirmed','nc'=>'No Confirmed'],['class'=>'dropdown',])?>
<?=Html::submitButton('Send', ['class' => 'btn btn-info',]);?>
<?=GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\CheckboxColumn'],
...
],
]); ?>
<?= Html::endForm();?>
In Controller:
public function actionBulk(){
$action=Yii::$app->request->post('action');
$selection=(array)Yii::$app->request->post('selection');//typecasting
foreach($selection as $id){
$model = Post::findOne((int)$id);//make a typecasting
//do your stuff
$model->save();
// or delete
}
}
basically, i am using yii's CheckboxColumn:
<?php
namespace common\grid;
class CheckboxColumn extends \yii\grid\CheckboxColumn {
public $headerOptions = ['class' => 'text-center', 'style' => 'width: 5em'];
public $contentOptions = ['class' => 'text-center'];
}
?>
then i wrote a jquery plugin for triggering operations with selected items, plus custom Actions and so on, here the relevant javascript code, where options.grid is the id/selector for your grid, e.g. '#grid':
var selection = [];
$(options.grid + ' input:checkbox[name="selection[]"]:checked').each(function() {
selection.push($(this).val());
});
so var selection contains an array with my item ids. length is:
selection.length
Can anyone give me sample of how to retrieve data from model without having to use Widget ? Because need to get data per table column and put them inside my own view (not using widget)
Controller :
public function actionIndex() {
$searchModel = new B2CProductsSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
View :
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'sku',
'name',
'short_description',
'long_description',
'thumb_img:ntext',
'large_img:ntext',
'url_content:ntext',
'contact_info',
'status',
'currency',
'price',
'dimension',
'weight',
// 'created',
// 'modified',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
The widget above iterate through the element inside the predefined gridview,
but what I want to do instead is something like :
foreach($data as $ab) {
echo $ab->id;
}
You can do it this way:
/* assuming $data is an ActiveDataProvider object */
$models = $data->getModels();
foreach($models as $model) { ... }
see more here
If you are using an ActiveDataProvider:
Controller:
public function actionMyAction()
{
$dataProvider = new ActiveDataProvider([
'query' => MyModel::find(),
]);
return $this->render('my-results-page', [
'dataProvider' => $dataProvider,
]);
}
View:
<?php
foreach ($dataProvider->models as $model){
echo $model->myProperty;
}
?>
If you are using a query, such as this:
$query = (new \yii\db\Query())
->select('this, that')
->from('over_there');
$command = $query->createCommand();
$rows = $command->queryAll();
Then you can iterate over the result like this(assuming you passed it to the view in a variable called $dataProvider):
foreach($dataProvider as $data)
{
$data['myProperty'];
}
I have a GridView which displays an employee's summary of his/her payslip. Here's a screenshot for more understanding:
Those highlighted columns come from a different model which is the User model while the rest come from the Payslip model.
How do I merge 2 models in one GridView? Because in GridView, it is more likely for you to have a single model to display data. But how about 2 models?
Here's a code in my Payslip model, note that getUser() is generated with gii since user_id is a foreign key in my payslip table:
public function getUser()
{
return $this->hasOne(User::className(), ['user_id' => 'user_id']);
}
public function getFirstName()
{
return $this->user ? $this->user->fname : 'First Name';
}
public function getLastName()
{
return $this->user ? $this->user->lname : 'Last Name';
}
The Payslip controller:
public function actionIndex()
{
$searchModel = new PayslipSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
And then the Payslip view:
<?php
echo GridView::widget([
'dataProvider' => $dataProvider,
//'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'payslip_id',
//'store_id',
'firstName',
'lastName',
'total_earnings',
'total_deduction',
'net_pay',
['class' => 'yii\grid\ActionColumn'],
],
]);
?>
BTW, in this example, I just created payslip #1 manually to give you a demo.
Additional info:
The logged in user is a BizAdmin user, and all of BizAdmin's staff users should be displayed in the payslip table (that table above) even if these staff users still don't have any payslip created for them. So by default, that table will be occupied already with staff users under the logged in BizAdmin user, and those staff users who still have no payslips created will be indicated "Create Payslip"
Here's an example in KashFlow:
Update view to:
<?php
echo GridView::widget([
'dataProvider' => $dataProvider,
//'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'payslip_id',
//'store_id',
['value' => function ($data) {return $data->getFirstName();}, 'label' => 'First Name'],
['value' => function ($data) {return $data->getLastName();}, 'label' => 'LastName'],
'total_earnings',
'total_deduction',
'net_pay',
['class' => 'yii\grid\ActionColumn'],
],
]);
?>
And in $searchModel->search add you relation, like that:
$query = Payslip::find()->with(['user']);
Read for data column - http://www.yiiframework.com/doc-2.0/guide-output-data-widgets.html#data-column