I have three select boxes: State, District, School. The first two work great if I don't have the school, but the school is actually the important part. Without the school select everything works fine. With the school box I get the error:
Bind failed, element not found: pid
CFC
<cfcomponent>
<cfset THIS.dsn="whatever">
<cffunction name="getDistricts" access="remote" returntype="query">
<cfargument name="state" required="yes" hint="The districts are in this state." />
<cfstoredproc datasource="#THIS.dsn#" procedure="getSchoolAndDistrict" returncode="yes">
<cfprocparam cfsqltype="cf_sql_varchar" dbvarname="#mstate" value="#arguments.state#" type="in">
<cfprocresult resultset="1" name="districts">
</cfstoredproc>
<cfreturn districts>
</cffunction>
<cffunction name="getSchools" access="remote" returntype="query">
<cfargument name="state" required="yes" hint="The districts are in this state." />
<cfargument name="pid" required="yes" hint="The district pid." />
<cfstoredproc datasource="#THIS.dsn#" procedure="getSchoolAndDistrict" returncode="yes">
<cfprocparam cfsqltype="cf_sql_varchar" dbvarname="#mstate" value="#arguments.state#" type="in">
<cfprocparam cfsqltype="cf_sql_varchar" dbvarname="#pid" value="#arguments.pid#" type="in">
<cfprocresult resultset="2" name="schools">
</cfstoredproc>
<cfreturn schools>
</cffunction>
</cfcomponent>
CFM
<cfoutput>
<cfform action="#CGI.PATH_INFO#" name="testdistricts" method="post">
<cfselect name="states" query="states"
queryPosition="below"
display="state" value="state">
<option value="">State</option>
</cfselect>
<cfselect name="districts"
bind="cfc:cfcs.getDistricts.getDistricts({states})"
queryPosition="below"
display="name" value="pid" bindonload="no">
<option value="">District</option></cfselect>
<cfselect name="schools"
bind="cfc:cfcs.getDistricts.getSchools({pid})"
queryPosition="below"
display="name" value="pid" bindonload="no">
<option value="">School</option>
</cfselect>
<br> <br>
<cfinput type="submit" name="submit" value="Submit">
</cfform>
</cfoutput>
Your problem is that the Schools select is bound to the value of the selected option instead of being bound to the district control itself...
<cfform action="#CGI.PATH_INFO#" name="testdistricts" method="post">
<cfselect name="states" query="states"
queryPosition="below"
display="state" value="state">
<option value="">State</option>
</cfselect>
<cfselect name="districts"
bind="cfc:cfcs.getDistricts.getDistricts({states})"
queryPosition="below"
display="name" value="pid" bindonload="no">
<option value="">District</option></cfselect>
<cfselect name="schools"
bind="cfc:cfcs.getDistricts.getSchools({districts})"
queryPosition="below"
display="name" value="pid" bindonload="no">
<option value="">School</option>
</cfselect>
<br> <br>
<cfinput type="submit" name="submit" value="Submit">
</cfform>
This is where your problem is
bind="cfc:cfcs.getDistricts.getSchools({districts})"
Related
I'm using CFML for my application. I need help with developing a logout operation that destroys a session. For now, on the logout link I'm calling the login page but when the BACK Button on the browser is clicked the user is still logged in.
<!---LoginForm.cfm>--->
<!---Handle the logout--->
<cfif structKeyExists(URL,'logout')>
<cfset createObject("component",'authenticationService').doLogout() />
</cfif>
<!---Form processing begins here--->
<cfif structkeyExists(form,'submitLogin')>
<!---Create an instane of the authenticate service component--->
<cfset authenticationService=createObject("component",'authenticationService') />
<!---Server side data validation--->
<cfset aErrorMessages=authenticationService.validateUser(form.userEmail,form.userPassword)>
<cfif ArrayisEmpty(aErrorMessages)>
<!---Proceed to the login procedure --->
<cfset isUserLoggedIn=authenticationService.doLogin(form.userEmail,form.userPassword) >
</cfif>
</cfif>
<!---Form processing ends here--->
<cfform>
<fieldset>
<legend>Login</legend>
<cfif structKeyExists(variables,'aErrorMessages') AND NOT ArrayIsEmpty(aErrorMessages)>
<cfoutput>
<cfloop array="#aErrorMessages#" index="message" >
<p >#message#</p>
</cfloop>
</cfoutput>
</cfif>
<cfif structKeyExists(variables,'isUserLoggedIn') AND isUserLoggedIn EQ false>
<p class="errorMessage">User not found.Please try again!</p>
</cfif>
<cfif structKeyExists(session,'stLoggedInUser')>
<!---display a welcome message--->
<p><cfoutput>Welcome #session.stLoggedInUser.userFirstName# </cfoutput>
<p>Logout</p>
<cfelse>
<dl>
<dt>
<label for="userEmail">Email address</label>
</dt>
<dd>
<cfinput type="email" name="userEmail" required="true" >
</dd>
<dt>
<label for="userEmail">Password</label>
</dt>
<dd>
<cfinput type="password" name="userPassword" required="true" >
</dd>
</dl>
<cfinput type="submit" name="submitLogin" value="Login" />
</fieldset>
</cfif>
</cfform>
<cfdump var="#session#">
<!---authenticationService.cfc--->
<cfcomponent>
<cffunction name="validateUser" access="public" output="false" returntype="array">
<cfargument name="userEmail" type="string" required="true" />
<cfargument name="userPassword" type="string" required="true" />
<cfset var aErrorMessages=ArrayNew(1) />
<!---Validate the email--->
<cfif NOT isValid('email',arguments.userEmail)>
<cfset arrayAppend(aErrorMessages,'Please,provide a valid email address') />
</cfif>
<!---Validating the Password--->
<cfif arguments.userPassword EQ ''>
<cfset arrayAppend(aErrorMessages,'Please, provide a password') />
</cfif>
<cfreturn aErrorMessages />
</cffunction>
<!---doLogin() Method--->
<cffunction name="doLogin" access="public" output="false" returntype="boolean">
<cfargument name="userEmail" type="string" required="true" />
<cfargument name="userPassword" type="string" required="true" />
<!---create the isUserLoggedIn variable--->
<cfset var isUserLoggedIn=false />
<!---get the user data from the database--->
<cfquery datasource="myapp" name="getInfo">
select * from Info
where emailid='#form.userEmail#' and password='#form.userPassword#'
</cfquery>
<!---Check if the query returns one and only one user--->
<cfif getInfo.recordcount eq 1 >
<!--- log the user in --->
<cflogin>
<cfloginuser name="#getInfo.username#" password="#getInfo.password#" roles="#getInfo.role#">
</cflogin>
<!--- save user data in session scope --->
<cfset session.stLoggedInUser={'userFirstName'=getInfo.username} />
<!---change the isUserLoggedIn variable to true--->
<cfset var isUserLoggedIn=true />
</cfif>
<!---return the isUserLoggedIn variable --->
<cfreturn isUserLoggedIn />
</cffunction>
<!---doLogout() Method--->
<cffunction name="doLogout" access="public" output="false" returntype="any">
<!---delete user from session scope--->
<cfset structDelete(session,'stLoggedInUser') />
<!---log the user out--->
<cflogout />
</cffunction>
</cfcomponent>
Regarding the back button after logout, the situation being that someone could log off and walk away from their computer without closing the browser or locking it. Then anyone else could go back on their browser and view the data they had been viewing before logging out.
We solved this for a financial application by implementing a Pragma: no-cache header on every page request. This forces requests to the page to reload from the server, not just load what's in the browser's cache. This means the back button will request the previous URL from the server, which will check session and kick you to your logged out landing page.
It will throw off some users who are used to navigating your site a certain way, but it will make it much more secure.
I have a ColdFusion 11 component which is supposed to populate a cfselect using bind. However, the select is not populated with the values at all. It shows blank. These are 2 select form controls that I want to relate to each other. A select from one should populate the other with values based on the selection made.
<td>
From IJ:
<cfselect name="im"
id="im"
bind="cfc:BTransfer.Get_Alls()"
display="strTName"
value="city_code"
queryposition="below"
bindonload="true">
<option value="">Select ...</option>
</cfselect>
</td>
<td>
To IJ:
<cfselect
name="toij"
id="toij"
bind="cfc:BTransfer.Get_Ts({city_code})"
value="strTCode"
display="strTName"
queryposition="below">
<option value="">Select ...</option>
</cfselect>
</td>
[b]The component.[/b]
<cfcomponent output="false">
<cffunction name="Get_Alls" access="remote" output="false" returntype="Query">
<cfset var qry_getall = "">
<CFQUERY NAME="qry_getall" DATASOURCE="#dsn#" cachedWithin="#CreateTimeSpan(1,0,0,0)#" >
SELECT T_Code AS strTCode,
ltrim(t_name) AS strTName,
city_code
FROM tblLookupTCity
WHERE blnactive = 1
ORDER BY T_name
</CFQUERY>
<cfreturn qry_getall />
</cffunction>
<cffunction name="Get_Ts" access="remote" output="false" returntype="Query">
<cfset var qry_getall = "">
<cfargument name="city_code" type="numeric" required="true" >
<CFQUERY NAME="qry_getall" DATASOURCE="#dsn#" cachedWithin="#CreateTimeSpan(1,0,0,0)#" >
SELECT T_Code AS strTCode,
trim(T_name) AS strTName,
city_code
FROM tblLookupTCity
WHERE CITY_CODE = '#arguments.city_code#'
AND blnactive = 1
ORDER BY T_name
</CFQUERY>
<cfreturn qry_getall />
</cffunction>
</cfcomponent>
<cffunction name="TEST" returntype="string" output="false">
<cfreturn "So your name is #name#?")>
</cffunction>
<cfif (isDefined("form.test"))>
<cfoutput>#test()#</cfoutput><br>
</cfif>
<cfform>
<cfinput name="names" type="text">
<cfinput name="TEST" type="submit" value="Call test()">
</cfform>
How to get the text from the textbox and set it in a variable?
THANKS!
This is how I would re-write this. Please note that I removed cfform and cfinput form example. They are not needed, and will likely cause issues down the road. You should pass in, as arguments, any data your function is going to need.
<cffunction name="test" returntype="string" output="false">
<cfargument name="name" type="string" required="true" />
<cfreturn "So, your name is #arguments.name#?" />
</cffunction>
<cfif isDefined("form.name") >
<cfoutput>#test( htmlEditFormat( form.name ) )#</cfoutput><br>
</cfif>
<form method="post">
<input name="name" type="text">
<input name="TEST" type="submit" value="Call test()">
</form>
We just need to pass the correct form field name to fix this issue. In form fieldname <cfinput name="names" type="text"> and the return variable name <cfreturn "So your name is #names#?"> is not same. And unwanted closebracket ")" is there. So, If we correct the code means the issue will be fixed.
<cffunction name="TEST" returntype="string" output="false">
<cfreturn "So your name is #names#?")>
</cffunction>
<cfif (isDefined("form.test"))>
<cfoutput>#test()#</cfoutput><br>
</cfif>
<cfform>
<cfinput name="names" type="text">
<cfinput name="TEST" type="submit" value="Call test()">
</cfform>
This fix answer may help you!
I tried to bind a CFGrid in ColdFusion through a CFC function which works correctly, but after login when I tried to surf to the page the CFGrid does not get populated with any records.
Here is my grid.cfm code:
<cfform name="GridForm">
<cfgrid format="html" name="UserGrid" pagesize="10" selectmode="row" bind="cfc:Consumer.getUserinfo({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection})">
<cfgridcolumn name="FirstName" width="300" header="FirstName" />
<cfgridcolumn name="LastName" width="180" header="LastName" />
<cfgridcolumn name="UserName" width="120" header="UserName" />
<cfgridcolumn name="Age" width="60" header="Age" />
</cfgrid>
<br/>
</cfform>
And here is my cfc function:
<cfcomponent output="false">
<cffunction name="getUserInfo" access="remote" returntype="struct" >
<cfargument name="page" required="true" />
<cfargument name="pageSize" required="true" />
<cfargument name="gridsortcolumn" required="true" />
<cfargument name="gridsortdirection" required="true" />
<cfif arguments.gridsortcolumn eq "">
<cfset arguments.gridsortcolumn = "FirstName" />
<cfset arguments.gridsortdirection = "asc" />
</cfif>
<cfquery name="GetUser" datasource="MyDatabase" >
select *
from UserInfo
order by #arguments.gridsortcolumn# #arguments.gridsortdirection#
</cfquery>
<cfreturn queryconvertforgrid(GetUser, page, pagesize) />
</cffunction>
</cfcomponent>
Why doesn't this grid get populated after the login?
I recommend using the developer tools / javascript console in Chrome. Turn on log XMLHTTPRequests. Then, next time you reload your app, the console will show you all of the ajax calls your app is making and if they succeed or fail.
If you have a failing request you can right click on it and open it in a new tab to see the error details just like you would normally trouble shoot a problem.
I have the following Applicaton.cfc
<cffunction name="onApplicationStart" access="public" returntype="Object">
<cfset application.dsn = "myDB" />
<cfset application.userGateway = createObject("component","cfc.UserGateway").init(dsn = application.dsn) />
<cfreturn this />
</cffunction>
This is my component UserGateway.cfc
<cfcomponent name="UserGateway" hint="Data Access Object" output="false">
<cffunction name="init" access="public" hint="constructor" output="false" returntype="UserGateway">
<cfargument name="dsn" type="string" required="true" hint="datasource" />
<cfset variables.dsn = arguments.dsn />
<cfreturn this />
</cffunction>
<cffunction name="getUsers" access="public" output="false" returntype="query">
<cfargument name="id" type="String" default="" />
<cfargument name="name" type="String" default="" />
<cfargument name="district" type="String" default="" />
<cfset var qQuery = "" />
<cfquery name="qQuery" datasource="#variables.dsn#">
SELECT *
FROM A INNER JOIN B
ON A.X = B.Y
WHERE 0=0
<cfif "#arguments.id#" neq "">
AND B.X LIKE '%#arguments.id#%'
</cfif>
<cfif "#arguments.name#" neq "">
AND (A.I LIKE '#arguments.name#%'
OR A.J LIKE '#arguments.name#%')
</cfif>
<cfif "#arguments.district#" neq "">
AND A.O LIKE '%#arguments.district#%'
</cfif>
</cfquery>
<cfreturn qQuery />
</cffunction>
</cfcomponent>
And this is my same.cfm
<cfform action="same.cfm" method="post" preservedata="true">
<p>ID: <cfinput type="text" name="id" size="20" maxlength="4" /></p>
<p>Name: <cfinput type="text" name="name" size="20" maxlength="64" /></p>
<p>District: <cfinput type="text" name="district" size="20" maxlength="3" /></p>
<p><cfinput class="button" type="submit" name="submit" value="OK" /></p>
</cfform>
<cfif IsDefined("form.submit")>
<table>
<cfset qQuery = application.userGateway.getUsers(id = form.id, name = form.name, district = form.district) />
<cfoutput query="qQuery">
<tr>
<td>#qQuery.currentRow#.</a></td>
<td>#qQuery.I#</a></td>
<td>#qQuery.M#, #qQuery.N#</a></td>
<td>#qQuery.D#</a></td>
</tr>
</cfoutput>
</table>
</cfif>
I get the following error:
Element USERGATEWAY is undefined in a Java object of type class [Ljava.lang.String;.
The error occurred in same.cfm: line 10
What am i missing?
-------------------------------------------
-------------------------------------------
When i do it this way it works. it must be something trivial that i as a beginner do not get.
Application.cfc
<cffunction name="onRequestStart" access="public" returntype="String">
<cfset request.dsn="myDB" />
</cffunction>
same.cfm
<cfset userGateway = createObject("component","cfc.UserGateway").init(dsn = request.dsn) />
<cfset qGetUser = userGateway.getUsers(id = form.personid, name = form.name, district = form.district) />
<cfoutput query="qQuery">
<tr>
<td>#qQuery.currentRow#.</a></td>
<td>#qQuery.I#</a></td>
<td>#qQuery.M#, #qQuery.N#</a></td>
<td>#qQuery.D#</a></td>
</tr>
</cfoutput>
There are two things I see wrong here:
First, To my understanding, using the 'this' scope in application.cfc doesn't work the way you're trying to do it. By setting your userGateway object to an application scoped value, it becomes globally available and really makes returning it in onApplicationStart unnecessary. In your application.cfc, change your returntype to boolean and just return true; that should fix your problem.
Second, if in your query, your arguments and conditionals are not proxies of what you actually have, you're referencing an argument 'personid' which does not exist in your function. When calling that query through an object call in the application scope, I've seen the java string error returned as an error before as opposed to the CF Friendly 'variable doesn't exist' error.
In same.cfm, run this:
<cfset OnApplicationStart()>
Then refresh the page again. Does it now work?
<cffunction name="init" access="public" hint="constructor" output="false" returntype="UserGateway">
should be:
<cffunction name="init" access="public" hint="constructor" output="false" returntype="Any">
The following line is incorrect:
<cfset application.userGateway = createObject("component","cfc.UserGateway").init(dsn = application.dsn) />
It should read with out "cfc." at the beginning of the component name you want:
<cfset application.userGateway = createObject("component","UserGateway").init(dsn = application.dsn) />
Also, double check the rest of the application.cfc for correctness because something isn't running right, as you should have seen this error that it couldn't find component cfc.UserGateway.
EDIT:
I also forgot to mention that onApplicationStart does not need to return anything. The return type should be void and no <return this/> needs to be present.
Could it be this:
http://kathylynnward.wordpress.com/2008/04/14/lyra-captcha-error-element-captcha-is-undefined-in-a-java-object-of-type-class-ljavalangstring/
(I'll elaborate the post if this is the problem)
restart your CF service might help.