Link to home
Start Free TrialLog in
Avatar of Coast Line
Coast LineFlag for Canada

asked on

Login using AjaxCFC and loading Contents

Hi experts. i am really upto a task to build a login system. i have build the one login system which works very perfect without ajax. i mean i submit and it fetched values from query and sets some sessions and then pass to the page.

I AM ON COLDFUSION 7

i am trying to use Ajax CFC here. i am very noob in this Stuff. What i am trying to do is when i should click the login button, it should validate the form and load the contents in the <div> hiding the login form.  i mean compleetely replacing the login form.

i have the following code below:

i downloaded ajaxcfc from riaforge and placeed the ajax.cfc file in my main root folder and with the js folder too which have some files like util.js and ajax.ja and others

can some one please guide me
<cfif IsDefined('form.login')>
        	<cfinvoke component="admin.cfc.auth" method="checklog" argumentcollection="#form#" returnvariable="fm"/>
            <cfset session.userid = #fm.ID#>
            <cfset session.rsurvey = #fm.repetitivesurvey#>
            <cfset session.showresult = #fm.showresult#>
            <cfset session.sendemail = #fm.sendemail#>
            <cfset session.userpassed = True>
    		<fm:surveydisplay survey="#survey#" />               
        </cfif>
        <cfif session.userpassed IS False>
        	<cfform method="post" action="#CGI.SCRIPT_NAME#?#CGI.QUERY_STRING#">
            	<table align="center" width="100%">
                	<tr><td width="16%"><div align="right">Username</div></td>
                    <td width="84%"><div align="left">
                      <cfinput type="text" name="uname" required="yes" message="Username required">
                    </div></td></tr>
                    <tr><td><div align="right">Passwod</div></td>
                    <td><div align="left">
                      <cfinput type="password" name="upass" required="yes" message="Password required">
                    </div></td></tr>
                    <tr><td>&nbsp;</td>
                    <td><input type="submit" name="login" value="Sign In" /></td></tr>
                </table>
            </cfform>
            <cfabort>
          </cfif>

Open in new window

Avatar of azadisaryev
azadisaryev
Flag of Hong Kong image

>> "and load the contents in the <div> hiding the login form"

what contents? which <div>? on which page?
+ are you using Application.cfm or Application.cfc in this app?

Azadi
Avatar of Coast Line

ASKER

i am using application.cfm

What i am doing is:

login form is shown once session is setup, it relocates to the survey page:

as
<
cfif
 
IsDefined
(
'form.login'
)
>

                
<
cfinvoke
 
component
=
"admin.cfc.auth"
 
method
=
"checklog"
 
argumentcollection
=
"#form#"
 
returnvariable
=
"fm"
/>

            
<
cfset
 
session
.
userid
 
=
 #
fm
.
ID
#
>

            
<
cfset
 
session
.
rsurvey
 
=
 #
fm
.
repetitivesurvey
#
>

            
<
cfset
 
session
.
showresult
 
=
 #
fm
.
showresult
#
>

            
<
cfset
 
session
.
sendemail
 
=
 #
fm
.
sendemail
#
>

            
<
cfset
 
session
.
userpassed
 
=
 
True
>

                
<
fm:surveydisplay
 
survey
=
"#survey#"
 
/>
               
        
</
cfif
>


once i get logged in, it relocating to other page, while i want it show display in the div rather than page refreshing 

Open in new window

lets it make very simple, i want ajaxcfc to login and set up my session variable so it can load the contents of custom tag:
<fm:surveydisplay survey="#survey#" />              
Hi searched around and found one post from dan's Blog:

http://www.danvega.org/blog/index.cfm/2006/12/4/ajaxCFC-Login-Form

It is very nice post and it shows how can we do a login.

I am just trying same way but stuck how can i set up the session variables when it los in and after it logs in it should oad the contents in separet DIV. i mean when i gets logs in. it should show the members area in the separate DIV in the same Page:

The complete code is below here, so it is easy for experts to judge what i am trying to do.

Please experts please tell how can i set the session variables and then move to members page or loads the members page contents in a div


