Welcome Guest, Not a member yet? Register   Sign In
[TUTORIAL] *UPDATED* Using jQuery and CI for a AJAX Login (v0.2) + example rar
#1

[eluser]Isern Palaus[/eluser]

IMPORTANT!!

ipalaus-ajaxlogin v0.2 is now out, check it here!
Quote:I've updated the script to clarify the concepts. Now we are using the Redux Authentication library to manage the users and we only shows how to login with ajax.

IMPORTANT!!


------------

------------
THE OLD ONE!
------------

------------

Hello friends,

My name is Isern Palaus and I'm from Spain. I say this because my English is not fine and I'll try to explain how to develop a AJAX Login in English Confusedhut: .

One of the most problem when the people starts coding is the needed of another to see what to do. The user guide of CI is one of the best I've ever read, but sometimes the newbies needs more. Personally I talked with the creator of CodeExtinguisher developer for using the pagination class and he shows me a Model Controller View that helped me a lot. Now it's my time and I'll try to explain how to do a little AJAX Login.

For this we need the last jQuery, you can download it on the official jQuery website. Then, obviously, Code Igniter.

We will start with the database. It's simple because usually I separate the user from her profile.

Code:
CREATE TABLE `users` (
  `uid` int(10) NOT NULL auto_increment,
  `username` varchar(16) NOT NULL,
  `password` varchar(32) NOT NULL,
  `email` varchar(128) NOT NULL,
  `time` int(10) NOT NULL,
  PRIMARY KEY  (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

In this tutorial I'll use md5, I prefer SHA-1 but the site I developed I used md5 :long: . Then, I'll start with the controller and the model.

It's called user and it controls the register/login/logout but I'll only show the second term.

Code:
<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

class User extends Controller {

    function User() {
        parent::Controller();
        
        $this->load->model("user_model");
        $this->load->model("dalia_model");
        
        $this->load->helper("security");
        $this->load->helper("form");
    }
    
    /* Checks if the password that the user gives is equal at the DB ones */
    function _check_login($username) {
        $password = md5($this->validation->password);
        
        if(!$this->user_model->checkUserLogin($username,$password,"users"))
            return FALSE;
            
        return TRUE;
    }
    
    function index() {
        $this->load->view("userLogin");
    }

    function checkLogin()
    {
        $this->load->library('validation');
        $rules['username'] = 'trim|required|callback__check_login';
        $rules['password'] = 'trim|required';
        $this->validation->set_rules($rules);
        
        $fields['username'] = 'username';
        $fields['password'] = 'password';
        $this->validation->set_fields($fields);
        
        if ($this->validation->run()) {
            $username     = $this->validation->username;
            $uid         = $this->user_model->getUserId($username,"users");
            
            $this->session->set_userdata("logged_in",$uid);
            
            $output = '{ "success": "yes", "welcome": "Welcome" }';
        } else {
            $output = '{ "success": "no", "message": "This is not working" }';
        }
        
        $output = str_replace("\r", "", $output);
        $output = str_replace("\n", "", $output);
        
        echo $output;
    }
    
    function logout()
    {
        $this->session->sess_destroy();
        redirect("");
    }

}

?>

With jQuery we need a function that returns to the script the output. This function is checkLogin(), later you will see where I used it. If you look at this function now, you can see how I validate the terms. At the first rule:

Code:
$rules['username'] = 'trim|required|callback__check_login';

I use a callback to _check_login to check the if the username and password is valid. If we look to this function you will see that it uses a model:

Code:
function _check_login($username) {
    $password = md5($this->validation->password);
    
    if(!$this->user_model->checkUserLogin($username,$password,"users"))
        return FALSE;
        
    return TRUE;
}

First we encrypt the $password term from the form to md5, because we already have the password in md5 at database. Then we check if the content of the checkUserLogin is NULL or not. If it's NULL its because the username/password aren't valids. Else, it's TRUE ;-) . Then its time for the model:

It's named user_model.
Code:
<?php
class User_model extends Model
{
    function __construct()
    {
        parent::__construct();
    }
    
    function checkUserLogin($username,$password,$table=users)
    {
        $query = $this->db->where("username",$username);
        $query = $this->db->where("password",$password);
        $query = $this->db->limit(1,0);
        $query = $this->db->get($table);
        
        if ($query->num_rows() == 0) {
            return NULL;
        }
        
        return TRUE;
    }
}
?>

You can see that the function checkUserLogin gets the $username, $password and $table (I EVER use $table in my functions because if I need use this user system in another project probably the user table is named differently (It's ever user but in case...)).

A simple database class use that checks first for the username and later for the password. If the num_rows() returned is equal a 0 it is because isn't valid. Else we return TRUE.

Now we have the checkLogin working. It's time to see how to use it on a view. The controller is simple, because this login doesn't needs that. Only a $this->load->helper("form");.
#2

[eluser]Isern Palaus[/eluser]
There's no more characters allowed, I continue in a reply.

I named my view baseHeader.php because I want to see the AJAX login on EVERY page:
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
&lt;html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"&gt;

    &lt;head&gt;    
        &lt;title&gt;Test &lt;?php if (isset($webTitle)) { echo ":: ".$webTitle; } ?&gt;&lt;/title&gt;
        &lt;link href="&lt;?=base_url();?&gt;content/css/main.css" rel="stylesheet" type="text/css" /&gt;
        
        
        
        
        
        &lt;!-- Extra Head Content --&gt;
        &lt;?php
            if (isset($extraHeadContent)) {
                echo $extraHeadContent;
            }
        ?&gt;
        &lt;!-- Extra Head Content --&gt;
        
        &lt;meta http-equiv="Content-Type" content="text/html;charset=utf-8" /&gt;
    &lt;/head&gt;
    
    &lt;body&gt;
    
        <div id="content">
        
            <div id="header">
            
                <div id="logo">
                    <img src="&lt;?=base_url();?&gt;content/img/logo.png" width="321px" height="111px" alt=" " />
                </div>
                
                <div id="login">
                    &lt;?php
                        if($this->session->userdata('logged_in')) {
                    ?&gt;
                            <div id="logged">
                                Welcome, you're already logged In.
                            </div>
                    &lt;?php
                        }
                        
                        else  {
                    ?&gt;
                            <div id="loginform">
                                &lt;?=form_open('user/login',array('id' => 'userlogin'));?&gt;
                                    <label for="username">Username:</label>
                                    &lt;input class="logininput" type="text" name="username" id="username"  /&gt;
                                     <label for="password">Password:</label>
                                    &lt;input class="logininput" type="password" name="password" id="password" /&gt;        
                                    &lt;input class="loginsubmit" type="submit" value="Login" /&gt;
                                &lt;?=form_close();?&gt;
                            </div>
                            <div id="logged"></div>
                            <div id="loginerror"></div>
                    &lt;?php
                        }
                    ?&gt;
                    
                </div>
                
            </div>
            
            <div id="body">

You can see in the middle of the script that I used a if like this:

Code:
if($this->session->userdata('logged_in')) {

This is because I check if the user is already logged in. If it's logged I will show him the personal menu or a simple welcome. Else we will show the form for the user login:

Code:
<div id="loginform">
    &lt;?=form_open('user/login',array('id' => 'userlogin'));?&gt;
        <label for="username">Username:</label>
        &lt;input class="logininput" type="text" name="username" id="username"  /&gt;
        <label for="password">Password:</label>
        &lt;input class="logininput" type="password" name="password" id="password" /&gt;        
        &lt;input class="loginsubmit" type="submit" value="Login" /&gt;
    &lt;?=form_close();?&gt;
</div>
<div id="logged"></div>
<div id="loginerror"></div>

This a simple form with form_open. I used a action on it for the non-JS browser can login. Then check the two divs with id logged and loginerror. This two are needed, we can use only one but I prefer two. (In the second I've on the CSS a color:redWink.
#3

[eluser]Isern Palaus[/eluser]
Lets see the jQuery ones:
Code:
$(document).ready(
    function(){
    
        $("#userlogin").ajaxForm({
            type: "POST",
            url: "http://localhost/dalia/trunk/public_html/index.php/user/checkLogin",
            dataType: "json",
            data: "username="+$("#username").val()+"&password;="+$("#password").val(),
            success: updateLogin
        });
    
    }
)

You can see how I use the ids to set the jQuery form. For use ajaxForm we will need the jQuery Form plugin you can download it on the official webpage for the jQuery form or the jQuery Plugins section.

Code:
type: "POST", // We use post for the login form
url: ""http://localhost/dalia/trunk/public_html/index.php/user/checkLogin", // We will call the function of the user controller
dataType: "json", // Its the type of the data we send. A json looks like: { "success": "yes", "message": "in a bottle" }
data: "username="+$("#username").val()+"&password;="+$("#password").val(), // The data we sent to the url, the inputs of the form have id=username and id=password
success: updateLogin // What happens when the function success I personally separate this from the ajaxForm

Now the updateLogin term:
Code:
function updateLogin(data) {
    $('#logged').html('');
    $('#logged').hide();
    
    $("#loginform").fadeOut("slow",
        function() {
             if (data.success == 'yes') {
                $('#logged').html(data.welcome).fadeIn("slow");    
            }
            
            if (data.success == 'no') {
                $('#loginerror').html(data.message).fadeIn("slow").fadeOut("slow",
                    function() {
                        $("#loginform").fadeIn("slow");
                    }
                );    
            }
        }
    );
    
}

Its so easy, if data.success send by the controller isn't valid we show de data.message in the #loginerror id (remember the div) and the login appears another time. If the data is valid the form disappears and we write the data.message.

And then... It's now working. Remember to check that you included the correct javascript files on the view after start asking :-P .

I hope you like it,
-- Isern Palaus
#4

[eluser]Jay Turley[/eluser]
Very nice tutorial and example of integrating an ajax call into a CI application.
#5

[eluser]sexy22[/eluser]
Very grateful。。。
#6

[eluser]Isern Palaus[/eluser]
Thanks :-)!

Regards,
-- Isern Palaus
#7

[eluser]Nick Husher[/eluser]
Note that if you're using PHP5, you can use the super-fabulistic json_encode to build json response objects:
Code:
$data = array(
     'method'=>'user_login',
     'response'=>'success',
     'message'=>'You have logged in successfully!'
    );
$output = json_encode($data);

It's very nice when you have large AJAX response objects to pass around.
#8

[eluser]Isern Palaus[/eluser]
[quote author="Nick Husher" date="1203202733"]Note that if you're using PHP5, you can use the super-fabulistic json_encode to build json response objects:
Code:
$data = array(
     'method'=>'user_login',
     'response'=>'success',
     'message'=>'You have logged in successfully!'
    );
$output = json_encode($data);

It's very nice when you have large AJAX response objects to pass around.[/quote]

Hey Nick Husher,

Nice to know. It's best that build yourself. ;-)

Thank you,
-- Isern Palaus
#9

[eluser]fdog[/eluser]
Great tutorial! Is this in the wiki?
#10

[eluser]Isern Palaus[/eluser]
[quote author="fdog" date="1203321020"]Great tutorial! Is this in the wiki?[/quote]

Not at the moment. I'll put on it soon.

Thanks for all!




Theme © iAndrew 2016 - Forum software by © MyBB