Reputation: 1316
I have a CodeIgniter web application that takes student information and saves them in a table named student
. My table structure is this:
name varchar(30)
roll varchar(10)
department varchar(10)
email varchar(50)
mobile varchar(15)
In my application, I want to achieve the following behavior:
While inserting data, if roll data already exists, then a validation will appear next to the roll text field saying This roll number already exists. Please enter a new roll. That means, for duplicate entries of roll data, a validation will appear, and that data will not be inserted.
My controller is student.php
, note that it contains a callback function and a validation rule:
<?php
if ( ! defined('BASEPATH')){ exit('No direct script access allowed');}
class Student extends CI_Controller
{
function __construct()
{
parent::__construct();
#$this->load->helper('url');
$this->load->model('student_model');
$this->load->library('form_validation');
$this->load->library('session');
}
//Show all Students
public function index()
{
$data['student_list'] = $this->student_model->get_all_students();
$this->load->view('student_view', $data);
}
//Insert a student
public function insert_student_db()
{
$udata['name'] = $this->input->post('name');
$udata['roll'] = $this->input->post('roll');
$udata['department'] = $this->input->post('department');
$udata['email'] = $this->input->post('email');
$udata['mobile'] = $this->input->post('mobile');
$this->form_validation->set_rules('roll', 'Roll', 'callback_check_duplicate_roll');
if($this->form_validation->run() == TRUE)
{
$res = $this->student_model->insert_student($udata);
if($res)
{
header('location:'.base_url()."index.php/student/".$this->index());
}
}
else
{
$this->session->set_flashdata('warning', 'Data already exists');
redirect('/student/index/', 'refresh');
}
}
// My callback function
public function check_duplicate_roll($post_roll)
{
return $this->student_model->checkDuplicateRoll($post_roll);
}
}
?>
And my model is student_model.php
, note that I've a method for checking duplicate roll data:
<?php
class Student_model extends CI_Model
{
function __construct()
{
parent::__construct();
$this->load->database();
}
//To retrieve all students
public function get_all_students()
{
$query = $this->db->get('student');
return $query->result();
}
//Checking for duplicate roll
public function checkDuplicateRoll($post_roll)
{
$this->db->where('roll', $roll);
$query = $this->db->get('student');
$count_row = $query->num_rows();
if ($count_row > 0)
{
return FALSE;
}
else
{
return TRUE;
}
}
//To add a new student to the database
public function insert_student($data)
{
return $this->db->insert('student', $data);
}
}
?>
My view page - student_view.php
:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>My first site in CI</title>
</head>
<body>
<h2>Student Information</h2>
<form method="post" action="<?php echo base_url();?>index.php/student/insert_student_db">
<table width="800" border="0">
<tr>
<th width="213" align="right" scope="row">Name:</th>
<td width="161"><input type="text" name="name" size="60" /></td>
</tr>
<tr>
<th align="right" scope="row">Roll:</th>
<td><input type="text" name="roll" size="60" /></td>
</tr>
<tr>
<th align="right" scope="row">Department:</th>
<td>
<select name="department">
<?php
$sql = mysql_query("SELECT dept_name FROM department");
while ($row = mysql_fetch_array($sql)){
echo "<option value=\"{$row['dept_name']}\">" . $row['dept_name'] . "</option>";
}
?></select>
</td>
</tr>
<tr>
<th align="right" scope="row">Email:</th>
<td><input type="text" name="email" size="60" /></td>
</tr>
<tr>
<th align="right" scope="row">Mobile:</th>
<td><input type="text" name="mobile" size="60" /></td>
</tr>
<tr>
<th align="right" scope="row"> </th>
<td><input type="submit" name="submit" value="Send" /></td>
</tr>
</table>
</form>
<table width="600" border="1" cellpadding="5">
<tr>
<th scope="col">Name</th>
<th scope="col">Roll</th>
<th scope="col">Department</th>
<th scope="col">Email</th>
<th scope="col">Mobile</th>
</tr>
<?php foreach ($student_list as $std_key){ ?>
<tr>
<td><?php echo $std_key->name; ?></td>
<td><?php echo $std_key->roll; ?></td>
<td><?php echo $std_key->department; ?></td>
<td><?php echo $std_key->email; ?></td>
<td><?php echo $std_key->mobile; ?></td>
</tr>
<?php }?>
</table>
</body>
</html>
After I run my application in localhost and try to insert data, duplicate roll data is not inserted in my student
table, that's fine, and my page is redirected to student_view.php
. But the flash message doesn't show up. What is the problem? Is it a problem with my misplacement of flashdata? Or something else?
Note that this is the final, fully modified version of my question. I've edited this question 4 times ever since I first posted it, and because of all those edits, it looked ugly. So I've decided to trim my question according to the last updated version of my code. Please excuse the nature of this question and my inability to figure out the problem, cause I'm an absolute newby to CodeIgniter. Your kind help is going to help me understand CI and encourage me to carry on this journey.
Upvotes: 1
Views: 4869
Reputation: 1397
student.php
public function checkDuplicateRoll($roll) {
return $this->student_model->checkDuplicateRoll($roll);
}
If you define a callback function in a validation rule, the validator will call a function in the class where the validation rules are set. In this case Student controller.
Edit
Controller student.php:
public function insert_student_db() {
// check if form is posted and assing variable to post data
if (false !== $udata = $this->input->post()) {
//unset the submit button
unset($udata['submit']);
$this->form_validation->set_rules('roll', 'Roll', 'callback_check_duplicate_roll');
$this->form_validation->set_message('check_duplicate_roll', 'Role already exists');
if ($this->form_validation->run()) {
$this->student_model->insert_student($udata);
redirect('index.php/student');
}
else {
$this->load->helper('form');
$this->load->view('studentForm');
}
}
}
//for some reason a callback function needs to be public
public function check_duplicate_roll($roll) {
return $this->student_model->checkDuplicateRoll($roll) == false;
}
Model student_model.php
public function ckeckDuplicateRoll($roll) {
$this->db->select('roll');
$this->db->where('roll', $roll);
$result = $this->db->get('student');
return (bool) $result->num_rows();
}
Views in CodeIgniter
As a matter of fact it's MVC where talking about, but a view shouldn't contain any programming logic, except for some echoes (optional in an iteration), some minor calculations and some condtional statements. It's the controller that interacts with the model(s), and parses the data obtained to the view. In CI it's quite simple:
public function index() {
$data = array('title' => 'My first CI site',
'header' => 'First attempt',
'departments' => $this->m_departments->getCollection()
);
$this->load->view('student_view', $data);
}
CI runs $data through extract (core php function), so the keys becomes variables which contains the value. You can use these variables in the view:
// departments as example
<select name="department">
<?php
foreach($departments as $row) {
echo '<option value="' . $row['dept_name'] . '">' . $row['dept_name'] . '</option>';
}
?>
</select>
Upvotes: 2
Reputation: 41885
In your present code, the validation is no where to be found. Initialize the library in your controller first:
$this->load->library('form_validation');
And then when everything is okay, setting rules, etc.:
if($this->form_validation->run() !== false) {
$res = $this->student_model->insert_student($udata);
}
For more info: https://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#validationrules
EDIT:
Since you have your own validation, you could use that custom validation too:
$this->form_validation->set_rules('roll', 'Roll', 'callback_checkDuplicateRoll');
and in your custom funtion:
public function checkDuplicateRoll($post_roll)
{
$this->db->where('roll', $roll);
$query = $this->db->get('student');
$count_row = $query->num_rows();
if ($count_row > 0)
{
$this->form_validation->set_message('checkDuplicateRoll', 'This roll number already exists. Please enter a new roll.');
return FALSE;
}
else
{
return TRUE;
}
}
Upvotes: 2