<script type="text/javascript">
   function submitForm() {
      authenticateUser();
      return false;   
   }
   function authenticateUser() {
      var username = $("username").value;
      var password = $("password").value;
      
      DWRUtil.useLoadingMessage();
      DWREngine._execute(_ajaxConfig._cfscriptLocation, null, 'authenticate', username,password, authenticateResults);
   }
   function authenticateResults(r) {
      // evaluate server side JS       if( eval(r) == true ) {
         $('results').innerHTML = "user ok";
      }else {
         $('results').innerHTML = "bad username / password try again";
         document.getElementById("username").style.border = "1px solid red;";
         document.getElementById("password").style.border = "1px solid red;";
      }
   }
   </script>
 
This is Dan's Component for Authentication:
 
<cfcomponent name="Security" extends="ajax" hint="I handle security in our application.">
   
   <cffunction name="authenticate" access="public" returntype="boolean" hint="I will authenticate a user">
      <cfargument name="username" type="string" required="true" />
      <cfargument name="password" type="string" required="true" />
      <cfset var isAuthenticated = false>
      
      <!--- you would replace this with db functionality --->
      <cfif arguments.username EQ "admin" AND arguments.password EQ "password">
         <cfset isAuthenticated = true>
      </cfif>
      
      <cfreturn isAuthenticated>
   </cffunction>
   
</cfcomponent>
 
this is my component for authentication
 
<cffunction name="checklog" access="public" returntype="query">
		<cfargument name="username" type="string" required="yes">
        <cfargument name="password" type="string" required="yes">
		<cfset myResult="">
        <cfquery name="myResult" datasource="#request.dsn#">
          SELECT * 
          FROM users 
          WHERE [username]=<cfqueryparam value="#arguments.username#" cfsqltype="cf_sql_clob" maxlength="255"> 
          AND npassword=<cfqueryparam value="#arguments.password#" cfsqltype="cf_sql_clob" maxlength="255">
          </cfquery>
		<cfreturn myResult>
	</cffunction>
 
 
 
<form name="frmLogin" method="post" onSubmit="return submitForm()">
      <p>
         <label for="username">Username:</label>
         <input type="text" name="username" id="username" />
      </p>
      <p>
         <label for="password">Password:</label>
         <input type="text" name="password" id="password" />
      </p>
      <p>
         <input type="submit" name="submit" value="Login">
      </p>
   </form>
   
   <div id="results"></div>

Open in new window

see attached code.
i, obviously, had to make some assumptions about your app setup, but important comments are included in code.
i have also assumed that the survey page you want to display on successful user authentication is called survey.cfm and it requires userid url parameter. change that in the code below as needed.

Azadi
<!---
1) in your page with login form include this in the <HEAD> section
[NOTE: i use jquery AjaxCFC implementation - the DWR implementation in the code sample you posted has been deprecated in the latest AjaxCFC version]
--->
<script type="text/javascript" src="path/to/jquery.js"></script>
<script type="text/javascript" src="path/to/jquery.AjaxCFC.js"></script>
<script type="text/javascript">
$.AjaxCFC({require:'json'}); // make sure json.cfc file is in same folder as your auth.cfc and ajax.cfc components!!! json.cfc comes in AjaxCFC package
$.AjaxCFCHelper.setDebug(false);
$.AjaxCFCHelper.setUseDefaultErrorHandler(true);
$.AjaxCFCHelper.setSerialization('json');
 
submitForm = function() {
 $("#loginerr").html(' ');
 authenticateUser();
 return false;   
};
 
authenticateUser = function() {
 $.AjaxCFC({
  url: "admin/cfc/auth.cfc",
  method: "checklog",
  data: {username: $("#username").val(), password: $("#password").val()},
  unnamedargs: false,
  success: function(result) {
   var userid = eval(result); 
   if (userid > 0) { //user authenticated and logged in
    //forward to survey page passing it logged-in user's id
    window.location.href='survey.cfm?userid='+userid;
    //or load survey into a div, passing user id to the survey.cfm page
    //loadsurvey(userid);
   } else { // invalid login
    $("#loginerr").html('Invalid login');
   }
  }
 });
 
loadsurvey = function(userid) {
  //fetch survey.cfm page passing it logged-in user's id, and load the page contents in #results div
  $.get('survey.cfm?userid='+userid, function(data){
    $("#loginerr").html('Invalid login'); // empty out the login error div, just in case there is an error message displayed there
    $("#frmLogin").hide().reset(); //hide the login form
    $("#results").html(data).show();
  });
};
</script>
 
<!---
2) this is your login form:
[NOTE: added ID attribute in <form> tag]
--->
<div id="loginerr"> </div><!--- login errors will be displayed in this div --->
<form name="frmLogin" ID="frmLogin" method="post" onSubmit="return submitForm();">
<p>
  <label for="username">Username:</label>
  <input type="text" name="username" id="username" />
