How to validate a form with radio group in CodeIgniter - arrays

I have a form that presents questions and answers from a survey. User can select between 5 radio buttons - to choose answer of questions. They are array and the key is question_id - each question has these 5 radio buttons and they differ on this key.Could you help me with form validation?
Now if you choose answer for one of the questions, form submits. It has to submit only if all questions have answers. That's my view:
<html>
<head></head>
<body>
<?php
$survey_id = $this->uri->segment(3);
$question_id = $this->uri->segment(4);
$att=array('id'=>'form');
echo form_open('index/survey_fill/' .$survey_id .'/'. $question_id , $att);
echo "<table border="0" id='questionsTable' >";
echo "<tr><th>Въпрос</th></tr>";
echo validation_errors();
$index = 0;
foreach ($question as $row)
{
echo "<tr id='$index'>";
$index++;
?>
<td>
<?php echo "$row->question"; ?><br/>
<?php echo "<input type='hidden' name='question_id' value='$row->question_id' />"; ?>
<?php
$data=array(
'name' => 'answer['.$row->question_id.']',
'value' => '5',
'class' => 'answer'
);
echo "<input type='hidden' name='survey_id' value='$row->survey_id'>";
echo form_radio($data);
echo " 5 ";
$data=array(
'name' => 'answer['.$row->question_id.']',
'value' => '4',
'class' => 'answer'
);
echo form_radio($data);
echo " 4 ";
$data=array(
'name' => 'answer['.$row->question_id.']',
'value' => '3',
'class' => 'answer'
);
echo form_radio($data);
echo " 3 ";
$data=array(
'name' => 'answer['.$row->question_id.']',
'value' => '2',
'class' => 'answer'
);
echo form_radio($data);
echo " 2 ";
$data=array(
'name' => 'answer['.$row->question_id.']',
'value' => '1',
'class' => 'answer'
);
echo form_radio($data);
echo " 1 ";
?>
</td></tr>
<?php
}
?>
</table>
<?php echo "<input type='hidden' name='question_id' value='$row->question_id' />"; ?>
<?php echo '<input type="submit" id="button" name = "submit" value="Submit" class="btn btn-success">';
?>
</form>
</div>
</body>
</html>
My controller is:
public function survey_fill()
{
$this->form_validation->set_rules('answer[]', 'Answer', 'required');
if ($this->form_validation->run()==FALSE)
{
$this->survey_show();
}
else
{
if ($this->user_model->survey_fill())
{
header('Refresh: 2; url=/survey/index.php/index/surveys_show');
}
else
{
$this->load->model('user_model');
$data['survey'] =$this->user_model->survey_show();
$data['dynamic_view'] = 'survey_show';
$data['menu']=$this->menu_model->get_menu();
$this->load->view('templates/main',$data);
}
}
}

Two ways:
1) Set the required attribute in your data array like
$data = array('name' => 'answer['.$row->question_id.']', 'required' => 'required');
2) Set the form validation for each of your answer[$question_id] variables.
foreach($questions as $question){
$this->form_validation->set_rules('answer['.$question->id.']', 'Question '.$question->id, 'required');
}
I'd stick with 1.

Related

CakePHP Html->link and Form->end

I have this link that I use to for my modal
<?php
echo $this->Html->link('Create Schedule', '#', array('id' => 'createSchedule', 'class' => 'btn btn-success', 'role' => 'button', ));
?>
How do I convert it to $this->Form->end() format?
Thank you!
You can do this also
<?php
echo $this->Form->button("Create Schedule", array("id" => "createSchedule", "class" => "btn btn-success", "type" => "submit"));
echo $this->Form->end();
?>
or you could also do this
<?php
echo $this->Form->submit("Create Schedule", array("id" => "createSchedule", "class" => "btn btn-success"));
echo $this->Form->end();
?>
You can try this
<?php
$options = array(
'label' => 'Create Schedule',
'id' => 'createSchedule',
'class' => 'btn btn-success'
);
echo $this->Form->end($options);
?>

Why my variables are undefined i click on the submit button?

