Basic edit operation in yii - php

I have used CgridView which list all the data from my table 'Jobs',also have an edit and delete for each row.Which has been implemeted using prebuilt template in yii.I tried few things,but it not working.My first aim is to display that particular row data in edit form.
My codes are as follows:
The model corresponding is,UpdateJob.php.
/*Model*/
public function edit() {
$criteria = new CDbCriteria;
$criteria->compare('id', 'Admin', true);
return new CActiveDataProvider('viewjob', array(
// 'criteria' => $criteria,
'sort'=>array(
'defaultOrder'=>'key_skills ASC',
),
));
}
/*Contoller*/
public function actionUpdateJob()
{
if(isset($_GET['id'])) //Is it the right way //
{
$id=$_GET['id'];
}
$model = new UpdateJob('edit');
$params = array('model' => $model,'id' => $id
);
$this->render('update', $params);
}
/*VIEW*/ Have just tried to show the data as follows.
<div class="row">
<?php echo $form->labelEx($model,'Company Name'); ?>
<?php echo $form->textField($model,'posted_by'); ?>
<?php echo $form->error($model,'posted_by'); ?>
</div>
Thats it..
How to just display the row of a particular id. For the time being I don't want to update it. Please Help

this will be done through js
$(gridID).yiiGridView('getSelection') should be your start
read http://www.yiiframework.com/doc/api/1.1/CGridView

Related

How to save values of multiple radios in yii2 activeForm?

