I am new to ColdFusion and I was hoping for some advice. I created a super basic shopping list program and I was wondering how I can update the list without having to refresh the page. I thought about importing the data from my DBMS into an array and just displaying the content of that array. I was able to do everything besides actually displaying every item within the array. I am getting an error: Complex object types cannot be converted to simple values.
Here is my code:
<body>
<cfquery datasource="ESC-ADD-TECH" name="items">
SELECT *
FROM items
ORDER BY itemDesc ASC
</cfquery>
<div id="myDIV" class="header">
<h2>My Shopping List</h2>
<cfform id="new_item">
<cfinput type="text" name="updateinfo" placeholder="Item..." required="true" />
<input name="submitButt" type="submit" class="addBtn"></input>
</cfform>
<cfset itemsArray = arrayNew(1)>
<cfset arrayAppend(itemsArray, #items#)>
<cfif structKeyExists(form, "submitButt")>
<cfset arrayAppend(itemsArray, #updateinfo#)>
<cfquery datasource="ESC-ADD-TECH">
INSERT INTO items(itemDesc) VALUES('#updateinfo#')
</cfquery>
</cfif>
</div>
<cfoutput query="items">
<ul>
<li>#itemsArray#</li>
</ul>
</cfoutput>
</body>
Thank you
(Too long for comments....)
CF is just like any other server side web app language (asp, asp.net, php, etc..). It doesn't know anything about client side code. The app server parses the CFML (php code, asp.net, whatever language...) and spits back the HTML/CSS/JS that code generated. So there's no reason your CFML code can't include javascript, unless the client explicitly said don't use it. If they did, then yeah, the only way to refresh the list is by resubmitting the page. From a coding standpoint, a self-posting form is simpler, but does make for a very 1990's UX ;-)
It sounds like you are well versed in javascript, so you should have no problem with manipulating the DOM via ajax. However, if you were going to use a self-posting form instead, a few comments about the current CF code:
Strictly a style preference, but separating query and "view" (or display) code keeps things more readable IMO.
In order to display any newly added items, the code must perform the INSERT first, then the SELECT query.
The 'complex object...' error is due to the INSERT query treating an array (complex) like a simple value (string, date, number). CF doesn't know how to implicitly convert the complex array '#updateinfo#' into a string. That said, you don't actually need an array at all (see #4)
Your form only contains a single input field, so no need for arrays. Just insert the single value directly. Keep in mind it's a good practice to always use cfqueryparam to protect against sql injection. Plus its other benefits like validation and performance. Also, always scope variables to avoid ambiguity. Example, use FORM.updateinfo instead of just updateinfo
Although <cfform> works, it (and associated controls like <cfinput>, etc..) have fallen out of favor in recent years. Primarily because it's baked into CF making it difficult to update or customize behavior.
It's good to get into the habit of knowing when to use or not use pound signs. Most people are surprised at how often they're NOT needed. There are a few exceptions, but generally they're only required when either:
a. A variable is enclosed in quotes. Example:
b. A variable is enclosed within <cfoutput> tags
If you're from a JavaScript background, you might prefer cfscript over cfml (tags). As of CF11+, almost anything you can do in cfml, can be done in cfscript.
Revised Script
<!--- 1. Add new items --->
<cfif structKeyExists(form, "submitButt")>
<cfquery datasource="NameOfYourDSN">
INSERT INTO items(itemDesc)
VALUES(
<cfqueryparam value="#FORM.itemDesc#" cfsqltype="cf_sql_varchar">
)
</cfquery>
</cfif>
<!--- 2. After inserting, get new list of items --->
<!--- Avoid SELECT * (select all) and only return the columns you need --->
<cfquery datasource="ESC-ADD-TECH" name="items">
SELECT *
FROM items
ORDER BY itemDesc ASC
</cfquery>
<!--- 3. View Code --->
<html>
<body>
<div id="myDIV" class="header">
<h2>My Shopping List</h2>
<form id="new_item" method="POST" action="nameOfYourScriptHere.cfm">
<input type="text" name="itemDesc">
<input name="submitButt" type="submit" class="addBtn">
</form>
<cfoutput query="items">
<ul>
<li>#itemsArray#</li>
</ul>
</cfoutput>
</div>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With