I'm new to cakePHP, so I may be missing something obvious.
I have an add form that was working and saving to the database, and suddenly stopped. I didn't think I added anything significant, mostly just styling stuff...unfortunately my last backup was before I had finished the add function, so I don't have a way to go back to when it worked. If anyone can take a look and see where I'm going wrong, I would appreciate it!
My Task model:
App::uses('AuthComponent', 'Controller/Component');
class Task extends AppModel {
public $belongsTo = 'User';
public $validate = array(
'task_name' => array(
'custom' => array(
'rule' => array('custom', '/^[a-z0-9 ]*$/i'),
'required' => true,
'message' => 'This field accepts letters and numbers only.'
),
'maxLength' => array(
'rule' => array('maxLength', 50),
'message' => 'Task name cannot exceed 50 characters'
)
),
'frequency' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'allowEmpty' => true
)
),
'day' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'allowEmpty' => true
)
),
'user_id' => array(
'numeric' => array(
'rule' => 'numeric'
)
),
'month_type' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'required' => false
)
),
'month_number' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'required' => false
)
),
'month_day' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'allowEmpty' => true
)
),
'day_number' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'required' => false
)
)
);
}
The add function from my TasksController file:
public function add() {
if ($this->request->is('post')) {
$this->Task->create();
if ($this->Task->save($this->request->data)) {
$this->Session->setFlash(__('Task saved!'));
$this->redirect(array('action' => 'index'));
}
else {
$this->Session->setFlash(__('The task could not be saved'));
}
}
}
And the form from my tasks/add.ctp file:
<?php
echo $this->Form->create('Task',array('class' => 'taskForm'));
$userId = $this->Session->read('Auth.User.id');?>
<fieldset>
<legend class="welcomeText"><?php echo __('Add a Task'); ?></legend>
<?php
echo $this->Form->hidden('user_id', array('value' => $userId));
echo $this->Form->input('task_name', array('label' => 'Task Name', 'maxLength' => 50));
//set frequency
echo "<p>How often should this task be done?</p>";
$options = array('unset' => 'Decide Later','daily' => 'Daily','weekly' => 'Weekly','monthly' => 'Monthly');
$attributes = array('value' => 'unset','separator' => '<br/>','class' => 'frequencyRadio','legend' => false);
echo $this->Form->radio('frequency', $options, $attributes);
//optional answers
//if "weekly" is selected
echo "<div id=\"weeklyRadio\" >";
echo "<p>Set a day of the week for this task?</p>";
$options = array('unset' => 'Decide later','monday' => 'Monday','tuesday' => 'Tuesday','wednesday' => 'Wednesday',
'thursday' => 'Thursday','friday' => 'Friday','saturday' => 'Saturday','sunday' => 'Sunday');
$attributes = array('value' => 'unset','separator' => '<br/>','class' => 'weeklyRadio','legend' => false);
echo $this->Form->radio('day',$options,$attributes);
echo "</div>";
//if "monthly" is selected
?>
<div id="monthlyRadio">
<p>Schedule this task?</p>
<input type="radio" name="data[Task][month_type]" id="TaskMonthTypeUnset"
value="unset" class="monthlyRadio" required="required" checked="checked" />
<label for="TaskMonthTypeUnset">Decide later</label><br/>
<input type="radio" name="data[Task][month_type]" id="TaskMonthTypeNumber"
value="number" class="monthlyRadio" required="required" />
<label for="TaskMonthTypeNumber">
<?php
echo "On the ";
$options = array(1 => '1st',2 => '2nd',3 => '3rd',4 => '4th',5 => '5th',6 => '6th',7 => '7th',8 => '8th',9 => '9th',
10 => '10th',11 => '11th',12 => '12th',13 => '13th',14 => '14th',15 => '15th', 16 => '16th',
17 => '17th',18 => '18th',19 => '19th',20 => '20th',21 => '21st',22 => '22nd',23 => '23rd',
24 => '24th',25 => '25th',26 => '26th',27 => '27th',28 => '28th',29 => '29th',30 => '30th',31 => '31st');
echo $this->Form->select('month_number',$options,array('value' => null));
echo " of the month";
?>
</label><br/>
<input type="radio" name="data[Task][month_type]" id="TaskMonthTypeDay" value="day" class="monthlyRadio" required="required" />
<label for="TaskMonthTypeDay">
<?php
echo "On the ";
$options = array(1 => '1st',2 => '2nd',3 => '3rd',4 => '4th',5 => '5th',6 => 'last');
echo $this->Form->select('day_number',$options,array('value' => null));
echo " ";
$options = array('monday' => 'Monday','tuesday' => 'Tuesday','wednesday' => 'Wednesday',
'thursday' => 'Thursday','friday' => 'Friday','saturday' => 'Saturday','sunday' => 'Sunday');
echo $this->Form->select('month_day',$options,array('value' => null));
echo " of the month";
?>
</label>
</div>
<?php
echo $this->Form->submit('Add Task', array('class' => 'formSubmit', 'title' => 'Create Task') );
?>
</fieldset>
<?php echo $this->Form->end(); ?>
There is also a javascript file that shows and hides the optional radio buttons, but I assume that wouldn't have anything to do with why it stopped saving to the database.
When I click the "Add Task" button on the form, it doesn't do anything at all (doesn't save to the database, and doesn't redirect to the index.ctp view like it used to). No idea what I'm missing here!
UPDATE
Fixed the problem! The places in my form where I specified a default value of null, it was passing an empty string. The data model was expecting numeric values for 'month_number' and 'day_number,' so it wasn't processing.
I fixed it by adding 0 => '' to the selection list, and specifying 0 as the default value, and now it works fine.
Thanks for the help!
I don't see errors in your code.
Add this in the controller add and make a debug for more information about what happens.
public function add() {
$this->loadModel('Task');
debug($this->request->is('post')); //try this first
//debug($this->request); //after try this
if ($this->request->is('post')) {
$this->Task->create();
if ($this->Task->save($this->request->data)) {
$this->Session->setFlash(__('Task saved!'));
$this->redirect(array('action' => 'index'));
}
else {
$this->Session->setFlash(__('The task could not be saved'));
}
}
}
loadModel adds this. update your question with that display the debug, and I update mi answer.
It looks like you have the submit form button assigned to a different class, which is why its not firing the form.
echo $this->Form->submit('Add Task', array('class' => 'formSubmit', 'title' => 'Create Task') );
Try changing it to either of the following
echo $this->Form->submit('Add Task', array(
'class' => 'taskForm',
'title' => 'Create Task'));
echo $this->Form->button('Add Task', array(
'class' => 'taskForm',
'title' => 'Create Task',
'action' => 'submit;));
or amend the form ending tag to see if it fires properly.
Change this
echo $this->Form->end();
to
echo $this-Form->end('Submit');
Related
In my view I have
<?= $this->Form->create('Asc201516', array(
'url' => array(
'controller' => 'asc201516s',
'action' => 'submit_asc201516'
),
'class' => 'form-inline',
'onsubmit' => 'return check_minteacher()'
)); ?>
<div class="form-group col-md-3">
<?= $this->Form->input('bi_school_na', array(
'type' => 'text',
'onkeypress' => 'return isNumberKey(event)',
'label' => 'NA',
'placeholder' => 'NA',
'class' => 'form-control'
)); ?>
</div>
<?php
$options = array(
'label' => 'Submit',
'class' => 'btn btn-primary');
echo $this->Form->end($options);
?>
In my Controller, I have
$this->Asc201516->set($this->request->data['Asc201516']);
if ($this->Asc201516->validates()) {
echo 'it validated logic';
exit();
} else {
$this->redirect(
array(
'controller' => 'asc201516s',
'action' => 'add', $semisid
)
);
}
In my Model, I have
public $validate = array(
'bi_school_na' => array(
'Numeric' => array(
'rule' => 'Numeric',
'required' => true,
'message' => 'numbers only',
'allowEmpty' => false
)
)
);
When I submit the form, logically it should not get submitted and print out the error message but the form gets submitted instead and validates the model inside controller which breaks the operation in controller.
You have to check validation in your controller like
$this->Asc201516->set($this->request->data);
if($this->Asc201516->validates()){
$this->Asc201516->save($this->request->data);
}else{
$this->set("semisid",$semisid);
$this->render("Asc201516s/add");
}
You will have your ID there in variable $semisid, or you can set data in $this->request->data = $this->Asc201516->findById($semisid);
I am having trouble submitting/saving data to the CakePHP Model. I constructed the form as usual as I always do, but this time I am getting notices and warning an also data is not getting saved. Here is the form I have constructed and method in Controller:
educationaldetails.ctp
<?php
if (empty($Education)):
echo $this->Form->create('Candidate', array('class' => 'dynamic_field_form'));
echo $this->Form->input('CandidatesEducation.0.candidate_id', array(
'type' => 'hidden',
'value' => $userId
));
echo $this->Form->input('CandidatesEducation.0.grade_level', array(
'options' => array(
'Basic' => 'Basic',
'Masters' => 'Masters',
'Doctorate' => 'Doctorate',
'Certificate' => 'Certificate'
)
));
echo $this->Form->input('CandidatesEducation.0.course');
echo $this->Form->input('CandidatesEducation.0.specialization');
echo $this->Form->input('CandidatesEducation.0.university');
echo $this->Form->input('CandidatesEducation.0.year_started', array(
'type' => 'year'
));
echo $this->Form->input('CandidatesEducation.0.year_completed', array(
'type' => 'year'
));
echo $this->Form->input('CandidatesEducation.0.type', array(
'options' => array(
'Full' => 'Full',
'Part-Time' => 'Part-Time',
'Correspondence' => 'Correspondence'
)));
echo $this->Form->input('CandidatesEducation.0.created_on', array(
'type' => 'hidden',
'value' => date('Y-m-d H:i:s')
));
echo $this->Form->input('CandidatesEducation.0.created_ip', array(
'type' => 'hidden',
'value' => $clientIp
));
echo $this->Form->button('Submit', array('type' => 'submit', 'class' => 'submit_button'));
echo $this->Form->end();
endif;
CandidatesController.php
public function educationaldetails() {
$this->layout = 'front_common';
$this->loadModel('CandidatesEducation');
$Education = $this->CandidatesEducation->find('first', array(
'conditions' => array(
'candidate_id = ' => $this->Auth->user('id')
)
));
$this->set('Education', $Education);
// Checking if in case the Candidates Education is available then polpulate the form
if (!empty($Education)):
// If Form is empty then populating the form with respective data.
if (empty($this->request->data)):
$this->request->data = $Education;
endif;
endif;
if ($this->request->is(array('post', 'put')) && !empty($this->request->data)):
$this->Candidate->id = $this->Auth->user('id');
if ($this->Candidate->saveAssociated($this->request->data)):
$this->Session->setFlash('You educational details has been successfully updated', array(
'class' => 'success'
));
return $this->redirect(array(
'controller' => 'candidates',
'action' => 'jbseeker_myprofile',
$this->Auth->user('id')
));
else:
$this->Session->setFlash('You personal details has not been '
. 'updated successfully, please try again later!!', array(
'class' => 'failure'
));
endif;
endif;
}
Here is the screenshot of errors I am getting, Not able to figure out what is happening while other forms are working correctly. looks like something something wrong with view?
This error is coming out because you are not passing the proper arguments to the session->setFlash() method, you are doing like this:
$this->Session->setFlash('You personal details has not been updated successfully, please try again later!!', array(
'class' => 'failure'
));
In docs it is mentioned like:
$this->Session->setFlash('You personal details has not been updated successfully, please try again later!!',
'default', array(
'class' => 'failure'
));
Hi so if i understand :
array(
'CandidatesEducation' => array(
(int) 0 => array(
'candidate_id' => '5',
'grade_level' => 'Basic',
'course' => 'Masters of Computer Application',
'specialization' => '',
'university' => 'Mumbai University',
'year_started' => array(
'year' => '2011'
),
'year_completed' => array(
'year' => '2014'
),
'type' => 'Full',
'created_on' => '2014-11-27 15:44:36',
'created_ip' => '127.0.0.1'
)
)
),
Is your data , and you just need to save this in your candidates_educations table , so in this case i would do :
$this->Candidate->CandidatesEducation->save($this->request->data);
and your $data had to look :
array(
'CandidatesEducation' => array(
'candidate_id' => '5',
'grade_level' => 'Basic',
'course' => 'Masters of Computer Application',
'specialization' => '',
'university' => 'Mumbai University',
'year_started' => array(
'year' => '2011'
),
'year_completed' => array(
'year' => '2014'
),
'type' => 'Full',
'created_on' => '2014-11-27 15:44:36',
'created_ip' => '127.0.0.1'
)
);
the saveAssociated is used when you create your Model AND Model associated , not only your Associated model.
And : i m not sure for year_started and year completed rm of data, it depends of your table schema ; what's the type of year_completed and year_started ?
I have some problem with Cakephp 2 validation.
I am trying to validate several fields on an Edit form. Some of them are a password and confirm password fields.
I want to validate both only if they are supplied. If they are empty I dont change the password, but if the user writes over them I would like to validate if they have a minLength or the passwords matchs.
Code:
'pwd' => array(
'length' => array(
'rule' => array('between', 8, 40),
'message' => 'Your password must be between 8 and 40 characters.',
'allowEmpty' => true
),
),
'pwd_repeat' => array(
'length' => array(
'rule' => array('between', 8, 40),
'message' => 'Your password must be between 8 and 40 characters.',
'allowEmpty' => true
),
'compare' => array(
'rule' => array('validate_passwords'),
'message' => 'The passwords you entered do not match.',
'allowEmpty' => true
),
I dont know if I have to define some rules on edit() function in the controller or it should be enough, but my code is not working.
Thanks!
Edit: (Controller Code)
public function edit($id = null) {
if (!$this->User->exists($id)) {
throw new NotFoundException(__('Usuario incorrecto'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('El usuario ha sido actualizado.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('El usuario no ha podido actualizarse. Por favor, inténtelo de nuevo.'));
}
unset($this->request->data['User']['pwd']);
unset($this->request->data['User']['pwd_repeat']);
} else {
$options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
$this->request->data = $this->User->find('first', $options);
}
$roles = $this->User->Role->find('list');
$this->set(compact('roles'));
}
(View Code)
<div id="contenedor" class="users form">
<?php echo $this->Form->create('User', array('name' => 'form')); ?>
<fieldset>
<legend><?php echo __('Editar Usuario'); ?></legend>
<?php
echo $this->Form->input('id');
echo $this->Form->input('username', array('label' => __('Usuario')));
echo $this->Form->input('pwd', array('label' => __('Contraseña'), 'type' => 'password', 'name' => 'pass', 'onKeyUp' => 'habilita()', 'value' => ''));
echo $this->Form->input('pwd_repeat', array('label' => __('Repite Contraseña'), 'type' => 'password', 'name' => 'rpass', 'disabled' => 'disabled'));
echo $this->Form->input('firstname', array('label' => __('Nombre')));
echo $this->Form->input('lastname', array('label' => __('Apellidos')));
echo $this->Form->input('telephone', array('label' => __('Teléfono')));
echo $this->Form->input('email', array('label' => __('Email')));
echo $this->Form->input('role_id', array('label' => __('Rol')));
?>
</fieldset>
<?php echo $this->Form->end(__('Aceptar')); ?>
Make the validation rules like this
'pwd' => array(
'length' => array(
'rule' => array('between', 8, 40),
'message' => 'Your password must be between 8 and 40 characters.',
),
),
'pwd_repeat' => array(
'length' => array(
'rule' => array('between', 8, 40),
'message' => 'Your password must be between 8 and 40 characters.',
),
'compare' => array(
'rule' => array('validate_passwords'),
'message' => 'The passwords you entered do not match.',
)
)
And your validate_passwords function should be like this.
public function validate_passwords() {
return $this->data[$this->alias]['pwd'] === $this->data[$this->alias]['pwd_repeat']
}
I'm using a form with multiplefields with the same name. After a false validation of the form i return to it with the validation messages. That all works. While the validation messages of the fields are shown correct, the entered data in the fields are gone.
Its cakephp 2.2 application without a database.
(saving the data to a session for 3 pages then write it to XML)
step2.ctp:
debug($this->Form);
echo $this->Form->input('Invoice.0.InvoiceOrderNumber', array('label' => false));
echo $this->Form->input('Invoice.0.NetAmount', array('label' => false));
echo $this->Form->input('Invoice.0.CostBearer', array('label' => false));
echo $this->Form->input('Invoice.0.CostCenter', array('label' => false));
echo $this->Form->input('Invoice.0.LedgerAccount', array('label' => false));
Controller:
public function step2() {
$invoice = $this->Session->read('Invoice');
if (!isset($invoice) && is_array($invoice))
$this->redirect(array('action' => 'step1'));
else
{
$this->set('title_for_layout', 'Nieuwe interne doorbelasting');
if ($this->request->is('post')) {
debug($this->request->data);
if ($this->Invoice->validateMany($this->request->data['Invoice']))
{
if ($this->Session->write('Invoice', $this->request->data['Invoice'])) {
$this->Session->setFlash(__('The invoice has been saved'));
$this->redirect(array('action' => 'step3'));
} else {
$this->Session->setFlash(__('The invoice could not be saved. Please, try again.'));
}
}
}
}
}
debug of ($this->Form) in step2.ctp:
.....
request => object(CakeRequest) {
params => array(
'plugin' => null,
'controller' => 'invoices',
'action' => 'step2',
'named' => array(),
'pass' => array(),
'models' => array(
'Invoice' => array(
'plugin' => null,
'className' => 'Invoice'
)
)
)
data => array(
'Invoice' => array(
(int) 0 => array(
'Invoice' => array(
'InvoiceOrderNumber' => 'adfas',
'NetAmount' => '2',
'CostBearer' => '',
'CostCenter' => '',
'LedgerAccount' => ''
)
),
(int) 1 => array(
'Invoice' => array(
'InvoiceOrderNumber' => 'adaaaaaaaaa',
'NetAmount' => 'bbbbbbbbb',
'CostBearer' => '',
'CostCenter' => '',
'LedgerAccount' => ''
)
)
)
)
....
So the data is there, but cake doesn't put it in the fields. But i can't figger out why...
I found the solution after the hint. Validation indeed changes the data. Theres a warning in the model i missed: "* Warning: This method could potentially change the passed argument $data, * If you do not want this to happen, make a copy of $data before passing it * to this method"
So my solution:
$invoiceData = $this->request->data['Invoice'];
if ($this->Invoice->validateMany($this->request->data['Invoice']))
{
...
}
$this->request->data['Invoice'] = $invoiceData;
Try this:
$this->Form->create('Invoice');
$this->Form->input('0.OrderNumber');
$this->Form->input('0.NetAmount');
...
$this->Form->input('1.OrderNumber');
$this->Form->input('1.NetAmount');
My application has contacts controller with add action which able to post contacts message to the database table comments. It works fine with its validation.
Now I want to use the add view (The contacts form) as a global form to be rendered in all pages of the application.
I know, to do that, I have to make an element contains the form (or the add view) as follows:
elements/contact.ctp
<div class="panel">
<h4><?php echo __('contact'); ?></h4>
<?php echo $form->create('Contact',array('action'=>'index', 'class' => ''));?>
<?php echo $form->input('name', array('size' => 45, 'class' => 'input-text', 'label' => array( 'text' => __('name',true).'<sup>*</sup>'), 'error' => array('class' => 'error', 'wrap' => 'small')));?>
<?php echo $form->input('email', array('size' => 45, 'class' => 'input-text', 'label' => array('text' => __('email',true).'<sup>*</sup>'), 'error' => array('class' => 'error', 'wrap' => 'small')));?>
<?php echo $form->input('subject', array('type' => 'select', 'options' => array(null => __('choose subject',true), 'g' => __('general', true), 'r' => __('report', true)), 'class' => 'input-text', 'label' => array('text' => __('subject', true).'<sup>*</sup>'),'error' => array('class' => 'error', 'wrap' => 'small'))); ?>
<?php echo $form->input('content', array('class' => 'input-text', 'style' => 'height: 140px', 'title' => __('message', true), 'label' => array('text' => __('message',true).'<sup>*</sup>'), 'error' => array('class' => 'error', 'wrap' => 'small')));?>
<?php //echo $fck->load('Contact.message','Mini'); ?>
<span>
<?php
App::import('Vendor','FoxCaptcha', array('file' => 'Fox_captcha.php'));
$cap = new Fox_captcha(120,30,5);
$cap->image_dir = $html->url('/').'img/';
$cap->lines_amount = 13;
$cap->en_reload = $html->image('reload.png', array('alt' => __('reload', true), 'title' => __('reload the captcha', true), 'id' => 'frel', 'style' => 'vertical-align:middle'));
?>
</span>
<div>
<span class="display:inline"><?php echo $cap->make_it('HTML');?></span>
<?php echo $form->input('vcode', array('size' => 45, 'class' => 'small input-text', 'label' => array('text' => __('captcha', true).'<sup>*</sup>'), 'error' => array('class' => 'error', 'wrap' => 'small')));?>
</div>
<?php echo $form->submit(__('send',true), array('class' => 'nice medium radius white button'));?>
<?php echo $form->end();?>
<div class="alert-box warning"><?php echo __('fields label with * are required');?></div>
</div>
The problem is: When I use this form from any page (for example posts/view/22) it submits to contacts/add. I want after submit posts/view/22 is rendered with any validation message triggered.
There is no solution for this requirement without Ajax and JSON. It includes submitting the form with Ajax to the contacts controller index action with event handler component activated and then check isAjax then render JSON output retrieved by the post's view and then populates the results.