Yii 1.1.19 Join Table Update not working fully - php

The Problem: If I select the new checkbox, it will update the data, but when I unchecked all the existing checkbox, it is not working. Even when I unchecked multiple checkboxes and leave one, it still works. Just not working when I select all unchecked checkbox to update data. Any suggestion would be greatly appreciated
This is my model that I am using get join table ID:
public function getProfileCampaigns($campaignIds = true) {
$campaignData = array();
$campaignProfiles = Yii::app()->db->createCommand()->select('campaign_id')
->from('campaign_profiles')
->where('profile_id = :profile_id',array(':profile_id' => $this->profile_id))
->queryAll();
// Check if need to send only campaign ids
if ($campaignIds) {
foreach ($campaignProfiles as $campaignProfile) {
$campaignData[] = $campaignProfile['campaign_id'];
}
}
return $campaignData;
}
This my controller for update action:
public function actionUpdate($id)
{
$model = $this->loadModel($id);
$model->setScenario(Profile::SCENARIO_UPDATE);
// Get active campaigns
$campaigns = Campaign::model()->findAll();
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model);
// Check if profile have any releated profile
$model->campaignIds = $model->getProfileCampaigns();
if(isset($_POST['Profile']))
{
$model->attributes=$_POST['Profile'];
if($model->validate()) {
$model->save();
// Check if any campaign choosed
if ($_POST['Profile']['campaignIds']) {
Yii::app()->db->createCommand()->delete('campaign_profiles', 'profile_id = :profile_id', array(':profile_id' => $model->profile_id));
foreach ($_POST['Profile']['campaignIds'] as $campaignId) {
$campaignProfile = new CampaignProfile();
$campaignProfile->setIsNewRecord(true);
$campaignProfile->campaign_id = $campaignId;
$campaignProfile->profile_id = $model->profile_id;
$campaignProfile->save();
}
Yii::app()->user->setFlash('success', 'The Profile was successfully updated.');
$this->redirect(array('update','id'=>$model->profile_id));
}
}
}
$this->render('update',array(
'model' => $model,
'campaignListData' =>$campaigns,
));
}
This is form for getting checkbox select for update:
<div class="form-group">
<?php echo $form->labelEx($model,'campaignIds'); ?>
<div class="col-sm-9">
<?php echo $form->checkBoxList($model, 'campaignIds', CHtml::listData($campaignListData, 'id', 'name')); ?>
<?php echo $form->error($model,'campaignIds'); ?>
</div>
</div>

That is because only selected checboxes are send as form data. When no checkbox is checked, no data is sent, so probably default/old value from model is used.
You may use uncheckValue setting to define default value which will be send, when no checkbox is checked:
<div class="form-group">
<?php echo $form->labelEx($model,'campaignIds'); ?>
<div class="col-sm-9">
<?php echo $form->checkBoxList(
$model,
'campaignIds',
CHtml::listData($campaignListData, 'id', 'name'),
['uncheckValue' => '']
); ?>
<?php echo $form->error($model,'campaignIds'); ?>
</div>
</div>
Since 1.1.7, a special option named 'uncheckValue' is available. It can be used to set the value that will be returned when the checkbox is not checked. By default, this value is ''. Internally, a hidden field is rendered so when the checkbox is not checked, we can still obtain the value. If 'uncheckValue' is set to NULL, there will be no hidden field rendered.
https://www.yiiframework.com/doc/api/1.1/CHtml#activeCheckBoxList-detail

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 checked values of radiolist to database?

