Display Php form errors next to fields - php

I looked in the forum for similar questions but could not find anything that would help me.
I have the validation class that validates form entries. But It displays them at the top of the table. How could I display these next to the fields rather then top of the form?
Registration.php
if(Input::exists()){
$validate = new Validate();
$validation = $validate->check($_POST, array(
'fullName' => array(
'required' => true,
'min' => 4,
'max' => 20
),
'username' => array(
'required' => true,
'min' => 4,
'max' => 20,
'unique' => 'user'
),
'email' => array(
'required' => true,
'unique' => 'user'
),
'password' => array(
'required' => true,
'min' => 6
),
'password_again' => array(
'required' => true,
'matches' => 'password'
)
));
if($validation->passed()){
// Register User
echo('Passed');
} else {
// Output Errors
foreach($validation->errors() as $error){
echo $error, '</br>';
}
}
}
?>
<div class="registration">
<h3> Register with WebA<font style="color: #c14a44;">ww</font>ards </h3>
<p> Spare us few little seconds, and you'll be glad you did. </p>
<form method="post" action="">
<input type="text" id="fullName" value="<?php echo escape(Input::get('fullName')); ?>" name="fullName" placeholder="Your Full name">
<input type="text" id="username" value="<?php echo escape(Input::get('username')); ?>" name="username" placeholder="Choose Username" autocomplete="off">
<input type="email" id="email" value="<?php echo escape(Input::get('email')); ?>" name="email" placeholder="Email address">
<input type="password" id="password" name="password" placeholder="Password">
<input type="password" id="password_again" name="password_again" placeholder="Comfirm password">
<input id="gobutton" type="submit" value="Register">
</form>
Validate.php
public function check($source, $items = array()){
foreach($items as $item => $rules){
foreach($rules as $rule => $rule_value){
$value = trim($source[$item]);
$item = escape($item);
// if rule is required and value is empty add error
if($rule === 'required' && empty($value)){
$this->addError("{$item} is required");
} else if(!empty($value)) {
// DEFINE THE RULES FOR VALIDATION MIN, MAX
// USE SWITCH STATEMENT TO SWITCH BETWEEN THE RULES AND CHECK IF VALID
// Case for each of the rules defined on the form
switch($rule){
case 'min':
if(strlen($value) < $rule_value){
$this->addError("{$item} must be a minimum of {$rule_value} characters.");
}
break;
case 'max':
if(strlen($value) > $rule_value){
$this->addError("{$item} must be a maximum of {$rule_value} characters.");
}
break;
case 'matches':
if($value != $source[$rule_value]){
$this->addError("{$rule_value} must match {$item}");
}
break;
case 'unique':
$check = $this->_db->get($rule_value, array($item, '=', $value));
if($check->count()){
$this->addError("{$item} already exists.");
}
break;
}
}
}
}
if(empty($this->_errors)){
$this->_passed = true;
}
return $this;
}

You write code that puts those errors where you want them.
<?php
$errors = array();
if (!$something) {
$errors['field'] = 'Message';
}
?>
<? if (isset($errors['field'])) : ?>
<p class="error"><?php echo $errors['field']; ?></p>
<?php endif; ?>
<input type="text" name="field" ...>

Without seeing more of your code I can't tell (the addError method isn't included), but your validation class doesn't appear to have an easy way of associating an error with a field in the response (it's just a single string), so it will need some work to do this. I would suggest returning the errors as an associative array, with the key being the name of the field, and the value being the error message to be printed, and leave it blank for fields that are correct. Then, in your registration file, you can easily refer to the field in question.

You have to iterate through the errors while you are outputting the fields, check for errors related to that field, and print them after outputting the inputs, instead of echoing all the errors above the form.
The errors array should be multidimensional, if you need to have more than one validation error in each field. You should have an array with an entry for each field name.
You would also need the fields to be an array to achieve this.
This way you could do something like this (untested):
foreach ($field as $f) {
echo "<input type='{$f->type}' id='{$f->name}' value='{$f->value}' name='{$f->name}' placeholder='{$f->description}'>";
if (in_array($f->name, $errors)) {
echo "<span class='errors'>{$errors[$f->name]}</span>";
}
}
If the error entry for each field is an array, you would have to iterate through it before echoing the errors.

Related

Is there a better way to validate my form? PHP