I have fields in a form with variables from the Controller TownsController, I use "set" to be able to affchés in sight. I arrive at the desired result, the problem is that when I want to send my information by clicking on the submit button, I have several errors telling me that the variable is undefined.
Before i click on the submit button :
After i click on the submit button :
The view :
<h2>Informations de votre ville</h2>
<?php echo $this->Form->create('Town'); ?>
<div class="form-group">
<div class="col-xs-6">
<?php echo $this->Form->input('statut',array(
'label' => 'Statut',
'type' => 'select',
'options' => array(
'Village'=>'Village',
'Ville'=>'Ville'),
'selected' => $selectedstatut,
'class' => 'form-control',
'id' => 'town_statut_municipal',
'empty' => __('Statut municipal')
));
?>
</div>
</div>
<div class="form-group">
<div class="col-xs-6">
<?php echo $this->Form->input('name', array('type' => 'text', 'id' => 'town_name', 'class' => 'form-control', 'placeholder' => 'Choisir un statut municipal', 'label' => 'Nom')); ?>
</div>
</div>
<div class="form-group">
<div class="col-xs-6">
<?php echo $this->Form->input('country', array('type' => 'select', 'class' => 'form-control', 'label' => 'Pays', 'id' => 'town_country', 'onchange' => "print_state('state',this.selectedIndex);", 'selected' => $selectedcountry, 'empty' => false,
'options' => array(
'Canada'=>'Canada',
'USA'=>'USA'))); ?>
</div>
</div>
<div class="form-group">
<div class="col-xs-6">
<?php
echo $this->Form->input('localisation', array('type' => 'select', 'class' => 'form-control', 'label' => 'Localisation', 'id' => 'state', 'empty' => $namelocalisation,
'options' => $localisations)); ?>
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<br>
<?php
$options = array('label' => 'Sauvegarder', 'class' => 'btn', 'div' => false, 'class' => 'btn btn-lg btn-success');
echo $this->Form->end($options);
?>
</div>
</div>
</form>
TownsController (edit view) :
public function edit(){
$town_id = $this->Auth->user('town_id');
$user_id = $this->Auth->user('user_id');
if(!$town_id && !$user_id) {
$this->redirect('/');
die();
}
$this->Town->id = $town_id;
if($this->request->is('put') || $this->request->is('post')) {
}
else {
$this->request->data = $this->Town->read(array('name', 'country', 'localisation', 'statut'), null);
$selectedstatut = $this->Session->read('Auth.Town.statut');
$this->set(compact('selectedstatut'));
$selectedcountry = $this->Session->read('Auth.Town.country');
$this->set(compact('selectedcountry'));
$countryuser = $this->Session->read('Auth.Town.country');
if($countryuser = 'Canada') {
$namelocalisation = 'Province';
$localisations = array(
'Alberta'=>"Alberta",
'British Columbia'=>"British Columbia",
'Manitoba'=>"Manitoba",
'New Brunswick'=>"New Brunswick",
'Newfoundland'=>"Newfoundland",
'Northwest Territories'=>"Northwest Territories",
'Nova Scotia'=>"Nova Scotia",
'Nunavut'=>"Nunavut",
'Ontario'=>"Ontario",
'Prince Edward Island'=>"Prince Edward Island",
'Quebec'=>"Quebec",
'Saskatchewan'=>"Saskatchewan",
'Yukon Territory'=>"Yukon Territory");
}
if($countryuser = 'USA') {
$namelocalisation = 'État';
$localisations = array(
'Alabama'=>"Alabama",
'Alaska'=>"Alaska",
'Arizona'=>"Arizona",
'Arkansas'=>"Arkansas",
'California'=>"California",
'Colorado'=>"Colorado",
'Connecticut'=>"Connecticut",
'Delaware'=>"Delaware",
'District Of Columbia'=>"District Of Columbia",
'Florida'=>"Florida",
'Georgia'=>"Georgia",
'Hawaii'=>"Hawaii",
'Idaho'=>"Idaho",
'Illinois'=>"Illinois",
'Indiana'=>"Indiana",
'Iowa'=>"Iowa",
'Kansas'=>"Kansas",
'Kentucky'=>"Kentucky",
'Louisiana'=>"Louisiana",
'Maine'=>"Maine",
'Maryland'=>"Maryland",
'Massachusetts'=>"Massachusetts",
'Michigan'=>"Michigan",
'Minnesota'=>"Minnesota",
'Mississippi'=>"Mississippi",
'Missouri'=>"Missouri",
'Montana'=>"Montana",
'Nebraska'=>"Nebraska",
'Nevada'=>"Nevada",
'New Hampshire'=>"New Hampshire",
'New Jersey'=>"New Jersey",
'New Mexico'=>"New Mexico",
'New York'=>"New York",
'North Carolina'=>"North Carolina",
'North Dakota'=>"North Dakota",
'Ohio'=>"Ohio",
'Oklahoma'=>"Oklahoma",
'Oregon'=>"Oregon",
'Pennsylvania'=>"Pennsylvania",
'Rhode Island'=>"Rhode Island",
'South Carolina'=>"South Carolina",
'South Dakota'=>"South Dakota",
'Tennessee'=>"Tennessee",
'Texas'=>"Texas",
'Utah'=>"Utah",
'Vermont'=>"Vermont",
'Virginia'=>"Virginia",
'Washington'=>"Washington",
'West Virginia'=>"West Virginia",
'Wisconsin'=>"Wisconsin",
'Wyoming'=>"Wyoming");
}
$this->set('localisations', $localisations);
$this->set('namelocalisation', $namelocalisation);
}
}
The reason is that you set those variables IF the request is not POST. When you click on Submit your code will enter in the "isPost" condition, hence the variables localisations, namelocalisation, selectedcountry and selectedstatut are never set.
Here's what I would do (pseudo code)
if ($this->request->is(array('post', 'put'))) {
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been updated.'));
return $this->redirect(array('action' => 'index'));
}
}
$selectedstatut = $this->Session->read('Auth.Town.statut');
etc...
Notice I am setting the view variables outside the if statement so that if save fails (because validation) then we set the variables again.

