My Codeigniter
site has side panel and when i click or select any options in side panel appropriate content will appear to the main panel.
Home page URL
is http://localhost/main/userinfo/allusers
When i click female button URL
is http://localhost/main/userinfo/female
i have following output when i made the Ajax request. Where i did the mistake?
Controller(main.php)
class Main extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->model('userinfo_model');
}
public function index() {}
public function userinfo($gender) {
$this->load->view('home/inc/header_view');
$usermain_data['user_info'] = $this->userinfo_model->get_data($gender);
$this->load->view('home/main_view', $usermain_data);
}
Model(userinfo_model.php)
class Userinfo_model extends CI_Model {
function __construct() {
// Call the Model constructor
parent::__construct();
}
function get_data($gender) {
$this->db->select('*');
if($gender == 'female'){
$this->db->where('gender', 0);
}
elseif($gender == 'male'){
$this->db->where('gender', 1);
}
elseif($gender == 'allusers'){
$gNames = array(0, 1);
$this->db->where_in('gender', $gNames);
}
else {
redirect(base_url() . 'main/userinfo/allusers');
}
$query = $this->db->get('tble_userinfo');
//return $query->result();
echo(json_encode($query->result()));
}}
View(main_view.php)
<div class="container">
<div class="row">
<div class="col-md-3 side_menu">
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default gender-label" id="lbl-female" onclick="displayfemale()">
<input type="radio" name="options" id="option1" autocomplete="off">
<span>Female</span>
</label>
<label class="btn btn-default gender-label" id="lbl-male" onclick="displaymale()">
<input type="radio" name="options" id="option2" autocomplete="off">
<span>Male</span>
</label>
</div> <br> <br>
<label class="label nav-label">Age</label>
<select class="btn nav-age-select" id="ageSelect1" autocomplete="off">
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21" selected="selected">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
</select>
<label class="label nav-label label-to">To</label>
<select class="btn nav-age-select" id="ageSelect2" autocomplete="off">
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25" selected="selected">25</option>
</select>
</div>
<div class="col-md-8 main-body">
<div id="userdata">
<?php
//foreach ($user_info as $info) {
//confuse of adding date here with ajax
//echo $info->content . '<br />' . $info->added_date .'<br />';
//}
?>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
var ajaxUrl = '<?php echo base_url(); ?>' + 'main/userinfo';
var gender = 'allusers'; // defual 1 for female and male both together
getAjax(ajaxUrl, gender);
$("#lbl-female").click(function () {
gender = 'female';
getAjax(ajaxUrl, gender);
});
$("#lbl-male").click(function () {
gender = 'male';
getAjax(ajaxUrl, gender);
});
});
function getAjax(ajaxUrl, gender){
ajaxUrl = ajaxUrl + '/' + gender;
$.ajax({
url: ajaxUrl,
dataType: "JSON",
type: "POST",
success: function (retdata) {
$("#userdata").html('');
if(retdata.hasOwnProperty("error")){
$("#userdata").html('<div">' + retdata.msg + '</div>');
}
else{
$.each(retdata, function(i){
$("#userdata").append(retdata[i].content + '<br>');
});
}
}
});
}
This answer will have main
load both genders initially. Rather than use several gender specific URLs the gender buttons will return the html of the selected gender and dynamically change the html of the page.
main_view.php (with Javascript included)
<div class="container">
<div class="row">
<div class="col-md-3 side_menu">
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default gender-label" id="lbl-female">
<input type="radio" name="options" id="option1" autocomplete="off">
<span>Female</span>
</label>
<label class="btn btn-default gender-label" id="lbl-male">
<input type="radio" name="options" id="option2" autocomplete="off">
<span>Male</span>
</label>
</div> <br> <br>
<label class="label nav-label">Age</label>
<select class="btn nav-age-select" id="ageSelect1" autocomplete="off">
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21" selected="selected">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
</select>
<label class="label nav-label label-to">To</label>
<select class="btn nav-age-select" id="ageSelect2" autocomplete="off">
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25" selected="selected">25</option>
</select>
</div>
<div class="col-md-8 main-body">
<div id="userdata">
<?php
foreach($user_info as $info)
{
echo $info->content.'<br />'.$info->added_date.'<br />';
}
?>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
var ajaxUrl = '<?php echo base_url(); ?>' + 'main/userinfo';
$("#lbl-female").click(function () {
getAjax(ajaxUrl, 'female');
});
$("#lbl-male").click(function () {
getAjax(ajaxUrl, 'male');
});
});
function getAjax(URL, gender) {
$.ajax({
url: URL,
data: {gender: gender},
dataType: "html",
type: "POST",
success: function (retdata) {
$("#userdata").html(retdata);
}
});
}
</script>
Note that in the $.ajax
options with the line
data: {gender: gender},
we are "posting" data to the controller which will be retrieved by using $this->input->post("gender");
in the AJAX response function.
Models should not do anything but return data for a controller to use. It is the controller's job to determine what happens based on the data returned. So the redirect()
call has been removed.
Userinfo_model.php
class Userinfo_model extends CI_Model
{
function __construct()
{
// Call the Model constructor
parent::__construct();
}
// Note the default value for argument $gender.
// This means you do not have to pass an argument.
// If you don't pass one, then !empty($gender) === FALSE
function get_data($gender = NULL)
{
$this->db->select('*');
//select based on gender.
//If no $gender then a "where" clause is not needed and both genders are selected
if(!empty($gender))
//an argument was provided
{
if($gender == 'female')
{
$this->db->where('gender', 0);
}
else
{
$this->db->where('gender', 1);
}
}
$query = $this->db->get('tble_userinfo');
return $query->result();
}
}
Finally, we get to the controller. index()
will display both genders by calling get_data()
without passing an argument to the model. After that the AJAX responder userinfo()
will return html of the desired gender to the ajax success
function. The success
function will replace the existing html with the new html echoed from userinfo()
.
class Main extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('userinfo_model');
}
public function index()
{
$usermain_data['user_info'] = $this->userinfo_model->get_data();
$this->load
->view('home/inc/header_view')
->view('home/main_view', $usermain_data);
}
//Only used to respond to an AJAX request
public function userinfo()
{
$gender = $this->input->post('gender');
if(empty($gender))
{
$out = "No Users Found";
}
else
{
$user_info = $this->userinfo_model->get_data($gender);
$out = "";
foreach($user_info as $info)
{
$out .= $info->content.'<br />'.$info->added_date.'<br />';
}
}
echo $out;
}
}
This seems reasonably secure so far. The only user input is the gender value. (Never trust user input) Should someone try to pass a value other than the string "female" the database will return only the males info. No user input is presented directly to the database so I don't see any vulnerabilities.