</p>
<p>
  <label for="password">Password:</label>
  <input type="text" name="password" id="password" />
</p>
<p>
  <input type="submit" name="submit" value="Login">
</p>
</form>
<div id="results" style="display:none;width:90%;hight:auto;overflow:visible;"></div>
 
<!---
3) and this is your CFC:
[NOTE: the ajax.cfc file that comes in AjaxCFC package must be in the same folder as this cfc]
--->
<cfcomponent displayname="auth" output="no" EXTENDS="ajax">
 
<cffunction name="checklog" access="public" returntype="NUMERIC" output="no">
  <cfargument name="username" type="string" required="yes">
  <cfargument name="password" type="string" required="yes">
  <cfset VAR checkUser="">
  <cfset VAR result = 0>
  <cftry>
  <cfquery name="checkUser" datasource="#request.dsn#">
  SELECT * 
  FROM users 
  WHERE [username]=<cfqueryparam value="#arguments.username#" cfsqltype="cf_sql_clob" maxlength="255"> 
  AND npassword=<cfqueryparam value="#arguments.password#" cfsqltype="cf_sql_clob" maxlength="255">
  </cfquery>
  <cfcatch><cfset result = 0></cfcatch>
  </cftry>
  <cfif checkUser.recordcount EQ 1>
    <cfset result = checkUser.ID>
    <cflock scope="session" type="exclusive" timeout="10">
      <cfset session.userid = checkUser.ID>
      <cfset session.rsurvey = checkUser.repetitivesurvey>
      <cfset session.showresult = checkUser.showresult>
      <cfset session.sendemail = checkUser.sendemail>
      <cfset session.userpassed = True>
    </cflock>
  <cfelse>
    <cfset result = 0>
  </cfif>
  <cfreturn result />
</cffunction>
 
</cfcomponent>

Open in new window

Thanks But from where i download the latest ajaxcfc, i did download from riaforge but could not find the one you listed jquery, jquery.ajaxcfc.js file

<script type="text/javascript" src="path/to/jquery.js"></script>
<script type="text/javascript" src="path/to/jquery.AjaxCFC.js"></script>

please tell me where i should download the latest
i think there is some communication gap between our understandings.

i have one index page which lists all surveys.

like

<a href="survey.cfm?id=#id#">#name#</a>

clicking on above link load the survey page and surveyID passed in the URL.

now i have two cfinvoke statements which check if any survey is active, if yes, then it checks does it require login, if yes. the it should display the login form.

i have something below:



well here login is anbled and survey is active, but it is not showing the login form.

also when the login form shows up. you have specified:

window.location.href='survey.cfm?userid='+userid;

in 2 locations. although this concept is bit confusing to me as i have another custom tag if u see in the above posted code is:

<fm:surveydisplay survey="#survey#" />  

which dispay the surveydisplay.cfm page

so can u pleaser elaboate here how yo pass that <fm:surveydisplay survey="#survey#" /> value when login successfull. but before that login form is not being displayed.

<cfinvoke component="admin.cfc.auth" method="getSurvey" id="#trim(url.id)#" returnvariable="survey"/>
<cfinvoke component="admin.cfc.auth" method="getmain" returnvariable="login"/>
<cfif survey.active IS 1>
<cfif login.ulogin IS 1>
<script type="text/javascript" src="branches/jquery/core/js/jquery.js"></script>
<script type="text/javascript" src="branches/jquery/core/js/jquery.AjaxCFC.js"></script>
<script type="text/javascript">
$.AjaxCFC({require:'json'}); // make sure json.cfc file is in same folder as your auth.cfc and ajax.cfc components!!! json.cfc comes in AjaxCFC package
$.AjaxCFCHelper.setDebug(false);
$.AjaxCFCHelper.setUseDefaultErrorHandler(true);
$.AjaxCFCHelper.setSerialization('json');
 