render elements in cakephp on home.ctp

I am using cakephp 2.4
in my apps I have a view in CategoriesController namely "Editorial" and I can show all the articles under that category by http://mydomain/categories/editorial
I am trying to show all the articles under "Editorial" category in the home.ctp by echo $this->element('editorials');
but it shows Notice (8): Undefined variable: articles [APP\View\Elements\Editorials.ctp, line 4]
CategoriesController.php
public function Editorial() {
$category = $this->Category->find('first', array(
'conditions' => array(
'Category.id' => 1
)
));
$this->set(compact('category'));
$this->Paginator = $this->Components->load('Paginator');
$this->Paginator->settings = array(
'Article' => array(
'recursive' => -1,
'contain' => array(
'Category'
),
'limit' => 5,
'conditions' => array(
'Article.category_id' => $category['Category']['id'],
),
'order' => array(
'Article.id' => 'ASC'
),
'paramType' => 'querystring',
)
);
$articles = $this->Paginator->paginate($this->Category->Article);
$this->set(compact('articles'));
}
View file:
<?php if (!empty($articles)): ?>
<?php echo $this->element('editorials'); ?>
<?php echo $this->element('pagination-counter'); ?>
<?php echo $this->element('pagination'); ?>
<?php endif; ?>
Elements/Editorials.ctp:
<div class="row">
<?php
$i = 0;
foreach ($articles as $art):
$i++;
if (($i % 4) == 0) { echo "\n<div class=\"row\">\n\n";}
?>
<div class="col col-sm-3">
<?php echo $this->Html->link($art['Article']['title'], array('controller' => 'articles', 'action' => 'view', 'id' => $art['Article']['id'])); ?>
<br />
</div>
<?php
if (($i % 4) == 0) { echo "\n</div>\n\n";}
endforeach;
?>
<br />
<br />
</div>
try to add $this->render('file'); in your Editorial action and replace file with view file name without.ctp
Something you can change:
1. In controller:
$this->set(compact('category', 'articles')); // one set()
2. In view: (Main Point)
<?php echo $this->element('editorials', array('articles' => $articles)); ?>
Here, you need to pass the articles variable to element like above, by default an element don't recognize the viewVars.

Form checkbox and label with CakePHP and Bootstrap

