Prevent form to display default values when validation fails codeigniter - php

public function edit_profile(){
$logged_in_user = $this->session->userdata('logged_in');
$data['images_url'] = $this->config->item('images_url');
$data['cdn_url'] = $this->config->item('cdn_url');
$data['reminder'] = $this->config->item('reminder');
$data['current_module'] = "ess";
$data['user_details'] = $this->ess->get_user_details($logged_in_user['user_id']);
$this->load->view("header", $data);
$this->load->view("leftbar", $data);
$this->load->view("ess/ess_edit_profile");
$this->load->view("footer", $data);
if($this->input->post('submit')){
$post_data = $this->input->post();
$this->form_validation->set_rules('full_name','Full Name','required|trim|xss_clean');
$this->form_validation->set_rules('email','Email','required|trim|valid_email');
$this->form_validation->set_rules('blood_group','Blood Group','max_length[2]');
$this->form_validation->set_rules('phone','Phone','required|trim|xss_clean');
$this->form_validation->set_rules('address','Address','required|xss_clean|max_length[100]');
$this->form_validation->set_rules('designation','Designation','required|xss_clean');
$this->form_validation->set_rules('emergency_name','Emergency Name','required|xss_clean');
$this->form_validation->set_rules('emergency_number','Emergency Number','required|xss_clean');
$this->form_validation->set_rules('next_of_kin','Next of Kin','trim|xss_clean');
if($this->form_validation->run() === true){
// update data
} else {
$this->load->view("ess/ess_edit_profile");
}
}
}
Above is the function of my controller that loads a edit profile view with database populated values in input fields. Now when the form get submitted after doing editing it goes to validation process in edit_profile() function. I am deliberately running false the validation function for checking purpose. Now if the validation runs === false i loaded the ess_edit_profile view again but the validation messages are not appearing. Also the form fields are getting populated with default values which i've set via set_value() function
Below is how i am showing form fields with database data
<td>
<label for="full_name">Full Name</label>
<input style="width: 300px;" type="text" name="full_name" id="full_name" value="<?php echo set_value('full_name',$user_details[0]->ui_full_name); ?>" />
<?php echo form_error('full_name', '<span class="alert">', '</span>'); ?>
</td>

try this remove else part then try
if($this->form_validation->run() === true){
// update data
}
$this->load->view("ess/ess_edit_profile");

Please use set_value function to set element values
Like this
<input type="text" name="name" value="<?php echo set_value("name", $database_name)?>"/>
In Controller
$this->form_validation->set_rules('name','Edit name','trim|xss_clean|required');
If the value not required then also set validation rules trim
$this->form_validation->set_rules('name','Edit name','trim');

Related

Is it possible to call codeigniter controller function from a html form action

I have a Login form in html template and want to call the codeigniter controller function on form submission. Where html page is outside the CI folder and the CI folder name is binary, Ctrl_signin is my controller and chkvalidatelogin is my function, is it possible?
HTML Form Code:
<form action="binary/Ctrl_signin/chkvalidatelogin" method="post">
<input type="email" name="username" class="email" placeholder="Username" required="" />
<input type="password" name="Password" class="password" placeholder="Password" required="" />
<input type="submit" value="Submit">
</form>
Ctrl_signin Controller Code:
function chkvalidatelogin(){
if(isset($_POST['login']) && $_POST['login']=='login')
{
$username=$_POST['username'];
$password = $_POST['password'];
$data = $this->Mdl_signin->validatelogin('member',$username,$password);
if($data>0)
{
$userdata=$this->Mdl_signin->fetchmemid($username);
$mid=$userdata->mem_lid;
$mid1=$userdata->username;
$_SESSION['user'] = $mid1;
$_SESSION['mlid'] = $mid;
$_SESSION['username'] = $mid;
$this->session->set_userdata('login','true');
$msg['message']="successfully login";
redirect(base_url().'Ctrl_signin/Dashboard',$msg);
}
else
{
$msg="login failed!!";
redirect(base_url().'Ctrl_signin/signin?mesg='.$msg);
}
}
}
Mdl_signin Model Code:
function validatelogin($table,$mid,$password)
{
$query=$this->db->query('select * from '.$table.' where username="'.$mid.'" and decrepted_password="'.$password.'"');
return $query->num_rows();
}
function fetchmemid($username)
{
$sql='select mem_lid,username from member where username="'.$username.'"';
$query=$this->db->query($sql);
return $query->row();
}
I tried above code but it shows the blank page on function url
It is very possible. Just point the form action to the full URL including the controller and method such as example.com/controller/method
Note, however, that if your CSRF protection is enabled you may encounter the controller refuses to process the form. You'd need to disable CSRF on that specific controller/method (not really recommended), disable CSRF at all (absolutely not recommended) or figure out a way to comply with CI's CSRF validations from outside Codeigniter

