I want to make a validation form in cakephp my code form is:
view
<div class="well">
<?php
echo $this->Form->create(false);
echo $this->Form->input('name', array('label' => 'name '));
echo $this->Form->input('PHONE_NUMBER', array('label' => 'PHONE_NUMBER '));
echo $this->Form->input('EMAIL', array('label' => 'EMAIL '));
echo $this->Form->input('ISSUE', array('label' => 'ISSUE '));
echo $this->Form->input('IP', array('label' => 'IP '));
echo $this->Form->submit('Send.');
?>
Controller
<?php
class ContactController extends AppController {
public function index() {
if (empty($_POST) === FALSE) {
$message = '';
$message .=$_POST['data']['EMAIL'] . ' <br/>';
$message .=$_POST['data']['name'] . ' <br/>';
$message .=$_POST['data']['PHONE_NUMBER'] . ' <br/>';
$message .=$_POST['data']['ISSUE'] . ' <br/>';
$message .=$_SERVER['REMOTE_ADDR'] . ' <br/>';
mail('mohmed#lcegy.com', 'Support From Website ', $message);
$this->Session->setFlash("Thanks , an email just sent .");
}
}
}
My question is how to implement validation in this form and how to get the IP address of the visitor?
You may want to update your index() function to look something similar to this: I think it's more of the cakePHP convention.
public function index() {
if ($this->request->is('post')) {
$message = '';
$message = $this->request->data['EMAIL'];
...
}
}
For validation, you can add that to your model. You could do something similar:
public $validate = array(
'EMAIL' => 'email',
'name' => array(
'rule' => 'alphaNumeric',
'required' => true
)
);
For more validation, you can look at the documentation: http://book.cakephp.org/2.0/en/models/data-validation.html
You can use $_SERVER['REMOTE_ADDR'] to get the client's IP Address.
You Can Do Validation From Your Model by setting Rules as follows
public $validate =
array(
'Email' => array
(
'rule' => 'notempty'
),
);
Best way to do it by model as above given answers but you can also do it at view page by simply adding attributes "require" and define proper types like emails, numbers. eg. in your form:
<?php
echo $this->Form->create(false);
echo $this->Form->input('name', array('label' => 'name ', 'required' => true));
echo $this->Form->input('PHONE_NUMBER', array('label' => 'PHONE_NUMBER ', 'required' => true,'type'=>'number'));
echo $this->Form->input('EMAIL', array('label' => 'EMAIL ', 'required' => true, 'type' => 'email'));
echo $this->Form->input('ISSUE', array('label' => 'ISSUE ', 'required' => true));
echo $this->Form->input('IP', array('label' => 'IP ', 'required' => true));
echo $this->Form->submit('Send.');
?>
Related
How do I make it so that when I go through with error validation on my post form, it doesn't only send back the default values from the database, but if I were to edit the values and hit submit, it would save the data I tried to update with. I'm stuck where I can only do one or the other.
<? if (isset($update)) { ?>
<?php echo set_value ('fname'); ?>
<?= form_open("Phonebook/updateentry/" . $entry['id']) ?>
<?= form_fieldset("Update Entry"); ?>
<?= form_label('First Name: ', 'fname'); ?> <br>
<?= form_input(array('name' => 'fname', 'id' => 'fname', 'value' => $entry['fname'])); ?> <br>
<?= form_label('Last Name: ', 'lname'); ?> <br>
<?= form_input(array('name' => 'lname', 'id' => 'lname', 'value' => $entry['lname'])); ?> <br>
<?= form_label('Phone Number: ', 'phone'); ?> <br>
<?= form_input(array('name' => 'phone', 'id' => 'phone', 'value' => $entry['phone'])); ?> <br>
<?= form_label('Email: ', 'email'); ?> <br>
<?= form_input(array('name' => 'email', 'id'=>'email', 'value' => $entry['email'])); ?> <br>
<?= form_submit('phonebooksubmit', 'Submit'); ?>
<?= form_fieldset_close(); ?>
<?= form_close() ?>
<? } ?>
private function display()
{
$query = $this->db->query("SELECT * FROM phonebook ORDER BY id ASC;");
$this->TPL['listing'] = $query->result_array();
$this->load->view('phonebook_view', $this->TPL);
}
public function updateentry($id)
{
$this->form_validation->set_rules('fname', 'First Name', 'required|alpha|min_length[5]|max_length[15]',
array(
'required' => 'You have not provided the %s. ',
'alpha' => '%s must only compose of alphanumeric letters.',
'max_length' => 'You exceeded max char of 20 . ',
'min_length' => 'The min length must be 5 . '
));
$this->form_validation->set_rules('lname', 'Last Name', 'required|alpha|min_length[5]|max_length[20]',
array(
'required' => 'You have not provided %s .',
'alpha' => '%s must only compose of alphanumeric letters.',
'max_length' => 'You exceeded max char of 20 . ',
'min_length' => 'The min length must be 5 . '
));
$this->form_validation->set_rules('phone', 'Phone Number', 'required|regex_match[/^([0-9]{3})[-. ]([0-9]{4})$/]',
array(
'required' => 'You have not provided %s .',
'regex_match' => 'Please use the correct phone format.'
));
$this->form_validation->set_rules('email', 'Email', 'required|valid_email',
array(
'required' => 'You have not provided %s .',
'valid_email' => 'Please provide valid email. '
));
$this->form_validation->set_error_delimiters('<p class = "errorlist">' , '</p>');
if ($this->form_validation->run() == FALSE) {
$query = $this->db->query("SELECT * FROM phonebook where id = '$id';");
$this->TPL['entry'] = $query->result_array()[0];
$this->TPL['update'] = true;
$this->TPL['memory'] = true;
$this->display();
}
else
{
$fname = $this->input->post("fname");
$lname = $this->input->post("lname");
$phone = $this->input->post("phone");
$email = $this->input->post("email");
$query = $this->db->query("UPDATE phonebook " .
"SET fname = '$fname'," .
" lname = '$lname'," .
" phone = '$phone'," .
" email = '$email'" .
" WHERE id = '$id';");
$this->display();
}
}
I know I have to use the set_value() but i'm not sure how to make it so that it can do both.
set_value has a second parameter, which is the default. In the case of you pulling up records and editing them, it looks like this:
// $data is from your database
set_value('name', $data['name'])
I used "name" as an example, but this could be any field in your record.
But back in your controller, you'd want something like this:
if( $this->input->method == 'POST' )
// Do your validation and updating to the record
// Then pull in the record for your view
$view_data['data'] = $this->db->query('... ... ...');
By doing this, you're always pulling in the fresh data
Your code looks pretty solid.
I would suggest to try adding a
$this->db->update(.......)
at the end of your function.
Then the database gets updated with up-to-the-second info.
Hope this helps.
Hew I wrote common bootstrap css for form fields.But is applying to hidden fields also.How do I restrict for hidden fields in cakephp 3.x bootstrap.
$myTemplates = [
//'nestingLabel' => '<label{{attrs}}>{{text}}</label>{{input}}{{hidden}}',
'inputContainer' => '<div class="form-group order-status">{{content}}</div>',
'checkboxContainer' => '<div class="checkbox">{{content}}</div>',
'label' => '<label class="col-sm-2">{{text}}</label>',
'input' => '<div class="col-md-3"><input type="{{type}}" name="{{name}}" class="form-control" {{attrs}} /></div>',
'select' => '<div class="col-md-3"><select name="{{name}}"{{attrs}} class="form-control">{{content}}</select></div>',
'textarea'=> '<div class="col-md-8"><textarea name="{{name}}" {{attrs}} class="form-control"></textarea></div>',
];
$this->Form->templates($myTemplates);?>
<fieldset>
<legend><?php echo __('{0} Promotion', $edit ? 'Edit' : 'Add'); ?></legend>
<?php
if($edit) {
echo $this->Form->hidden('id');
echo $this->Form->input('active', array('type' => 'checkbox','div'=>false));
} else {
echo $this->Form->input('active', array('type' => 'checkbox','checked' => true));
}
echo $this->Form->input('name');
echo $this->Form->input('description');
if($edit) {
echo $this->Form->input('promotion_type', array('type' => 'select', 'options' => Configure::read('Sidecart.ModelOptions.Promotion.promotion_types'), 'empty' => '-- Select One --', 'disabled' => true));
echo $this->Form->hidden('promotion_type');
} else {
echo $this->Form->input('promotion_type', array('type' => 'select', 'options' => Configure::read('Sidecart.ModelOptions.Promotion.promotion_types'), 'empty' => '-- Select One --'));
}
?>
In CakePHP 3.0, you can do this with Widgets.
Create src\View\Widget\HiddenWidget.php:
<?php
namespace App\View\Widget;
use Cake\View\Widget\BasicWidget;
use Cake\View\Form\ContextInterface;
use Cake\View\Widget\WidgetInterface;
class HiddenWidget extends BasicWidget implements WidgetInterface {
public function render(array $data, ContextInterface $context) {
$data += [
'name' => '',
];
return $this->_templates->format('hidden' /* <-- Define the template name */, [
'name' => $data['name'],
'attrs' => $this->_templates->formatAttributes($data, ['name'])
]);
}
}
Then in a view file:
<?php
$templates = [ // Define your templates
'hidden' => '<input type="hidden" name="{{name}}"{{attrs}}/>',
'input' => '<div class="col-md-3">' .
'<input type="{{type}}" name="{{name}}" class="form-control" {{attrs}}/>' .
'</div>'
];
$this->Form->templates($templates); // Update the templates in FormHelper
$this->Form->addWidget('hidden', ['Hidden']); // Add the HiddenWidget to FormHelper
echo $this->Form->hidden('id'); // Renders with the 'hidden' template
echo $this->Form->input('name'); // Renders with the 'input' template
Conversely, you may want to do the opposite and create BsFormControlWidget(s) instead. This way, the input fields (hidden and visible) keep their "out-of-the-box" functionality. Your custom implementation would sit alongside -Cake, in general, seems to prefer being built "on-top-of" rather than morphed. Plus your widgets would now be more easily reusable in other projects.
Here is my validation rule in User.php
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'User name is required'
),
'alphaNumeric'=>array(
'rule' => 'alphaNumeric',
'required' => true,
'message' => 'Alphabets and numbers only'
)
))
and this is my view page code
<?php
echo $this->Form->create('User');
echo $this->Form->input('username', array('label' => 'Username'));
echo $this->Form->input('email', array('label' => 'Email'));
echo $this->Form->input('password', array('label' => 'Password'));
echo $this->Form->submit('Sign Up');
echo $this->Form->end();
?>
Here is my controller code
public function register() {
$this->layout = 'starter';
//debug($this->validationErrors);
if ($this->request->is('post')) {
if ($this->User->validates()) {
$this->User->save($this->request->data);
$this->Session->setFlash(__('Please login your account'));
$this->redirect('/users/login');
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
}
}
but validation message is not showing. What is wrong in my code?...
Your code is wrong.
if ($this->request->is('post')) {
if ($this->User->validates()) {
$this->User->save($this->request->data);
this is not how it could ever work as the data is not passed prior to validation.
You need to first pass the data, then validate, then optionally save (or save and validate together):
if ($this->request->is('post')) {
if ($this->User->save($this->request->data)) {}
or, careful not to retrigger validation twice:
if ($this->request->is('post')) {
$this->User->set($this->request->data);
if ($this->User->validates()) {
$success = $this->User->save(null, array('validate' => false));
But that is documented.
The latter only makes sense if you really need to do this in two steps.
In your comment you have written you have changed layout page.It may you miss
<?php echo $this->Session->flash(); ?>
this line.Add this line in your view/layouts/yourlayout.ctp file.
Disable HTML5 required in your view page code
<?php
echo $this->Form->create('User');
echo $this->Form->input('username', array('label' => 'Username','required'=>'false'));
echo $this->Form->input('email', array('label' => 'Email','required'=>'false'));
echo $this->Form->input('password', array('label' => 'Password','required'=>'false'));
echo $this->Form->submit('Sign Up');
echo $this->Form->end();
?>
i want to validate 2 date input in codeigniter, with the conditions, if the end date is greater than the start date, will appear warning [javascript warning or something] or data can't be input
my form like this,
<h1><?php echo $title; ?></h1>
<form action="<?= base_url(); ?>index.php/admin/kalender/buat" method="post" enctype="multipart/form-data" name="form" id="form">
<?php
echo "<p><label for='IDKategori'>Tingkatan Pimpinan :</label><br/>";
echo form_dropdown('IDKategori', $kategori) . "</p>";
echo "<label for='ptitle'>Kegiatan / Lokasi :</label><br/>";
$data = array('class' => 'validate[required] text-input', 'name' => 'judul', 'id' => 'ptitle', 'size' => 80);
echo form_input($data);
echo "<p><label for='long'>Uraian Kegiatan / Keterangan / Catatan :</label><br/>";
$data = array('class' => 'validate[required] text-input', 'name' => 'konten', 'rows' => '13', 'cols' => '60', 'style' => 'width: 60%');
echo form_textarea($data) . "</p>";
echo "<p><label for='ptitle'>Waktu Mulai :</label><br/>";
$data = array('class' => 'validate[required] text-input', 'name' => 'TanggalMulai', 'id' => 'basic_example_1');
echo form_input($data) . "</p>";
echo "<p><label for='ptitle'>Waktu Akhir :</label><br/>";
$data = array('class' => 'validate[required] text-input', 'name' => 'TanggalAkhir', 'id' => 'basic_example_2');
echo form_input($data) . "</p>";
echo form_submit('submit', 'Tambah Even');
?>
<input type="button" value="Kembali" onClick="javascript: history.go(-1)" />
how to validate in form "Waktu Akhir & Waktu Mulai" ?
Try this. It is by using CI validation library.
It uses callback type of validation.
Put this in if(isset($_POST['submit_button_name'])) {} section.
First, load validation array,
$validation = array(
array('field' => 'startDate', 'label' => 'StartDate', 'rules' => 'required|callback_compareDate'),
array('field' => 'endDate', 'label' => 'endDate', 'rules' => 'required|callback_compareDate'),
);
Then load CI validation library as,
$this->form_validation->set_rules($validation);
$this->form_validation->set_message('required', '%s is required.');
This is the called back function.
function compareDate() {
$startDate = strtotime($_POST['startDate']);
$endDate = strtotime($_POST['endDate']);
if ($endDate >= $startDate)
return True;
else {
$this->form_validation->set_message('compareDate', '%s should be greater than Contract Start Date.');
return False;
}
}
The "required" validation makes the fields mandatory to be filled with something.
The callback function, in this case, compares the dates, and further processes the form if start date is less than from date OR flags error otherwise.
Meanwhile, if you want in Jquery you can use this.
var startDate = new Date($('#startDate').val());
var endDate = new Date($('#endDate').val());
if (startDate > endDate){
alert("Start Date should be less than End Date");
return false;
}
This is working code
$params['toDate'] = $this->input->post('toDate', TRUE);
$params['fromDate'] = $this->input->post('fromDate', TRUE);$this->load->model('your_model');
$this->load->library('form_validation');
$this->form_validation->set_data($params);
$startDate = strtotime($params['fromDate']);
$endDate = strtotime($params['toDate']);
if ($endDate >= $startDate):
$this->form_validation->set_rules('fromDate', 'From Date', 'required|trim');
$this->form_validation->set_rules('branchCode', 'Branch Code', 'required|trim');
else:
$json = array(
"success" => false,
"msg" => "Start date must be greater than end date"
);
echo json_encode($json);
die();
endif;
I have a form that requires the user to enter some information. If they fail to complete the required fields they are re-presented with the form; the top of the page notifying them what fields are required and I've enabled sticky forms (set_value()) so their input is not lost.
I'm using flashdata to display messages to the user (i.e., if what they've entered already exists in the database).
My form is in the index method of my controller.
When submit is clicked from my view it calls the add() method in my controller.
The add() method performs the validation and depending on the results either submits to the database or kicks back out to the user to get more data.
I have several issues with the way that i've done this.
1. If validation fails I'm using $this->index() to get back to my form and display the validation errors. If I try using redirect, I lose my validation errors and my $_POST[] data so my sticky forms end up blank.
2. Using $this->index() appends the 'add' to the end of my url
3. Using $this->index() causes issues with the flashdata. Random results.
Any ideas?
<?php
class Restaurant extends Controller {
function Restaurant() {
parent::Controller();
}
function index() {
// Load libraries and models
$this->load->model('/restaurant/mRestaurantTypes');
$this->load->model('/restaurant/mRestaurant');
$this->load->model('/utilities/mUtilities');
// Get states
$stateSelect = array();
$getStates = $this->mUtilities->getStates();
if($getStates->num_rows() > 0) {
foreach($getStates->result() as $row) {
$stateSelect[$row->abbr] = $row->name;
}
}
// Get restaurant types
$restaurantTypes = array();
$getRestaurantTypes = $this->mRestaurantTypes->getRestaurantTypes();
if($getRestaurantTypes->num_rows() > 0) {
foreach($getRestaurantTypes->result() as $row) {
$restaurantTypes[$row->restaurant_types_id] = $row->type;
}
}
// Create form elements
$data['name'] = array(
'name' => 'name',
'id' => 'name',
'value' => set_value('name'),
'maxlength' => '200',
'size' => '50'
);
$data['address'] = array(
'name' => 'address',
'id' => 'address',
'value' => set_value('address'),
'maxlength' => '200',
'size' => '50'
);
$data['city'] = array(
'name' => 'city',
'id' => 'city',
'value' => set_value('city'),
'maxlength' => '50',
'size' => '25'
);
$data['state'] = $stateSelect;
$data['zip'] = array(
'name' => 'zip',
'id' => 'zip',
'value' => set_value('zip'),
'maxlength' => '10',
'size' => '10'
);
$data['phone'] = array(
'name' => 'phone',
'id' => 'phone',
'value' => set_value('phone'),
'maxlength' => '15',
'size' => '15'
);
$data['url'] = array(
'name' => 'url',
'id' => 'url',
'value' => set_value('url'),
'maxlength' => '255',
'size' => '50'
);
$data['type'] = $restaurantTypes;
$data['tags'] = array(
'name' => 'tags',
'id' => 'tags',
'value' => set_value('tags'),
'maxlength' => '255',
'size' => '50'
);
$data['active'] = array(
'name' => 'active',
'id' => 'active',
'value' => 'Y',
'maxlength' => '1',
'size' => '2'
);
// Set page variables
$data_h['title'] = "Add new restaurant";
// Load views
$this->load->view('/template/header', $data_h);
$this->load->view('/restaurant/index', $data);
$this->load->view('/template/footer');
}
/**
* Add the the new restaurant to the database.
*/
function add() {
// Load libraries and models
$this->load->library('form_validation');
$this->load->model('/restaurant/mRestaurant');
// Define validation rules
$this->form_validation->set_rules('name', 'Name', 'trim|required|max_length[255]|xss_clean');
$this->form_validation->set_rules('address', 'Address', 'trim|required|max_length[100]|xss_clean');
$this->form_validation->set_rules('city', 'City', 'trim|required|max_length[128]|xss_clean');
//$this->form_validation->set_rules('state', 'State', 'trim|required');
$this->form_validation->set_rules('zip', 'Zip', 'trim|required|max_length[128]|xss_clean');
$this->form_validation->set_rules('phone', 'Phone', 'trim|required|max_length[10]|xss_clean');
$this->form_validation->set_rules('url', 'URL', 'trim|required|max_length[255]|xss_clean');
$this->form_validation->set_rules('tags', 'Tags', 'trim|xss_clean');
// Form validation
if ($this->form_validation->run() == FALSE) {
// On failure
$this->index();
} else {
// On success, prepare the data
$data = array(
'name' => $_POST['name'],
'address' => $_POST['address'],
'city' => $_POST['city'],
'state' => $_POST['state'],
'zip' => $_POST['zip'],
'phone' => $_POST['phone'],
'url' => $_POST['url'],
'type' => $_POST['type'],
'tags' => $_POST['tags'],
'active' => $_POST['active'],
);
// Check if the restaurant already exists
$check = $this->mRestaurant->getRestaurant($data['name'], $data['zip']);
// If no records were returned add the new restaurant
if($check->num_rows() == 0) {
$query = $this->mRestaurant->addRestaurant($data);
if ($query) {
// On success
$this->session->set_flashdata('status', '<div class="success">Added New Restaurant!</div>');
} else {
// On failure
$this->session->set_flashdata('status', '<div class="error">Could not add a new restaurant.</div>');
}
redirect('restaurant/confirm', 'refresh');
} else {
// Notify the user that the restaurant already exists in the database
$this->session->set_flashdata('status', '<div class="notice">This restaurant already exists in the database.</div>');
redirect('restaurant/index');
}
}
}
function confirm() {
$data['title'] = "Confirm";
$this->load->view('/template/header');
$this->load->view('/restaurant/confirm', $data);
$this->load->view('/template/footer');
}
}
?>
I will try to help with the logic in the controller that I always use:
function index()
{
//set some default variables
$data['error_message'] = '';
//if this is to edit existing value, load it here
// from database and assign to $data
//...
//set form validation rules
$validation = array();
$validation['field_name'] = array(
'field' => 'field_name',
'label' => 'Field label',
'rules' => 'trim|required'
);
//more rules here
//...
$this->load->library('form_validation');
$this->form_validation->set_rules($validation);
//run validation
if ($this->form_validation->run() == FALSE)
{
$data['error_message'] .= validation_errors();
}
else
{
//do insert/update
//
//it's better to do redirection after receiving post request
//you can use flashdata for success message
if ( $success )
{
$this->session_set_flashdata('success_message', MESSAGE_HERE);
}
redirect(RESULT_PAGE);
}
//reaching this block can have 2 meaning, direct page access, or not have valid form validation
//assign required variables, such as form dropdown option, etc
//...
//load view
$this->load->view(VIEW_FILE, $data);
}
View file:
...
<?php if ( $error_message ): ?>
<?php echo $error_message; ?>
<?php endif; ?>
<?php echo form_open(current_url, array('id' => 'some_form_id')); ?>
<!-- form field here -->
<label for="field_name">Field label</label>
<input name="field_name" value="<?php echo set_value('field_name', $DEFAULT_FIELD_NAME_IF_NEEDED); ?>" />
<!-- more form field here -->
<?php echo form_close(); ?>
...
I hope this will help you.
For the $DEFAULT_FIELD_NAME_IF_NEEDED in the view file, I use this to pass the default value if this form page is to edit existing data from database. You can load the data in the controller, then pass it to view file and display it in the form field.
-------controller-------
$data['post'] = $_POST;
$this->load->view('view/view', $data);
then in your view
<input type="text" value="><?=$post['username'];?>" name="username">
I had a similar problem and I ended up doing:
My form is to create new user but you should get the idea.
if($this->form_validation->run() == FALSE)
{
$this->data['title'] = "Add User";
$this->load->vars($this->data);
$this->load->view('head');
$this->load->view('header');
$this->load->view('admin/sidebar');
$this->load->view('admin/add_user');
$this->load->view('footer');
}
So effectively instead of calling new function I was showing new view from the same function.
Not the nicest solution but it works.
Also you might want to use something like this to check if the restaurant already exists:
function _check_username($str)
{
$this->db->where('username', $str);
$query = $this->db->get('sm_users');
if($query->num_rows() == 0)
{
return TRUE;
}
else
{
$this->form_validation->set_message('_check_username', "User '$str' already exists!");
return FALSE;
}
}
And use callback validation function:
$this->form_validation->set_rules('userName','User Name','trim|required|min_length[3]|callback__check_username');
You could try having the form post to index, and in the index method, do validation if the form has been submitted. Then either render the index view (if there are errors) or add the restaurant and render the confirm view.