I am trying to create a Quiz app, with many MCQ questions that are stored in Database. I successfully get questions and options from Db and display it.
However, when I try to post the checked values to Db it doesn't work.
I am using ActiveForm and RadioList inside of it.
All data is taken from Db using for loop.
Also, I need to pass the question_id when posting the checked value.
I have Tables:
Questions - questions table.
Answers - table where I want to write the checked values.
Options - Table from where I get the options(a,b,c) for the questions.
Answers Controller:
public function actionSave()
{
$model = new Answers;
$request = \Yii::$app->getRequest();
if ($request->isPost && $model->load($request->post())) {
\Yii::$app->response->format = Response::FORMAT_JSON;
return ['success' => $model->save()];
}
return $this->renderAjax('index', [
'model' => $model,
]);
}
public function actionCreate()
{
$model = new Answers;
$this->save($model);
}
protected function save($model)
{
if (isset($_POST['Answers'])) {
$model->attributes = $_POST['Answers'];
if ($model->save()) {
$this->redirect(array('index'));
}
}
$this->render('_form', compact('model'));
}
Here is the view:
<?php $form = ActiveForm::begin(); ?>
<?php for ($i=0; $i<count($questions); $i++): ?>
<div>
<?= Html::encode("{$questions[$i]->title}") ?>
</div>
<?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_id')->radioList($options, ['name'=>'Questions['.$questions[$i]->id.']', 'separator' => '<br>' ])->label(false) ?>
</label>
<?php endfor; ?>
<?= Html::submitButton('Save', ['class' => 'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>
I expect that when user answers all questions and press the "Save" button, it will save the checked value and question_id to the table in Db. However, now it do nothing, and do not show any errors.
I am working on this first time, so please can you help me to understand how to do it?
We are lacking the code of the model, as it is right now you could do:
Dump the post inside the action with var_dump($request->post());die();
Check if the values are on the post.
Check if the field name are in the rules of the class.
Check if the name of the field in the post is right.

Dependent dropdown is not showing selected value when update

I am new to yii. I have a dependent dropdown, my problem is that in dependent dropdown when someone is editing, while editing the dropdown is not automatically selected.
Here is my form code:
<div class="row">
<?php
Yii::app()->clientScript->registerScript('courseDropdown','jQuery(function($) {
$("#Subject_Subjectid").trigger("change");
$("#Subjectcourse_CourseId").val(\''.$model->CourseId.'\');
});
');//write this code on _form.php file
?>
<?php echo $form->labelEx($model,'Subjectid'); ?>
<?php
$sub = CHtml::listData(Subject::model()->findAll(array("condition"=>"School_Id='$School' and Status=1")),'Subjectid','SubjectName');
echo CHtml::activeDropDownList($model,'Subjectid',CHtml::listData(Subject::model()->findAll(array("condition"=>"School_Id='$School' and Status=1")),'Subjectid','SubjectName'),
array(
'empty'=>'--Select a Subject--',
'ajax' => array(
'type'=>'POST', //request type
'url'=>CController::createUrl('Timetable/subjectid'), //url to call.
'data'=>array('Subjectid'=>'js: $(this).val()'),
'update'=>'#CourseId', //selector to update
)));
echo $form->error($model,'Subjectid');
echo $form->labelEx($model,'CourseId');
echo CHtml::dropDownList('CourseId','', array(), array('empty' => '-- Select a Course --'));
echo $form->error($model,'CourseId');
?>
</div>
This is my controller action
public function actionSubjectid()
{
$SchoolId=Yii::app()->session['Schoolid'];
$subjectid=$_POST['Subjectid'];
$subject = Subject::model()->findByPk($subjectid);
$data = Subjectcourse::model()->findAll(array("order"=>"CourseName ASC", "select"=>"CourseId,CourseName","condition" => "SubjectId='$subjectid' AND Status=1 AND School_Id='$SchoolId'"));
$data=array('empty'=>'-- Select a Course --') +CHtml::listData($data,'CourseId','CourseName');
foreach($data as $value=>$name)
{
echo CHtml::tag('option', array('value'=>$value),CHtml::encode($name),true);
}
}
This is my action update
public function actionUpdate($id)
{
$model=$this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Timetable']))
{
$model->attributes=$_POST['Timetable'];
$model->School_Id=Yii::app()->session['Schoolid'];
$CourseId=$_POST['CourseId'];
if($CourseId=="empty")
$model->CourseId='';
else
$model->CourseId=$_POST['CourseId'];
$model->Status=1;
if($model->save())
$this->redirect(array('view','id'=>$model->Id));
}
$this->render('update',array(
'model'=>$model,
));
}
As your second drop down will only work when a change event occurs in your first drop down, you can trigger this event when the page loads, something like this:
<?php
Yii::app()->clientScript->registerScript('courseDropdown','jQuery(function($) {
$("#Subject_Subjectid").trigger("change");
$("#Subjectcourse_CourseId").val(\''.$model->CourseId.'\');
});
');//write this code on _form.php file
?>
Edit: Alternatively, you could populate the second dropdown by querying data from the value of first dropdown:
if(!$model->isNewRecord) {
$courseArr = Chtml::listData(Subjectcourse::model()->findAllByAttributes(array('SubjectId'=>$model->Subjectid)), 'CourseId','CourseName'); //your query, modify according to need
} else {
$courseArr = array();
}
echo $form->labelEx($model,'CourseId');
echo CHtml::dropDownList('CourseId','', $courseArr, array('empty' => '-- Select a Course --'));
echo $form->error($model,'CourseId');

Edit page has to be submitted twice for changes to be saved

I have an edit page set up for editing blog posts. Here's the controller action...
public function edit($id = null) {
$post = $this->Post->findById($id);
if(!$post) {
throw new NotFoundException('Post not found');
}
if($this->request->is('post')) {
$this->Post->id = $id;
if($this->Post->save($this->request->data)) {
$this->Session->setFlash('Post updated!');
$this->redirect('/');
} else {
$this->Session->setFlash('Unable to update post!');
}
}
if (!$this->request->data) {
$this->request->data = $post;
}
$this->set('tags', $this->Post->Tag->find('list'));
$this->set('pageTitle', 'Edit blog post');
}
And the edit pages view...
<h1>Edit blog post</h1>
<?php echo $this->Form->create('Post'); ?>
<?php echo $this->Form->input('Post.title'); ?>
<?php echo $this->Form->input('Post.body'); ?>
<?php echo $this->Form->input('Tag.Tag', array('type' => 'text', 'label' => 'Tags (seperated by space)', 'value' => $tags)); ?>
<?php echo $this->Form->input('Post.slug'); ?>
<?php echo $this->Form->end('Save Changes'); ?>
For some reason when I make changes and click "save changes", the page just refreshes and although the changes are reflected in the form after the refresh, I have to click "save changes" again for them to get saved to the database and for Cake to redirect me to /.
What could be causing that?
Because there is no Post.id in your form, CakePHP sends a PUT request (instead of a POST request) to create (or "put") a new row into your database the first time. This doesn't pass your request check:
if($this->request->is('post'))
Now, at this point your logic gets the entire row for the corresponding post, with this code:
$this->request->data = $post;
This will include the ID of the given post, since it's in your find() result and hence the second time you submit it, it has an id and therefor sends a POST request instead of a PUT request.
Assuming you only want to edit existing posts, add an id field to your form (the FormHelper automagic should make a hidden field of it, but you can always explicitly tell it to, like in the example below):
echo $this->Form->input('Post.id', array('type' => 'hidden');
This should pass along the id and hence trigger a POST request rather than a PUT request and make your submission pass at once.

how to get the value of form input box in codeigniter

value of FORM INPUT Help!!
//this is just a refrence of $nm and $fid from test_model//
$data['fid']['value'] = 0;
$data['nm'] = array('name'=>'fname',
'id'=>'id');
say i have one form_view with
<?=form_label('Insert Your Name :')?>
<?=form_input($nm)?>
and a function to get single row
function get($id){
$query = $this->db->getwhere('test',array('id'=>$id));
return $query->row_array();
}
then in controller.. index($id = 0)
and somewhere in index
if((int)$id > 0)
{
$q = $this->test_model->get($id);
$data['fid']['value'] = $q['id'];
$data['nm']['value'] = $q['name'];
}
and mysql table has something like 1. victor, 2. visible etc. as a name value
but here its not taking the value of name and id from form_input and not showing it again in form_view in same input box as victor etc so to update and post it back to database...
anyone please help!!
and please be easy as I am new to CI!!
Based on your comment to my first answer, here is a sample of a Controller, Model and View to update a user entry pulled from a table in a database.
Controller
class Users extends Controller
{
function Users()
{
parent::Controller();
}
function browse()
{
}
function edit($id)
{
// Fetch user by id
$user = $this->user_model->get_user($id);
// Form validation
$this->load->library('form_validation');
$this->form_validation->set_rules('name', 'Name', 'required');
if ($this->form_validation->run())
{
// Update user
$user['name'] = $this->input->post('name', true);
$this->user_model->update_user($user);
// Redirect to some other page
redirect('users/browse');
}
else
{
// Load edit view
$this->load->view('users/edit', array('user' => $user));
}
}
}
Model
class User_model extends Model
{
function User_model()
{
parent::Model();
}
function get_user($user_id)
{
$sql = 'select * from users where user_id=?';
$query = $this->db->query($sql, array($user_id));
return $query->row();
}
function update_user($user)
{
$this->db->where(array('user_id' => $user['user_id']));
$this->db->update('users', $user);
}
}
View
<?php echo form_open('users/edit/' . $user['user_id']); ?>
<div>
<label for="name">Name:</label>
<input type="text" name="name" value="<?php echo set_value('name', $user['name']); ?>" />
</div>
<div>
<input type="submit" value="Update" />
</div>
<?php echo form_close(); ?>
It's hard to see the problem from your snippets of code, please try and give a little more information as to the structure of your app and where these code samples are placed.
Presume in the last code listing ('somewhere in index') you are getting $id from the form, but you define the ID of the form input box as 'id' array('name'=>'fname','id'=>'id') rather than an integer value so maybe this is where the problem lies.
Where does the $data array get passed to in the third code listing?
From your question I think you want to display a form to edit a person record in the database.
Controller code
// Normally data object is retrieved from the database
// This is just to simplify the code
$person = array('id' => 1, 'name' => 'stephenc');
// Pass to the view
$this->load->view('my_view_name', array('person' => $person));
View code
<?php echo form_label('Your name: ', 'name'); ?>
<?php echo form_input(array('name' => 'name', 'value' => $person['name'])); ?>
Don't forget to echo what is returned from form_label and form_input. This could be where you are going wrong.

Categories