how to validate form in codeigniter

I have a website based on codeigniter framework. I have a form on my index page and some prices of flights which are coming through my database.
here is my form:
<?php echo validation_errors(); ?>
<form action="<?php echo base_url() ?>detail/travel" method="post">
<input type="text" name="departure">
<input type="text" name="destination">
<input type="text" name="name">
<input type="text" name="cell">
</form>
so my problem is when user did not fill the whole form and submit the button, it goes into the function of "travel" which I made in my controller(detail) and show 0 results because of the error. I want that user remain on my index page with all the details until he fill the form correctly and show errors on my index page if he missed any field of my form.
here is my function "travel" that i have in my controller(detail):
function search_travel(){
if($_POST){
$config = array(
array(
'field'=>'departure',
'label'=>'departure',
'rules'=>'trim|required|alpha'
),
array(
'field'=>'destination',
'label'=>'destination',
'rules'=>'trim|required|alpha'
),
array(
'field'=>'name',
'label'=>'name',
'rules'=>'trim|required|alpha'
),
array(
'field'=>'cell',
'label'=>'cell no',
'rules'=>'trim|required|regex_match[/^[0-13]+$/]'
)
);
$this->load->library('form_validation');
$this->load->helper(array('form', 'url'));
$this->form_validation->set_rules($config);
if($this->form_validation->run() == FALSE){
$data['errors']= validation_errors();
}
else{
$destination= $this->input->post('destination');
$this->email->send();
$data['var']= $this->Travel->search_travel($destination);
$this->load->view('details',$data)
}
}
}
and my index function is:
function index(){
$data['fares']= $this->Travel->all_fares();
$this->load->view('index', $data);
}
you need to redirect to old page and print error in view page
<?php echo form_error('departure'); ?>
(print this in view for each input fields and below in controller)
if ($this->form_validation->run() == FALSE) {
redirect('method name that loads form');
}

CodeIgniter's set_value() not re-populating