I'm having some issues trying to get checkbox inputs and labels to output the correct HTML using CakePHP and Twitter Bootstrap.
The Bootstrap specific output should be:
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox"> Keep me logged in
</label>
</div>
</div>
However, using the inputDefaults mentioned here (http://stackoverflow.com/a/9496242/1247225), this Cake form input:
echo $form->input('auto_login', array(
'type' => 'checkbox',
'label' => __('Keep me logged in', true)));
Outputs this:
<div class="control-group">
<input type="hidden" name="data[User][auto_login]" id="UserAutoLogin_" value="0" />
<input type="checkbox" name="data[User][auto_login]" class="" value="1" id="UserAutoLogin" />
<div class="controls">
<label for="UserAutoLogin">Keep me logged in</label>
</div>
</div>
Any ideas how to adjust this individual input so it outputs the correct Bootstrap HTML, like above?
The best way to control the form output, or the format of the output, is by passing a 'format' argument. Try playing with this:
'format' => array('before', 'label', 'input', 'between', 'after', 'error')
I don't think it is document, but by reading the code, you can find it in there.
the prettiest way to do it is this:
<?php
echo '<div class="col-lg-2">';
echo $this->Form->input('Content.checkbox', array(
'div' => array(
'class' => 'input-group',
),
'label' => false,
'type' => 'checkbox',
'before' => '<span class="input-group-addon">',
'after' => '</span><span class="input-group-addon"><label for="ContentCheckbox">What does the fox say?</label></span>',
));
echo '</div>';
I using :
<?php
echo $this->Form->input('coupDeCoeur',
array('div' => false,
'label' => false,
'type' => 'checkbox',
'before' => '<label class="checkbox">',
'after' => '<i></i>coupDeCoeur</label>'
));
?>
You need to build the form widget manually for checkboxes instead of using FormHelper::input.
For example:
echo '<div class="control-group">';
echo $this->Form->label('Model.field', null, array('class' => 'control-label'));
echo '<div class="controls">';
echo $this->Form->checkbox('Model.field');
echo '</div>';
echo '</div>';
Try following code:
<div class="control-group">
<div class="controls">
<label class="checkbox">
<?php echo $this->Form->input('auto_login', array('type'=>'checkbox','label' => false, 'div' => false,'class'=>false,'after'=>__('Keep me logged in')));?>
</label>
</div>
</div>
If you're using security component, you may have problems if you create your inputs without FormHelper::input. If that's the case, you should try with this:
echo "
<div class='control-group'>
<div class='controls'>
<label class='checkbox'>";
echo $this->Form->input('Model.field', array('label' => false, 'after' => 'Model.field'))."
</label>
</div>
</div>";
Here is the ready-to-use solution:
App::uses('FormHelper', 'View/Helper');
class InputHelper extends FormHelper {
// var $helpers = array('Form', 'Html');
public function create($model, $options = array()) {
$options['class'] = (isset($options['class']) && $options['class']) ? $options['class'] : 'form-horizontal table';
$options['inputDefaults'] = (isset($options['inputDefaults']) && $options['inputDefaults']) ? $options['inputDefaults'] : array(
'div' => 'control-group',
'label' => array('class' => 'control-label'),
'between' => '<div class="controls">',
'after' => '</div>'
);
return parent::create($model, $options);
}
public function input($fieldName, $options = array()) {
$this->setEntity($fieldName);
$options = $this->_parseOptions($options);
if ($options['type'] == 'checkbox') {
$options['format'] = array('before', 'label', 'between', 'input', 'after', 'error');
}
fdebug($options);
return parent::input($fieldName, $options);
}
}
If you want a "one line" answer i got it:
echo $this->Form->input('Model.Field', array('class'=>'form-inline', 'after'=>'</br>'));
In my case, I used AdminLTE template with Bootstrap 3 and this code was working for me:
<?php
echo $this->Form->input('Model.fieldname', array(
'label' => false,
'type' => 'checkbox',
'before' => '<label>',
'after' => 'Field name label here</label>',
));
?>
Good luck here!!!
Here's a simple solution that works for me:
The CSS (LESS):
input.form-control[type="checkbox"] {
width: auto;
height: auto;
margin-right: 5px;
display: inline;
}
Then use the Form helper:
echo $this->Form->input(
'field_name',
array(
'div' => 'form-group',
'class' => 'form-control',
'type' => 'checkbox',
'label' => array(
'text' => 'Your label',
'class' => 'label-checkbox'
),
'format' => array('input', 'label')
)
);

cakephp pagination with count issue

I have written below code in my controller action.
$this->paginate['Tag'] = array(
'fields' => array('COUNT(tag_id) AS numbers', 'tag', 'slug'),
'limit' => 50,
'order' => 'numbers desc',
'recursive' => 2,
'group' => array('tag'),
);
$tags = $this->paginate('Tag', array('not' => array('site_id' => NULL), 'tag !=' => ''));
And written below code in the .ctp file.
<div class="row section">
<div class="col col_16 pagination">
<h3>Tags</h3>
<?php
foreach ($tags as $key => $tag) {
echo '<span>' . $this->Html->link($tag['Tag']['tag'] . ' (' . $tag[0]['numbers'] . ')', '/tags/' . $tag['Tag']['slug']) . '</span>';
}
?>
</div>
<div class="col col_16 pagination">
<?php
echo $this->Paginator->first('First', null, null, array('class' => 'disabled'));
echo $this->Paginator->prev('Previous', null, null, array('class' => 'disabled'));
echo $this->Paginator->numbers(array('separator' => ''));
echo $this->Paginator->next('Next', null, null, array('class' => 'disabled'));
echo $this->Paginator->last('Last', null, null, array('class' => 'disabled'));
?>
</div>
<div class="col col_16 pagination">
<h5 class="margin0Px">
<?php
echo $this->Paginator->counter(array(
'format' => __('Page %page% of %pages%, showing %current% out of %count% total, starting on %start%, ending on %end%.', true)
));
?>
</h5>
</div>
</div>
Getting false result in view $this->Paginator.
What is the issue here? I am not getting any idea. Pls help.
Does you controller define the helpers variable? If it doesn't the Paginator helper is included by default. If it does you have to remember to include it yourself.
Documentation: http://book.cakephp.org/1.3/en/view/1096/Using-Helpers

Resources