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>
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'm trying to use autocomplete with a field with commas in it. When I type the comma it will ignore it, and won't return anything. So far I have this:
index.cfm
<!--- A simple form for auto suggest --->
<cfform action="autosuggest.cfm" method="post">
Artist:
<cfinput type="text" name="artist" size="50" autosuggest="cfc:autosuggest.findartist({cfautosuggestvalue})" autosuggestminlength="4" maxresultsdisplayed="5" /><br /><br />
</cfform>
autosuggest.cfc
<cfcomponent output="false">
<!--- Lookup used for auto suggest --->
<cffunction name="findartist" access="remote" returntype="string">
<cfargument name="search" type="any" required="false" default="">
<!--- Define variables --->
<cfset var local = {} />
<!--- Query Location Table --->
<cfquery name="local.query" datasource="#application.datasource#" >
select DISTINCT artist
from items
where artist like <cfqueryparam cfsqltype="cf_sql_varchar" value="#ucase(arguments.search)#%" />
order by artist
</cfquery>
<!--- And return it as a List --->
<cfreturn valueList(local.query.artist)>
</cffunction>
</cfcomponent>
When I try to search for example Brown,James it doesn't return anything. What do I need to put in it to return results with commas.
Thanks
One option is to have your function return an array, instead of a string. Then delimiters are not an issue.
<cffunction name="findartist" access="remote" returntype="array">
...
<cfreturn listToArray(valueList(local.query.artist, chr(30)), chr(30))>
</cffunction>
Update:
As Raymond pointed out, the only sure-fire way to avoid delimiter issues on the CF side is not to use them. Instead loop through the query to build the array, ie:
<cffunction name="findartist" access="remote" returntype="array">
...
<cfset local.arr = []>
<cfloop query="local.query">
<cfset arrayAppend(local.arr, local.query.artist)>
</cfloop>
<cfreturn local.arr>
</cffunction>
I have a text field that I want to autosuggest values based on a query. I have a main file along with a separate file (getdata.cfc) that holds my query.
Here is the text field portion of my main file:
<cfinput name="search_query" autosuggest="url:getdata.cfc?suggestvalue={cfautosuggestvalue}" maxResultsDisplay="10" showAutoSuggestLoadingIcon="true" size="10" />
Here is the code in getdata.cfc:
<cfcomponent>
<cffunction name="get_data" access="remote" output="false">
<cfargument name="suggestvalue" required="true">
<cfquery name="get_data" datasource="#application.DSN#">
SELECT DISTINCT myItem
FROM myTable
WHERE myItem LIKE <cfqueryparam value="#suggestvalue#%"
cfsqltype="cf_sql_varchar">
ORDER BY myItem
</cfquery>
<cfif get_data.recordCount eq 1>
<cfreturn ",#get_data.myItem#">
<cfelse>
<cfreturn ValueList(get_data.myItem)>
</cfif>
</cffunction>
</cfcomponent>
The text field shows up fine, but when I type a word no autosuggest values show up. Nothing happens. The text is just displayed as I type it.
Any suggestions? Thank you!
I switched away to using jquery plugins from a lot of CF stuff, but here is an example I have that works in some old production code
<cfinput type="text" name="email" id="email" autosuggest="cfc:cfc.users.lookupEmail({cfautosuggestvalue})" maxresultsdisplayed = "25">
<cffunction name="lookupEmail" access="remote" returntype="array">
<cfargument name="search" type="any" required="false" default="">
<!--- Define variables --->
<cfset var data="">
<cfset var result=ArrayNew(1)>
<!--- Do search --->
<cfquery name="data" datasource="datasource" maxrows="25" cachedwithin="#CreateTimeSpan(0,0,30,0)#">
SELECT distinct email
FROM users
WHERE email LIKE <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.search#%">
ORDER BY email
</cfquery>
<!--- Build result array --->
<cfloop query="data">
<cfset ArrayAppend(result, email)>
</cfloop>
<!--- And return it --->
<cfreturn result>
</cffunction>
maybe this helps
also make sure you have your cfform tags around your form, and make sure that your /cfide folder is mapped to your website.
looking at your code and comparing it... it may be the way your calling the cfc (filename)
try: autosuggest="cfc:getdata.get_data.({cfautosuggestvalue})"
I have a query loop and inside that loop, I make a cfc function call to return a second query. It's doing weird things with the display:
In the example below, instead of making a function call to obtain the second query, I create a simple loop. This displays fine. View the actual page here
<cfoutput>
<cfif qCal.recordcount>
<a class="control" onClick="return hs.getExpander(this).printHtml()" href="##">Print</a>
</cfif>
<table width="100%" cellspacing="0" cellpadding="4">
<cfloop query="qCal">
<tr>
<td align="middle" valign="top" style="width:150px;">
<a title="View full-sized image" onclick="return hs.expand(this)" href="/images/classes/#qCal.image#" class="highslide"><img src="/images/classes/#qCal.thumb#" class="resize2"></a></td>
<td>
<table cellspacing="0" cellpadding="3">
<tr>
<td colspan="2" class="textNormal"><h2>#qCal.title#</h2></td>
</tr>
<tr>
<td class="textNormal"><strong>Date:</strong></td>
<td class="textNormal"><strong>Time:</strong></td>
</tr>
<cfloop from="1" to="5" index="i"> <!--- basic loop --->
<tr>
<td>#i#</td>
<td></td>
</tr>
</cfloop>
</table>
</td>
</tr>
</cfloop>
</table>
</cfoutput>
But, as soon as I make a function call to obtain a secondary query, inexplicable things happen with the display. View the actual page here (which renders half-cooked html code).
<cfoutput>
<cfif qCal.recordcount>
<a class="control" onClick="return hs.getExpander(this).printHtml()" href="##">Print</a>
</cfif>
<table width="100%" cellspacing="0" cellpadding="4">
<cfloop query="qCal">
<cfsilent>
<cfset qCalItems = o_system.getCalendarItems(
start=dateformat(vStartDate,"yyyy-mm-yy"),
end=dateformat(vEndDate,"yyyy-mm-yy"),
classID=qCal.classID,
forQuarterlyCalendar=true,
order_by="i.startDate")>
</cfsilent>
<tr>
<td align="middle" valign="top" style="width:150px;">
<a title="View full-sized image" onclick="return hs.expand(this)" href="/images/classes/#qCal.image#" class="highslide"><img src="/images/classes/#qCal.thumb#" class="resize2"></a></td>
<td>
<table cellspacing="0" cellpadding="3">
<tr>
<td colspan="2" class="textNormal"><h2>#qCal.title#</h2></td>
</tr>
<tr>
<td class="textNormal"><strong>Date:</strong></td>
<td class="textNormal"><strong>Time:</strong></td>
</tr>
<cfloop query="qCalItems">
<tr bgcolor="#iif(qCalItems.CurrentRow MOD(2) eq 1,de('ffffff'),de('EFEFEF'))#">
<td>#DayOfWeekAsString(dayofweek(qCalItems.startDate))# #dateformat(qCalItems.startDate,"dd mmm yyyy")#</td>
<td>#qCalItems.startTime#-#qCalItems.endTime#</td>
</tr>
</cfloop>
</table>
</td>
</tr>
</cfloop>
</table>
</cfoutput>
UPDATE - CFC CODE ADDED
NOTE: Function returns either a struct or a query depending on the argument "forQuarterlyCalendar". It definitely returns a query object in this case. I have dumped the query out and confirm that it is a valid query object.
<cffunction name="getCalendarItems" access="remote" returntype="any" output="false" returnformat="json">
<cfargument name="classID" type="any" required="false" default="">
<cfargument name="forSelect" type="boolean" required="false" default="false">
<cfargument name="forQuarterlyCalendar" type="boolean" required="false" default="false">
<cfargument name="start" type="any" required="false" default="">
<cfargument name="end" type="any" required="false" default="">
<cfargument name="order_by" type="any" required="false" default="c.title">
<cfargument name="sort_direction" type="any" required="false" default="asc">
<cfargument name="json" type="boolean" required="false" default="true">
<cfargument name="must_have_store_item" type="boolean" required="false" default="true">
<cfset var qClass = 0>
<cfset var realStart = "">
<cfset var realEnd = "">
<cfset var results = []>
<cfset var vUrl = "">
<cfset var vId = "">
<cfset var vTitle = "">
<cfset var vStart = "">
<cfif len(trim(arguments.start))>
<cfset realStart = EpochTimeToLocalDate(arguments.start)>
</cfif>
<cfif len(trim(arguments.end))>
<cfset realEnd = EpochTimeToLocalDate(arguments.end)>
</cfif>
<cfquery name="qClass" datasource="#application.datasource#">
select <cfif arguments.forSelect>
c.title, i.calendarItemID as id, convert(varchar, i.startDate, 103)+' '+i.startTime+'-'+i.endTime as text
<cfelseif arguments.forQuarterlyCalendar>
c.description, i.calendarItemID as id, i.startDate, i.startTime, i.endTime
<cfelse>
i.calendarItemID, i.startDate, i.startTime, i.endTime
,c.classID, c.title, c.description, c.price, c.places, c.exclusive, c.discounted, c.url
,s.storeItemID
</cfif>
from calendarItem i
<cfif arguments.must_have_store_item>
join storeItem s on s.entityID = i.calendarItemID and s.storeItemTypeID = 3
</cfif>
join class c on c.classID = i.classID and c.active=1
where i.active=1
<cfif isnumeric(arguments.classID)>
and i.classID = <cfqueryparam value="#arguments.classID#" cfsqltype="cf_sql_integer">
</cfif>
<cfif len(trim(arguments.start))>
<cfif arguments.forQuarterlyCalendar>
and i.startDate >= <cfqueryparam value="#arguments.start#" cfsqltype="cf_sql_date">
<cfelse>
and i.startDate >= <cfqueryparam value="#dateformat(realStart,'yyyy-mm-dd')#" cfsqltype="cf_sql_date">
</cfif>
</cfif>
order by #arguments.order_by# #arguments.sort_direction#
</cfquery>
<cfif qClass.recordcount>
<cfif not arguments.forSelect and not arguments.forQuarterlyCalendar>
<cfloop query="qClass">
<cfset vUrl = qClass["url"]>
<cfset vId = qClass["storeItemID"]>
<cfset vTitle = qClass["title"]>
<cfset vStart = GetEpochTimeFromLocal(qClass.startDate)>
<cfif not len(trim(url)) or len(trim(url)) is 0>
<cfset vUrl = "#application.webroot#/class_detail.cfm?id=#vId#">
</cfif>
<cfset s = structnew()>
<cfset s["id"] = vId>
<cfset s["url"] = vUrl>
<cfset s["title"] = vTitle>
<cfset s["start"] = vStart>
<cfset arrayappend(results, s)>
</cfloop>
<cfelse>
<cfset results = qClass>
</cfif>
</cfif>
<cfif arguments.json>
<cfcontent type="application/json">
</cfif>
<cfreturn results>
</cffunction>
You need to var scope 's':
<cfset s = structnew()>
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.