I've checked and re-checked my code, referencing the CI docs and other posts throughout the web, but I am unsuccessful at implementing the set_value() method for re-populating form fields after failed validation.
Perhaps I am missing something very fundamental to the CI framework (I'm rather new to it), but your insight would be much appreciated.
I have the following in my controller method:
public function form_step2(){
//Form Setup
$this->load->helper('form');
$this->load->helper('url');
$this->load->library('form_validation');
$data['title'] = $this->base_title;
$data['base_url'] = base_url();
//Validation Settings - must be set per step
$this->form_validation->set_rules('request_type', 'Request Type', 'required');
*...more of the same set_rules()*
if ($this->form_validation->run() === FALSE) {
### Validation failed or New Form
// Get form element data
$data['request_types'] = $this->my_model->get_form_data('request_type');
*...more of the same get_form_data() calls for loading form elements*
//Generate Page from View Templates
$this->load->view('templates/header', $data);
$this->load->view('templates/form_step2', $data);
$this->load->view('templates/footer');
} else {
### Save to database
$this->my_model->set_data($data);
redirect('my_model/success','refresh');
}
}
And in my view, a snippet of the code that is not re-populating:
<?php echo form_open('my_model/form_step2', array('class'=>'form-inline')); ?>
<label for="fname">First Name</label>
<input type="text" id="fname" name="fname" value="<?php echo set_value('fname'); ?>" />
<input type="submit" name="submit" value="Submit" />
I can't figure this one out, so thanks in advance for your help.
if you want to use set_data() you need to also use set_rules for that POST/GET field.
Since you've commented out all your set_rules I can not confirm that this is the issue but most likely it is.
please check if you have this line in your code
$this->form_validation->set_rules('fname', 'First name', 'trim|required');
So if you want to re-populate field with name="fname" you need to have set_rules() // as line above for it otherwise it won't process therefore set_value('fname') is empty.
you surely have found a solution but, for people like me which were spending too many time for this trouble.
I found a solution:
so instead to code that
<input type="text" id="fname" name="fname" value="<?php echo set_value('fname'); ?>" />
Try this, it run very well:
<?php $data = array('id' =>fnam, 'name'=> 'fname','value'=> set_value('fname'), 'size =>'50');
echo form_input($data).'<br />'; ?>
Try this way. It will get both validation errors and set value
In View
<?php echo flash_message();
if($this->session->userdata('postinput') !=""){
$value = $this->session->userdata('postinput');
$this->session->unset_userdata('postinput');
}else
$value = "";
?>
<form action="<?php echo site_url('carlisting/carlist');?>" method="post" id="your_reg_form">
<div class="reg-search">
<input placeholder="YOUR REG" name="input" type="text" value="<?php echo $value; ?>">
</div>
In Controller
$this->form_validation->set_rules('input', 'Registration', 'required|min_length[2]|max_length[7]');
if ($this->form_validation->run() == false){
$this->session->set_flashdata( 'message', array('content' => validation_errors(), 'type' => 'error_message_small' ));
$this->session->set_userdata('postinput',$this->input->post('input'));
redirect('home');
}
Permits you to set the value of an input form or textarea. You must supply the field name via the first parameter of the function. The second (optional) parameter allows you to set a default value for the form. Example:
<input type="text" name="quantity" value="<?php echo set_value('quantity', '0'); ?>" size="50" />
The above form will show "0" when loaded for the first time.

store the $_POST form data if page fail to submit

I am using codeigniter. I am currently having a very simple form (nothing but input fields) that submits to the controller for processing.
That all doesn't matter, but what I am asking about is that I have an upload file in the form also. so the upload function will check for file size and type and so on and gives error if not complying. when that happens and I choose another file that matches the requirement, I submit but nothing goes to next page but the uploaded file and its details while the other fields are not posted or are blank.
It is as if the post is not cached and when I select new file to upload and its okay, it checks $_POST of those fields and they are empty. How can I check for that so that to make sure all fields contain values?
Thank you and more than happy to help elaborating.
To repopulate the fields you can use the set_value function.
set_value()
Permits you to set the value of an input form or textarea. You must supply the field name via the first parameter of the function. The second (optional) parameter allows you to set a default value for the form.
First you check if the form validation and upload was successful.
If both are successful we redirect the user to a new page.
If one of these is unsuccessful we add the error message to your data array which we can access in our view and display our form.
Controller
public function signup()
{
// Data array
$data = array();
// Load form validation libary
$this->load->library('form_validation');
// Load upload library and set configuration
$config['upload_path'] = './uploads/';
$this->load->library('upload', $config);
// Set the required fields
$this->form_validation->set_rules('first_name', 'First name', 'required');
if ($this->form_validation->run() == TRUE)
{
// If upload was succesfull
if ($this->upload->do_upload())
{
$upload_data = $this->upload->data();
// Build array to store in database
$save_data = array(
'first_name' => $this->input->post('first_name'),
'image' => $upload_data['file_name']
);
// Send data to your model to process
$this->your_model->save($save_data);
// Redirect to success page
redirect('registration_succes');
}
else
{
// Upload failed, set error
$data['error'] = $this->upload->display_errors();
}
}
else
{
// Form validation failed, set error
$data['error'] = validation_errors();
}
// Display the form by default or on error
$this->load->view('myform', $data);
}
In our view we repopulate the fields with the submitted values using the set_value function.
View ( myform )
<?php echo form_open_multipart('signup');?>
<fieldset>
<?php if( isset($error) && ! empty($error) ): ?>
<div class="error"><?php echo $error; ?></div>
<?php endif; ?>
<p>
<label>First name</label>
<input type="text" name="first_name" value="<?php echo set_value('first_name'); ?>" />
</p>
<p>
<label>File</label>
<input type="file" name="userfile" size="20" />
</p>
<p>
<input type="submit" />
</p>
</fieldset>
</form>

PHP Show error messages in order and re-display correct fields

I have an email form that checks three fields, name, valid email and comments. But the way it's set up now, since name and comments are in one function it first checks name and comments even if email is not valid, how can I re-write it so it checks the fields in order. Also, I would like to re-display the fields that have no errors, so the user doesn't have to type again. Please help. Thanks
<?php
$myemail = "comments#myemail.com";
$yourname = check_input($_POST['yourname'], "Enter your name!");
$email = check_input($_POST['email']);
$phone = check_input($_POST['phone']);
$subject = check_input($_POST['subject']);
$comments = check_input($_POST['comments'], "Write your comments!");
if (!preg_match("/([\w\-]+\#[\w\-]+\.[\w\-]+)/", $email))
{
show_error("Enter a valid E-mail address!");
}
exit();
function check_input($data, $problem='')
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
if ($problem && strlen($data) == 0)
{
show_error($problem);
}
return $data;
}
function show_error($myError)
{
?>
<!doctype html>
<html>
<body>
<form action="myform.php" method="post">
<p style="color: red;"><b>Please correct the following error:</b><br />
<?php echo $myError; ?></p>
<p>Name: <input type="text" name="yourname" /></P>
<P>Email: <input type="text" name="email" /></p>
<P>Phone: <input type="text" name="phone" /></p><br />
<P>Subject: <input type="text" style="width:75%;" name="subject" /></p>
<p>Comments:<br />
<textarea name="comments" rows="10" cols="50" style="width: 100%;"></textarea></p>
<p><input type="submit" value="Submit"></p>
</form>
</body>
</html>
<?php
exit();
}
?>
First off, I would suggest you validate ALL of the fields at once, and display all appropriate error messages on the form. The primary reason is that it can be bad user experience if they have to submit your form a whole bunch of times because they have to address one error at a time. I'd rather correct my email address, password, comments, and selection in one try instead of fixing one at a time just to reveal what the next error is.
That said, here are some pointers on validating the form like you want. This is typically how I approach a form doing what you want to do. This assumes your form HTML and form processor (PHP) are together in the same file (which is what you have now). You can split the two, but the methods for doing that can be a bit different.
Have one function or code block that outputs the form and is aware of your error messages and has access to the previous form input (if any). Typically, this can be left outside of a function and can be the last block of code in your PHP script.
Set up an array for error messages (e.g. $errors = array()). When this array is empty, you know there were no errors with the submission
Check to see if the form was submitted near the top of your script before the form is output.
If the form was submitted, validate each field one at a time, if a field contained an error, add the error message to the $errors array (e.g. $errors['password'] = 'Passwords must be at least 8 characters long';)
To re-populate the form inputs with the previous values, you have to store the entered values somewhere (you can either just use the $_POST array, or sanitize and assign the $_POST values to individual variables or an array.
Once all the processing is done, you can check for any errors to decide whether the form can be processed at this point, or needs new input from the user.
To do this, I typically do something like if (sizeof($errors) > 0) { // show messages } else { // process form }
If you are re-displaying the form, you simply need to add a value="" attribute to each form element and echo the value that was submitted by the user. It is very important to escape the output using htmlspecialchars() or similar functions
With those things in place, here is some re-work of your form to do that:
<?php
$myemail = "comments#myemail.com";
$errors = array();
$values = array();
$errmsg = '';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
foreach($_POST as $key => $value) {
$values[$key] = trim(stripslashes($value)); // basic input filter
}
if (check_input($values['yourname']) == false) {
$errors['yourname'] = 'Enter your name!';
}
if (check_input($values['email']) == false) {
$errors['email'] = 'Please enter your email address.';
} else if (!preg_match('/([\w\-]+\#[\w\-]+\.[\w\-]+)/', $values['email'])) {
$errors['email'] = 'Invalid email address format.';
}
if (check_input($values['comments']) == false) {
$errors['comments'] = 'Write your comments!';
}
if (sizeof($errors) == 0) {
// you can process your for here and redirect or show a success message
$values = array(); // empty values array
echo "Form was OK! Good to process...<br />";
} else {
// one or more errors
foreach($errors as $error) {
$errmsg .= $error . '<br />';
}
}
}
function check_input($input) {
if (strlen($input) == 0) {
return false;
} else {
// TODO: other checks?
return true;
}
}
?>
<!doctype html>
<html>
<body>
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<?php if ($errmsg != ''): ?>
<p style="color: red;"><b>Please correct the following errors:</b><br />
<?php echo $errmsg; ?>
</p>
<?php endif; ?>
<p>Name: <input type="text" name="yourname" value="<?php echo htmlspecialchars(#$values['yourname']) ?>" /></P>
<P>Email: <input type="text" name="email" value="<?php echo htmlspecialchars(#$values['email']) ?>" /></p>
<P>Phone: <input type="text" name="phone" value="<?php echo htmlspecialchars(#$values['phone']) ?>"/></p><br />
<P>Subject: <input type="text" style="width:75%;" name="subject" value="<?php echo htmlspecialchars(#$values['subject']) ?>" /></p>
<p>Comments:<br />
<textarea name="comments" rows="10" cols="50" style="width: 100%;"><?php echo htmlspecialchars(#$values['comments']) ?></textarea></p>
<p><input type="submit" value="Submit"></p>
</form>
</body>
</html>
I have a more advanced example which you can see here that may give you some guidance as well.
Hope that helps.
The simplest option is to use a form validation library. PHP's filter extension, for example, offers validation and sanitization for some types, though it's not a complete solution.
If you insist on implementing it yourself, one issue you'll have to consider is what counts as the order: the order of the elements in the form or the order of the user input in $_POST. On most browsers, these should be the same, but there's no standard that enforces this. If you want to go off of form order, you'll need to define the form structure in one place, and use that information to do things like generating or validating the form (a consequence of the Don't Repeat Yourself (DRY) principle). Iterating over the appropriate structure will give you the order you desire: looping over the form gives you form order, whereas looping over $_POST gives you user input order.
It looks like you want to more than simply validate the data; you also want to prepare it for use, a process called "sanitization".
When it comes to sanitization, define different kinds of sanitizers, rather than a single check_input function. Specific sanitizers could be functions, or objects with an __invoke method. Create a map of form fields to sanitizers (for example, an array of input name to sanitizer callbacks). The order of the elements in the mapping sets the order of the sanitization; if you use a single structure to define the form information, the display order and sanitization order will thus be the same.
Here's a very broad outline:
# $fields could be form structure or user input
foreach ($fields as $name => $data) {
# sanitize dispatches to the appropriate sanitizer for the given field name
$form->sanitize($name, $data);
# or:
//sanitize($name, $data);
# or however you choose to structure your sanitization dispatch mechanism
}
As for setting an input's value to the user-supplied data, simply output the element value when outputting the element. As with all user input (really, all formatted output), properly escape the data when outputting it. For HTML attributes, this means using (e.g.) htmlspecialchars. Note you should only escape outgoing data. This means your sanitization functions shouldn't call htmlspecialchars.
You can improve usability by placing each error next to the corresponding input, adding an "error" class to the element and styling the "error" class to make it stand out. Improve accessibility by wrapping <label> elements around the label text.
Use this structure of script:
<?php
$errors = array();
if (isset($_POST['send'])) {
// check data validity
if (!mailValid($_POST['email']))
$errors[] = 'Mail is not valid';
...
// send data by email
if (!$errors) {
// send mail and redirect
}
}
?>
<html>
...
<?php
if ($errors) {
// display errors
foreach ($errors as $error) {
echo "$error<br />";
}
}
?>
<form ...>
...
Email: <input type="text" name="email" value="<?php echo isset($_POST['email']) ? htmlspecialchars($_POST['email']) : '' ?>" />
...
</form>
...
</html>
You could always do it like this, using filter_var and in_array checks:
<?php
$myemail = "comments#myemail.com";
//Pre made errors array
$errors=array('name'=>'Enter Your name',
'email'=>'Please enter valid email',
'phone'=>'Please enter valid phone number',
'subject'=>'Please enter valid subject, more then 10 chars',
'comment'=>'Please enter valid comment, more then 10 chars');
//Allowed post params and its validation type
$types = array('name'=>'string',
'email'=>'email',
'phone'=>'phone',
'subject'=>'string',
'comment'=>'string');
//A simple validation function using filter_var
function validate($value,$type){
switch ($type){
case "email":
return ((filter_var($value, FILTER_VALIDATE_EMAIL))?true:false);
break;
case "phone":
return ((preg_match("/^[0-9]{3}-[0-9]{4}-[0-9]{4}$/", $value))?true:false);
break;
case "string":
return ((strlen($value) >=10 )?true:false);
break;
default:
return false;
break;
}
}
//If forms been posted
if(!empty($_POST) && $_SERVER['REQUEST_METHOD'] == 'POST'){
//Assign true, if all is good then this will still be true
$cont=true;
$error=array();
foreach($_POST as $key=>$value){
//if key is in $types array
if(in_array($key,$types)){
//If validation true
if(validate($value, $types[$key])==true){
$$key=filter_var($value, FILTER_SANITIZE_STRING);
}else{
//Validation failed assign error and swithc cont to false
$error[$key]=$errors[$key];
$cont=false;
}
}
}
}
if($cont==true && empty($error)){
//Send mail / do insert ect
}else{
//Default to form
?>
<!doctype html>
<html>
<body>
<form action="" method="post">
<p>Name: <input type="text" name="name" value="<?=#htmlentities($name);?>"/> <?=#$error['name'];?></P>
<P>Email: <input type="text" name="email" value="<?=#htmlentities($email);?>" /> <?=#$error['email'];?></p>
<P>Phone: <input type="text" name="phone" value="<?=#htmlentities($phone);?>"/> <?=#$error['phone'];?></p><br />
<P>Subject: <input type="text" style="width:75%;" name="subject" /> <?=#$error['subject'];?></p>
<p>Comments: <?=#$error['comment'];?><br />
<textarea name="comment" rows="10" cols="50" style="width: 100%;"><?=#htmlentities($comment);?></textarea></p>
<p><input type="submit" value="Submit"></p>
</form>
</body>
</html>
<?php
}?>

Categories