I am trying to create a register page and I was wondering if there is a better way of doing this. So what I was think was instead of typing every field or is this a good way of doing this?
This is what I have currently.
This is the form
<form action="" method="POST">
<input type="text" name="username" placeholder="Username:" />
<input type="password" name="password" placeholder="Password:" />
<input type="password" name="password" placeholder="Confirm password:" />
<input type="text" name="email" placeholder="Email:" />
<input type="text" name="first_name" placeholder="First name:" />
<input type="text" name="last_name" placeholder="Last name:" />
<input type="submit" name="register" value="REGISTER" />
</form>
This is what I have for PHP side
function reg_validation() {
if ($_POST['register']) {
if (empty($_POST['username'])) {
echo 'Please enter a username';
}
if (empty($_POST['password'])) {
echo 'Please enter a password';
}
if (empty($_POST['confirm_password'])) {
echo 'Please confirm your password';
}
if (empty($_POST['email'])) {
echo 'Please enter an email address';
}
if (empty($_POST['first_name'])) {
echo 'Please enter your first name';
}
if (empty($_POST['last_name'])) {
echo 'Please enter your last name';
}
}
}
<?php
function reg_validation() {
if (isset($_POST['register'])) {
$expectedFields = array(
'username', 'password', 'confirm_password', 'email', 'first_name', 'last_name'
);
foreach ($expectedFields as $value)
if (!array_key_exists($value, $_POST) || empty($_POST[$value]))
return false;
return true;
}
return false;
}
?>
Don't know if I misunderstood your question in my last answer, so here is another suggestion. Code is not tested, so it may contain minor typos.
In this suggestion we store all field names in an array an loop through the array and checks if any of the field names is not a key in the post array.
So this function will return true if all fields is found in post data or false if not.
<?php
if (isset($_POST['register'])) {
try {
if (empty($_POST['username']))
throw new Exception('missing_username');
else if (empty($_POST['password']))
throw new Exception('missing_password');
else if (empty($_POST['confirm_password']))
throw new Exception('missing_confirm_pass');
else if (empty($_POST['email']))
throw new Exception('missing_email');
else if (empty($_POST['first_name']))
throw new Exception('missing_firstname');
else if (empty($_POST['last_name']))
throw new Exception('missing_lastname');
// do something if all fields are filled
} catch (Exception $e) {
$errorArray = array(
'missing_username' => 'Please enter a username',
'missing_password' => 'Please enter a password',
'missing_confirm_pass' => 'Please confirm your password',
'missing_email' => 'Please enter an email address',
'missing_firstname' => 'Please enter your first name',
'missing_lastname' => 'Please enter your last name'
);
if (isset($errorArray[$e->getMessage()]))
echo $errorArray[$e->getMessage()];
}
}
?>
I like to do it this way, don't know what everyone else thinks about it.
By using try catch, we don't neccessarily need a function to return, since we instead can throw an exception to break from the try section.

Illegal String Offset and Validation not working in PHP

I'm making a validation system for my website. Well actually, my code works if I didn't put any parameter in my $_POST(like$_POST['Login']). If I put any parameter in my $_POST, it returns an error:
Warning: Illegal string offset: 'username' in C:\ ...
My sample authentication form:
<form action="" method="post">
<div class="field">
<label for="username">Username: </label>
<input type="text" name="username" id="username" autocomplete="off" />
</div>
<div class="field">
<label for="Password">Password: </label>
<input type="password" name="password" id="password" autocomplete="off" />
</div>
<div class="field">
<label for="remember">
<input type="checkbox" name="remember" id="remember" value="on"/> Remember Me
</label>
</div>
<input type="hidden" name="token" value="<?php echo Token::generate(); ?>" />
<input type="submit" value="Login" name="Login"/>
</form>
The script that will be processed if the form was submitted:
<?php
require_once 'init.php';
$user = new User();
if($user->isLoggedIn()){
Redirect::to('index.php');
}
$validate = new Validate();
if(Input::exists()) {
if(Token::check(Input::get('token'))) {
$validation = $validate->check($_POST["Login"], array(
'username' => array('required' => true),
'password' => array('required' => true)
));
}
}
?>
The validation class:
<?php
class Validate {
# Set the variables
private $_passed = false,
$_errors = array(),
$_db = null;
# Construct or establish connection to the database
public function __construct(){
$this->_db = Database::getInstance();
}
# The validation/checking code or the main brain of the code
public function check($source, $items = array()){
# Run a ` for each ` for each item in the fields
foreach($items as $item => $rules) {
# Run a ` for each ` for every rule in the items
foreach($rules as $rule => $rule_value) {
# Set the variables of `value` and `item`
$value = $source[$item];
$item = sanitize($item);
if($rule === 'required' && empty($value)) {
$this->addError("{$item} is required");
} else if (!empty($value)) {
switch($rule) {
# Case: Minimum
case 'min':
if(strlen($value) < $rule_value) {
$this->addError("{$item} must be a minimum of {$rule_value} characters.");
}
break;
# Case Maximum
case 'max':
if(strlen($value) > $rule_value) {
$this->addError("{$item} must be a maximum of {$rule_value} characters.");
}
break;
# Case: Match
case 'matches':
if($value != $source[$rule_value]) {
$this->addError("{$rule_value} must match {$item}.");
}
break;
# Case: Unique
case 'unique':
$check = $this->_db->get($rule_value, array($item, '=', $value));
if($check->count()) {
$this->addError("{$item} already exists.");
}
break;
# Case: Not match
case 'notmatch':
if($value === $source[$rule_value]) {
$this->addError("{$rule_value} must not match {$item}.");
}
break;
}
}
}
}
if(empty($this->_errors)) {
$this->_passed = true;
}
}
# ~ ADD ~ and error
public function addError($error) {
$this->_errors[] = $error;
}
# ~ RETURN ~ the errors
public function errors() {
return $this->_errors;
}
# ~ CHECK ~ if it is passed
public function passed() {
return $this->_passed;
}
}
You are calling $validate->check and passing it $_POST["Login"] as first argument but based on your HTML you should be passing only $_POST. When you pass $_POST["Login"] then the form inputs should have attribute name as name="Login[username]" .
Right now when you pass $_POST["Login"] its actually an empty array so that could be the reason why you are getting Illegal string offset