I have a survey app with many questions. Each question has options that are presented in form of radiolist.
I am using the ActiveForm and RadioList in for loop in order to get all the questions and options from the Database.
Everything is ok with printing the questions and options but
When I try to save the answers to the database, it saves only the last option.
In my save action I tried to put a foreach loop in order to save each answer, but it didn't work for me.
I tried to var_dump the $model->save and $request->post('Questions') there is all the selected options, not only the last one.
Model:
here is only the rules:
public function rules(){
return[
[['id','question_id', 'option_id'], 'required']
];
}
View:
<?php $form = ActiveForm::begin([
'id' => 'my-form-id',
'action' => ['answers/save'],
]
);
?>
<?php $questions = Questions::find()->orderBy('id ASC')->all(); ?>
<?php for ($i=0; $i<count($questions); $i++): ?>
<?= Html::encode("{$questions[$i]->title}") ?>
<?php $options = Options::find()->where (['question_id'=>$questions[$i]->id])->orderBy('id ASC')->all();
$options = ArrayHelper::map($options,'id', 'title');
?>
<label class="container" >
<?= $form->field($model, 'option_title')->radioList(
$options,
['name'=>'Questions['.$questions[$i]->id.']',
'separator' => '<br>',
])->label(false) ?>
</label>
<?php endfor; ?>
<?= Html::submitButton('Save', ['class' => 'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>
Controller:
public function actionSave(){
$model = new Answers();
$request = \Yii::$app->request;
foreach($request->post('Questions') as $key=>$value) {
$model->load($request->post());
$model->option_id = $value;
$model->question_id = $key;
$model->save();
}
}
Sorry guys if it is obvious question but I really do not understand how to do it. Googling also didn't helped.
If you have any ideas please share
You need to move the $model = new Answers(); inside the loop as you need to save all the checkboxes by looping on the post array you should create a new object every time and then it will save all of them. Just change your code to the below
public function actionSave(){
$request = \Yii::$app->request;
foreach($request->post('Questions') as $key=>$value) {
$model = new Answers();
$model->load($request->post());
$model->option_id = $value;
$model->question_id = $key;
$model->save();
}
}
Also you should use transaction block when working with related or multiple records like in this case you should either save all of them or none in case of any error or exception, currently it isnt the case. If the exception or error occurs on the 4th checkbox you still have the first 3 checkbox values saved. Try wrapping the code like below
public function actionSave(){
$request = \Yii::$app->request;
//start transaction
$transaction=Yii::$app->db->beginTransaction();
try{
foreach ($request->post('Questions') as $key => $value) {
$model = new Answers();
$model->load($request->post());
$model->option_id = $value;
$model->question_id = $key;
$model->save();
}
//commit the transaction to save the records
$transaction->commit();
}catch(\Exception $e){
//rollback the transaction so none of the checkboxes are saved
$transaction->rollBack();
//do your stuff intimate the user by adding the message to a flash and redirecting
}
}

How to post result from controller to view in yii

I am trying to do following things...I have a page which is been used for searching as well as displaying results. I have done the following things, have a controller which is filtering data and I think its working fine till now..., but now have no idea how to display the desired result in my view page.
/*Codes for Controller */
public function actionSearch()
{
$model = new SearchEmployee();
/*Getting Data From Search Form For Processing */
if (isset($_POST['SearchEmployee'])) {
$category = $_POST['SearchEmployee']['category_id'];
$skills = $_POST['SearchEmployee']['skills'];
$experience = $_POST['SearchEmployee']['experience'];
$model = SearchEmployee::model()->find(array(
'select' => array('*'), "condition" => "category_id=$category AND key_skills like '%$skills%' AND experience=$experience",
));
$this->render('search', array('model' => $model));
}
/*Getting Data From Search Form For Processing */
$this->render('search', array('model' => $model));
}
In View: I have done like below, not posting full view, just portion of section where I have to show results.
<div class="view">
<h1>Results </h1>
<div class="view" id="id">
<h1> Records Display </h1>
<h4>Name: <?php echo $model->name; ?></h4>
<h4>Skills: <?php echo $model->experience;?></h4>
<h4>Experience: <?php echo $model->key_skills; ?></h4>
<h5> <?php echo CHtml::submitButton('VIew Details'); ?></h5>
</div>
</div>
I don't know whether I am on right track.
You should try with different word rather then model like modelData etc.
public function actionSearch()
{
$model = new SearchEmployee();
/*Getting Data From Search Form For Processing */
if (isset($_POST['SearchEmployee'])) {
$category = $_POST['SearchEmployee']['category_id'];
$skills = $_POST['SearchEmployee']['skills'];
$experience = $_POST['SearchEmployee']['experience'];
$modelData = SearchEmployee::model()->find(array(
'select' => array('*'), "condition" => "category_id=$category AND key_skills like '%$skills%' AND experience=$experience",
));
$this->render('search', array('model' => $model));
}
/*Getting Data From Search Form For Processing */
$this->render('search', array('modelData' => $modelData));
}

Editing a specific record in yii

I have a view section in my project,and using CGridView to list all the data from table,also have an edit and delete option within the grid to edit and delete specific row.
I am stuck with the edit section.I am working on how to get a specific row data dispalyed in editjob.php,I have done a few things,but no use.My codes are as follows,
In my view job section using CgridView,
'buttons' =>array('update'=>array(
'label'=>'edit',
'url'=>'Yii::app()->controller->createUrl("UpdateJob",array("id"=>$data["id"]))',
))
In Model UpdateJob:
public function edit()
{
$criteria=new CDbCriteria;
$criteria->find('id','Admin',true);
return new CActiveDataProvider('viewjob', array(
'criteria'=>$criteria,
// 'sort'=>array(
// 'defaultOrder'=>'key_skills ASC',
// ),
));
in controller:
public function actionUpdateJob()
{
if(isset($_GET['id']))
{
$id=$_GET['id'];
}
$model = new UpdateJob('edit');
$params = array('model' => $model,'id' => $id //passing the id like this
);
$this->render('update', $params);
}
And finaly in view written something like ,but showing error
<div class="row">
<?php echo $form->labelEx($model,'Company Name'); ?>
<?php echo Chtml::textField('posted_by',UpdateJob::model()->FindByPk($model->id)->posted_by); ?>
<?php echo $form->error($model,'posted_by'); ?>
</div>
am I on right track.
Youre loading a fresh model instead of fetching an existing one. Replace this line:
$model = new UpdateJob('edit');
By this line:
$model = UpdateJob::model()->findByPk($id);
To save the data you do this:
if(isset($_POST['UpdateJob'])) {
$model->scenario='edit';
$model->attributes=$_POST['UpdateJob'];
if($model->save())
$this->redirect(array('admin');
}

How to customize dataProvider using CListView in Yii

I'm trying to output data into the CListView of the current user only. So far, if I put in the $dataProvider, it only outputs ALL the records from the database.
This is my current code:
$current = Yii::app()->user->id;
$currentid = Yii::app()->db->createCommand("select * from content where id = ". $current)->queryRow();
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider, //This is the original. I tried replacing it
//with $currentid but errors.
'itemView'=>'_view2',
'template'=>'{items}<div>{pager}</div>',
'ajaxUpdate'=>false,
));
From what I understand from the Yii Documentations, $dataProvider stores all the data within the database and places it inside the dataProvider itself and my "_view2" uses that to output all the records.
My Controller codes for the showing/view is as follows:
public function actionView()
{
$post=$this->loadModel();
if(Persons::model()->compare_country(explode("|",$post->country)))
{
$post->view_count = $post->view_count + 1;
Yii::app()->db->createCommand("UPDATE content SET view_count = {$post->view_count} WHERE id = {$post->id}")->execute();
//$post->save();
$comment=$this->newComment($post, 'view');
if (!empty(Yii::app()->session['announcement_message']))
{
Yii::app()->user->setFlash('message',Yii::app()->session['announcement_message']);
Yii::app()->session['announcement_message'] = null;
}
$this->render('view',array(
'model'=>$post,
'comment'=>$comment,
'view'=>'view',
));
}
else
{
$this->redirect(Yii::app()->createAbsoluteUrl('news/index',array('page'=>'1')));
}
}
public function actionShow($id)
{
$post=$this->loadModel($id);
$comment=$this->newComment($post);
$attachments=Attachments::model()->findAllByAttributes(array(
'content_id' => $id,
));
$this->render('show',array(
'model'=>$post,
'comment'=>$comment,
'attachments'=>$attachments
));
}
If you wanted to see my _view2, these are my codes:
<div class="profile-member-post-box announcement" >
<div class="events-post-bodytext profile-member-info">
<?php $person=Persons::model()->findByAttributes(array('party_id'=>$data->party_id));
if ($person->party_id === Yii::app()->user->id)
{
?>
<span><?=CHtml::link($data->title, array('view', 'id'=>$data->id), array('class' => 'titlelink'));?></span>
<?php
$country=Lookup_codes::model()->findByAttributes(array('id'=>$person->country));
$location = empty($country) ? '' : 'of '.$country->name;
$sysUser=User::model()->findByAttributes(array('party_id'=>$data->party_id));
?>
<p>
By: <?php echo CHtml::link($person->getusername(), array('persons/view/id/'.$person->showViewLinkId())); ?>
<span class="date2"> - <?php echo date('M j, Y',strtotime($data->date_created)); ?></span>
</p>
<div>
<?php if(Yii::app()->partyroles->isAdmin() || ((get_access('Announcement','edit') && (Yii::app()->user->id == $data->party_id)) || (get_local_access('sub-admin','edit',$data->id)))):?>
Edit | <?php endif;?> <?php echo (Yii::app()->partyroles->isAdmin() || (get_access('Announcement','delete') && (Yii::app()->user->id == $data->party_id)) || (get_local_access('sub-admin','delete',$data->id))) ? CHtml::link('Delete','#',array('submit'=>array('delete','id'=>$data["id"]),'confirm'=>'Are you sure you want to delete this item?')) : NULL?>
</div>
<?php
}
else
?>
</div>
I just need to be able to fix the view to show records only by the current user.
UPDATE!!------------
I'm going to add my actionIndex here:
public function actionIndex()
{
if(get_access('Announcement','view') || get_access('Announcement','view_local'))
{
$id = Yii::app()->user->id;
$condition = Persons::model()->get_view_condition('Announcement');
$criteria=new CDbCriteria(array(
'condition'=>'1=1 '.$condition,
'order'=>'date_modified DESC',
'with'=>'commentCount',
));
/*
if(isset($_GET['tag']))
$criteria->addSearchCondition('tags',$_GET['tag']);
*/
$items=SystemParameters::model()->findAllByAttributes(array(
'name' => 'blogs_per_page',
));
$dataProvider=new CActiveDataProvider('Announcement', array(
'pagination'=>array(
'pageSize'=>strip_tags($items[0]->value),
),
'criteria'=>$criteria,
));
/* $dataProvider=new CActiveDataProvider('Announcement', array(
'pagination'=>array(
'pageSize'=>5,
),
'criteria'=>$criteria,
));*/
//$dataProvider=Announcement::model()->findAll();
$attachments=Attachments::model()->findAllByAttributes(array(
'content_id' => $id,
));
if (!empty(Yii::app()->session['announcement_message']))
{
Yii::app()->user->setFlash('message',Yii::app()->session['announcement_message']);
Yii::app()->session['announcement_message'] = null;
}
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
}
else
{
$this->redirect(Yii::app()->createAbsoluteUrl('news/index',array('page'=>'1')));
}
}
Your question is very hard to follow... but I'll attempt to answer by giving an example of how to use the CDataProvider and CListView to display all of the Announcements owned by the current logged in User. This assumes the Announcement model's table has a user_id field which contains the id of the User who owns or created it.
First, in your indexAction() in your controller:
// get the logged in user's ID
$userId = Yii::app()->user->id;
// now define the dataprovider, which will do the SQL query for you
$dataProvider = new CActiveDataProvider( // declare a new dataprovider
'Announcement', // declare the type of Model you want to query and display
array( // here we build the SQL 'where' clause
'criteria' => array( // this is just building a CDbCriteria object
'condition' => 'user_id=:id', // look for content with the user_id we pass in
'params' => array(':id' => $userId), // pass in (bind) user's id to the query
//'order'=>'date_modified DESC', // add your sort order if you want?
//'with'=>'commentCount', // join in your commentCount table?
)
)
);
$this->render('index',array( // render the Index view
'dataProvider'=>$dataProvider, // pass in the data provider
));
Then in your index.php view:
// create the CListView and pass in the $dataProvider we created above, in the indexAction
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider, // this is the data provider we just created
'itemView'=>'_view2',
'template'=>'{items}<div>{pager}</div>',
'ajaxUpdate'=>false,
));