submitForm = function() {
 $("#loginerr").html(' ');
 authenticateUser();
 return false;   
};
 
authenticateUser = function() {
 $.AjaxCFC({
  url: "admin/cfc/auth.cfc",
  method: "checklog",
  data: {username: $("#username").val(), password: $("#password").val()},
  unnamedargs: false,
  success: function(result) {
   var userid = eval(result);
   if (userid > 0) { //user authenticated and logged in
    //forward to survey page passing it logged-in user's id
    window.location.href='survey.cfm?userid='+userid;
    //or load survey into a div, passing user id to the survey.cfm page
    //loadsurvey(userid);
   } else { // invalid login
    $("#loginerr").html('Invalid login');
   }
  }
 });
 
loadsurvey = function(userid) {
  //fetch survey.cfm page passing it logged-in user's id, and load the page contents in #results div
  $.get('survey.cfm?userid='+userid, function(data){
    $("#loginerr").html('Invalid login'); // empty out the login error div, just in case there is an error message displayed there
    $("#frmLogin").hide().reset(); //hide the login form
    $("#results").html(data).show();
  });
};
</script>
 <div id="loginerr"> </div>
<form name="frmLogin" ID="frmLogin" method="post" onSubmit="return submitForm();">
<p>
  <label for="username">Username:</label>
  <input type="text" name="username" id="username" />
</p>
<p>
  <label for="password">Password:</label>
  <input type="text" name="password" id="password" />
</p>
<p>
  <input type="submit" name="submit" value="Login">
</p>
</form>
</cfif>
</cfif>
<div id="results" style="display:none;width:90%;hight:auto;overflow:visible;"></div>

Open in new window

it does load the form contents. clicking on survey link, i get a blank page
>> can u pleaser elaboate here how yo pass that <fm:surveydisplay survey="#survey#" /> value when login successfull

if that fm: thing is a custom tag, which it looks like it is, you can't 'pass' it to anything.
all you can do is have a page which accepts some parameter (name or id or whatever #survey# is), and executes this custom tag passing it the parameter as #survey# attribute.

so, in order to actually display the survey after a user logs in, you will need to create a separate page, which will:
a) check once again that requested survey exists and is active (same cfinvoke you already have)
b) check that a user is logged in (i.e. check that session.userpassed is true)
c) fetch and display the survey data (using your custom tag, presumably)

this is the page that $.get() should get and display in your <div>

the a) and b) above are required in this page so no smarty-pants users can just type this page's url in their browsers and view any survey without loggin in.

create a page that does the above (let's say you called it ajax_survey.cfm), and then:

1) in your authenticateUser js function:
- comment out the window.location... line
- un-comment the loadsurvey(userid); and change it to loadsurvey(<cfoutput>#trim(url.id)#</cfoutput>);

2) change the loadsurvey() function to:
loadsurvey = function(id) {
  //fetch survey.cfm page passing it logged-in user's id, and load the page contents in #results div
  $.get('ajax_survey.cfm?id='+id, function(data){
    $("#loginerr").html(' '); // empty out the login error div, just in case there is an error message displayed there
    $("#frmLogin").hide().reset(); //hide the login form
    $("#results").html(data).show();
  });
};

Azadi
but my login form is not loading up. can u please check up what is wrong.

$.get('ajax_survey.cfm?id='+id$.get('ajax_survey.cfm?id='+id

The $get load the ajax_survey.cfm in the div></div>. we can load the custom tag fm:survey="#survey#"> in the ajax_survey.cfm page.

can u see why the page does not load in when i click a link:

<a href="survey.cfm?id=#id#">#name#</a>.

then it executes the cfivoke statements to check if it is active and login is enabled then it should show the login form, but it is not showing the form.

Regards
ASKER CERTIFIED SOLUTION
Avatar of azadisaryev
azadisaryev
Flag of Hong Kong image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thnks