Codeigniter insert array into database

I am currently making a registration form where in you could register individually or by many I need a way how to make the multiple register work i cant add the input into db i get an array to string conversion error
i still dont have the model for this
my code is
controller
public function registerbatch(){
for ($i = 0; $i < count($this->input->post('surname','firstname','age','school','course','email')); $i++) {
$this->form_validation->set_rules("surname[$i]", "surname[$i]", "required");
$this->form_validation->set_rules("firstname[$i]", "firstname[$i]", "required");
$this->form_validation->set_rules("age[$i]", "Age[$i]", "required");
$this->form_validation->set_rules("school[$i]", "School[$i]", "required");
$this->form_validation->set_rules("course[$i]", "Course[$i]", "required");
$this->form_validation->set_rules("email[$i]", "Email[$i]", "required");
}
if ($this->form_validation->run() == TRUE) {
$reg_dat = array(
'surname' => $this->input->post('surname'),
'name' => $this->input->post('firstname'),
'age' => $this->input->post('age'),
'school' => $this->input->post('school'),
'course' => ($this->input->post('course')),
'email' => ($this->input->post('email')),
);
$this->user_model->add_user($reg_dat);
$this->load->view('user/home_view');
} else {
$this->load->view('user/batch_register');
}
view:
<html>
<head>
</head>
<body>
<form class="form" action="<?php echo base_url() . 'user/registerbatch'; ?>" method="post" class="form-horizontal" role="form">
<?php for ($i = 0; $i < $num; $i++): ?>
<br>
Surname: <input type="text" name="surname[]">
<br>
Name: <input type="text" name="firstname[]">
<br>
Age:<input type ="int" name ="age[]">
<br>
School: <input type="text" readonly value="<?= $school ?>" name="school[]">
<br>
Course:<input type ="text" name ="course[]">
<br>
Email:<input type ="text" name ="email[]">
<br>
<br>
<?php endfor ?>
<button type="submit" class="btn btn-success">Register</button>
</body>
</html>
Try this below coding ....
if ($this->form_validation->run() == TRUE) {
extract($_POST);
foreach($surname as $key=>$value) {
$reg_dat = array(
'surname' => $value,
'name' => $firstname[$key],
'age' => $age[$key],
'school' => $school[$key],
'course' => $course[$key],
'email' => $email[$key],
);
$this->user_model->add_user($reg_dat);
}
}
$this->load->view('user/home_view');
Seems that your Post can be a multidimensional array. I think the best way to solve your problem is to foreach that post and insert every row
//your controller
if ($this->form_validation->run() == TRUE) {
$reg_dat_multi = $this->input->post();
foreach ($reg_dat_multi as $reg_dat) {
$this->user_model->add_user($reg_dat);
}
);
you didn't show your model but let's think that is something like this
//your model
function add_user($reg_dat){
if ( $this->db->insert('table', $reg_dat) ){
return true;
}
return false;
}
hope that helps

php validation not working

I am developing a simple registration form that validates with php. problem is rather than the validation echoing on screen once I click the submit button nothing happens, no error or brake it dose not show me what the error is, I believe my logic is correct but I believe there may be a mistake.
would appriciate any advise or identification of my problem
register.php
<?php
require_once 'core/init.php';
if(Input::exists()) {
$validate = new Validate();
$validation = $validate->check($_POST, array(
'username' => array(
'required' => true,
'min' => 2,
'max' => 20,
'unique' => 'users'
),
'password' => array(
'required' => true,
'min' => 6
),
'password_again' => array(
'required' => true,
'matches' => 'password'
),
'name' => array(
'required' => true,
'min' => 2,
'max' => 50
),
));
if($validation->passed()) {
echo 'Passed';
} else {
print_r($validation->errors());
}
}
?>
<form action="" methord="post">
<div class="field">
<lable for="username">Username</lable>
<input type="text" name="username" id="username" value="<?php echo escape(Input::get('username')); ?>" autocomplete="off">
</div>
<div class="field">
<lable for="password">Choose Your Password</lable>
<input type="password" name="password" id="password">
</div>
<div class="field">
<lable for="password_again">Verify Password</lable>
<input type="password" name="password_again" id="password_again">
</div>
<div class="field">
<lable for="name">Your Name</lable>
<input type="text" name="name" value="<?php echo escape (Input::get('name')); ?>" id="name">
</div>
<input type="submit" value="Register">
</form>
Validation.php
<?php
class Validate {
private $_passed = false,
$_errors = array(),
$_db = null;
public function __contruct() {
$this->_db = DB::getInstance();
}
public function check($source, $items = array()) {
foreach($items as $item => $rules) {
foreach($rules as $rule => $rule_value) {
$value = $source[$item];
if($rule == 'required' && empty($value)) {
$this->addError("{$item} is required")
} else {
}
}
}
if(empty($this->_errors)) {
$this->_passed = true;
}
return $this;
}
private function addError() {
$this->_errors[] = $error;
}
public function errors() {
return $this->_errors;
}
public function passed() {
return $this->_passed;
}
}
UPDATE
Have corrected typo that was correctly pointed out by #PeteR, but there is still a problem that the echo validation is not printing out.
Link to form
http://stuweb.cms.gre.ac.uk/~ob219/membership/register.php
Looks like you have a typo, fella.
if($rule == 'requierd' && empty($value)) {
You also have a semicolon missing here:
$this->addError("{$item} is required");
----^
And another typo:
<form action="" methord="post">
Should be method...
And finally, try this:
private function addError($error) {
Input::exists()
returns false/null or contains errors, thus, the if statement is not true
if(Input::exists()) {
and the code inside of it (validation) does never get executed.
Debug with
print_r(Input::exists());
You should also change your if to a real condition:
if(Input::exists() === true) {
Enable error reporting in PHP (from http://blog.flowl.info/2013/enable-display-php-errors/)
<?php
// Put these lines to the top of your script
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('display_startup_errors', true);
ini_set('xmlrpc_errors', true);
Update - Yet another one:
private function addError() {
$this->_errors[] = $error;
}
Method has no parameters..
private function addError($error) {
$this->_errors[] = $error;
}

how to validate form in a order codeigniter

I would like to validate my login form like Google does.
First check username then check password; If both are empty then there is only an error on the username box.
In CodeInginter, if both are empty it prints each field is required messages.
Can we mimic this functionality easily with CodeIgnightor?
you need to research before you post some question. These kind of information available in codeIgniter user guide. Any way i am providing simple example.
View file: login.php
<form action="<?php echo ROOT_FOLDER ?>/controller_name/post_login" method="post" >
<p>
<label>Email:</label> <?php echo form_error('email'); ?><br />
<input type="text" class="text" name="email" value="<?php echo set_value('email'); ?>" />
</p>
<p>
<label>Password:</label> <?php echo form_error('passwd'); ?><br />
<input type="password" name="passwd" class="text" value="" />
</p>
<p>
<input type="submit" class="submit" value="Login" />
</p>
</form>
Controller function which is written in controller file..........
public function post_login()
{
$error_in_validation=set_form_validation($this->config->item('login_form'));
if($error_in_validation){
show_form_validation_error('controller_file_name/login');
}
else
{
$email=$this->input->post('email');
$passwd=$this->input->post('passwd');
$ret=$this->model_file_name->user_login($email, $passwd);
if($ret == NULL){
$model=array();
$model['error_msg']=$this->config->item('login_form_error_code_1');;
$this->load->view('controller_file_name/login',$model);
} else {
redirect("ro_manager/home");
}
}
}
After this you need to create you need to create a file name called form_validation in config folder. In that you need to write the validation rules as per user guide.
$config['login_form'] = array (
array
(
'key' => 'email',
'value' => 'Email',
'rule' => 'trim|required|valid_email|xss_clean'
),
array
(
'key' => 'passwd',
'value' => 'Password',
'rule' => 'trim|required|alpha_numeric|xss_clean'
)
);
Try like this way
$this->form_validation->set_rules('email', 'Email', 'required');
if ($this->form_validation->run() == FALSE){
$this->load->view('myform');
}else{
$this->form_validation->set_rules('passconf', 'Password Confirmation', 'required');
if($this->form_validation->run() == FALSE){
$this->load->view('myform');
}
$this->load->view('formsuccess');
}

Categories