DropDownList effects a ClistView in Yii

I am still very new to this Yii framework, and I would like assistance with this code. I currently manage to get a dropdownlist dependent on another dropdownlist but I can't seem to get the dropdownlist to effect what gets displayed in the ClistView.
profile Controller
/* add a team message submitted by the coach of the team */
public function actionAddTeamMessage($id)
{
/* check if team and message aren't null */
if(isset($_POST['teamId']['addTeamMessage']))
{
try
{
/* creates a new message */
$teamModel = new TeamMessage;
$teamModel->teamId = $_POST['teamId'];
$teamModel->content = $_POST['addTeamMessage'];
$teamModel->sendTime = new CDbExpression('NOW()');
$teamModel->save();
}
catch(Exception $e)
{
echo "Unable to save.";
}
}
/* render the profile page for the current user */
$user=User::model()->findByPk($id);
$this->render('profile', array(
'model' => $user));
}
/* will handle functionality for the user dropdownlist ajax
* under contructions
*/
public function actionDisplayMessage()
{
$data = TeamMessage::model()->findAll('teamId=:teamId', array(
':teamId'=>(int) $_POST['teamId']
)
);
$data=CHtml::listData($data,'id', 'content');
echo "<option value=''>Select Message</option>";
foreach($data as $value=>$content)
echo CHtml::tag('option', array('value'=>$value),CHtml::encode($content),true);
//TODO still being tested.
/* for ClistView still debugging */
/*$dataProvider=new CActiveDataProvider('Player', array(
'criteria'=>array(
'condition'=>'teamId=:teamId',
)));*/
}
View Profile
<!-- Would allow user to access specific team messages and control how much gets display.
still under construction. -->
<div class="row">
<?php
echo CHtml::dropDownList("teamId", 'id', Chtml::listData($model->memberOfTeams, 'id', 'teamName'),array(
'empty'=>'Select Team',
'ajax'=>array(
'type'=>'POST', // request type
'url'=>CController::createUrl('DisplayMessage'),
'update'=>'#teamMessages', // selector to update
'data'=>array('teamId'=>'js:this.value'),
)
)
);
?>
<?php
echo CHtml::dropDownList('teamMessages','',array(),array('empty'=>'Select Message'));
/*$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_viewTeamMessage',
'id'=>'ajaxListView',
));*/
?>
</div>
As you can see in the cListView. I was debating on creating a _viewTeamMessage which will display the team message + sendtime. But I realize, I wouldn't be able to pass a dataprovider without re rendering the page, and i am trying to avoid heading into that direction.
You could pull your Team messges out into a partial view and then just use a render partial to render just the messages into your page usig Ajax. If the partial view is named _teamMessages.php it would look something like this (untested):
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_viewTeamMessage',
'id'=>'ajaxListView',
));
Then you modify your profile view to look like:
<!-- Would allow user to access specific team messages and control how much gets display.
still under construction. -->
<div class="row">
<?php
echo CHtml::dropDownList("teamId", 'id', Chtml::listData($model->memberOfTeams, 'id', 'teamName'),array(
'empty'=>'Select Team',
'ajax'=>array(
'type'=>'POST', // request type
'url'=>CController::createUrl('DisplayMessage'),
'update'=>'.team-messages', // selector to update
'data'=>array('teamId'=>'js:this.value'),
)
)
);
?>
<div class="team-messages">
<?php
$this->renderPartial('_teamMessages',
array('dataProvider'=>$dataProvider))
?>
</div>
</div>
Then finally you change your controller to something like this:
public function actionDisplayMessage()
{
/* REMOVE
$data = TeamMessage::model()->findAll('teamId=:teamId', array(
':teamId'=>(int) $_POST['teamId']
)
);
$data=CHtml::listData($data,'id', 'content');
echo "<option value=''>Select Message</option>";
foreach($data as $value=>$content)
echo CHtml::tag('option', array('value'=>$value),CHtml::encode($content),true);
*/
// still being tested.
$dataProvider=new CActiveDataProvider('Player', array(
'criteria'=>array(
'condition'=>'teamId=(int) $_POST['teamId']',
)));
$this->renderPartial('_teamMessages', array('dataProvider'=>$dataProvider);
}
this should just cause the message widget to be recreated instead of the whole page.

Categories