Brandon G
Brandon G

Reputation: 27

Newbie, very basic CRUD via Application.cfc

So I've been using in-line (correct term?) ColdFusion code to run all my pages and have gotten to a point where I think I have a decent understanding of the basics, and want to take the next step. After a lot of cross-referencing, research, and trial and error, I've come up with the following 4 pages of which the intent is to be able to enter a username and password in the form page (crud.cfm), then, after submission, redirect the user to a page which displays the newly entered data, as well as any past entries.

I can do all of this with simple in-line code and an Application.CFM but I want to migrate toward a more OOP/Modular approach going forward, as presently I find myself rewriting/copy-pasting scads of code across several different pages. The error that I get when I submit from 'crud.cfm' is:

"The component attribute in cfinvoke tag has invalid value."

I have tried it without hashes and without the uppercase "A" to no avail. Here is my non-working code:

Application.cfc

<cfcomponent output="false">
<cffunction name="insertrecord" access="public" output="false">
    <cfargument name="data" type="struct" required="true">
    <cfquery name="create" datasource="test">
        INSERT INTO logins(
            username,
            password)
        VALUES(
            'trim(form.username)',
            'trim(form.password)')
    </cfquery>
</cffunction>
</cfcomponent>

crud.cfm

<h3> Enter new user/password </h3>

<cfform name="thisform" method="post" action="procpage.cfm">
    Username:<cfinput type="text" name="username" value="">
    Password:<cfinput type="password" name="password" value="">
    <input type="submit" value="submit">
</cfform>

procpage.cfm

<cfif !StructIsEmpty(form)>
<cfinvoke component="#Application#" method="insertrecord">
    <cfinvokeargument name="data" value="#form#">
</cfinvoke>
</cfif>

<cflocation url="resultpage.cfm" addtoken="no">

resultpage.cfm

<cfquery name="read" datasource="test">
SELECT * FROM logins
</cfquery>

<table>
<tr>
    <th>LOGIN</th>
    <th>USERNAME</th>
    <th>PASSWORD</th>
</tr>
<cfloop query="read">
<tr>
    <td>#read.login#</td>
    <td>#read.username#</td>
    <td>#read.password#</td>
</tr>
</cfloop>   
</table>

ColdFusion version 8, MSSQL 2005 database. Thank you all in advance for your help, looking forward to your responses!

Upvotes: 1

Views: 758

Answers (2)

Lance
Lance

Reputation: 3213

In answer to your question to Miguel, Yes. The application.cfc is called each time a cfm is called. So when you hit the crud.cfm, application.cfc runs. When you hit procpage.cfm application.cfc runs etc..

so you want your procpage.cfm to look more like

<cfif !StructIsEmpty(form)>
<cfinvoke component="functions" method="insertrecord">
    <cfinvokeargument name="data" value="#form#">
</cfinvoke>
</cfif>

and your functions.cfc looks more like

<cfcomponent output="false">
<cffunction name="insertrecord" access="public" output="false" returntype="void">
    <cfargument name="data" type="struct" required="true">
    <cfquery name="create" datasource="test">
        INSERT INTO logins(
            username,
            password)
        VALUES(
            <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.username)#">,
            <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.password)#">
              )
    </cfquery>
</cffunction>

<cffunction name="readRecord" access="public" returntype="query">
    <cfargument name="loginID" type="numeric" required="false" default="0">
        <cfquery name="read" datasource="test">
            SELECT * FROM logins 
            where loginID = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.loginID#">
        </cfquery>
        <cfreturn read/>
</cffunction>
</cfcomponent>

resultsPage.cfm

<cfscript>
  f = createObject('component','functions');
  r= f.readRecord(theIdToPass);
</cfscript>
<table>
<tr>
    <th>LOGIN</th>
    <th>USERNAME</th>
    <th>PASSWORD</th>
</tr>
<cfloop query="r">
<tr>
    <td>#r.login#</td>
    <td>#r.username#</td>
    <td>#r.password#</td>
</tr>
</cfloop>   
</table>

You will find that cfqueryparam not only has a small performance boost but will protect you from sql attacks and such, USE IT!! Always.

You also might think about doing arguments for each one expect instead of using struct variables, since writting error trapping for a struct without know what you are expecting to be passed can be pretty frustrating.

Hopefully this can get you off to a positive start with CF!

Upvotes: 1

Billy Cravens
Billy Cravens

Reputation: 1663

Application.cfc is a special file in ColdFusion.

http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=AppEvents_01.html

You'll need to name your component something else. Application.cfc is where you put Application events, setup code, etc.

Upvotes: 2

Related Questions