ListFindNoCase problem with spaces

I ran into a problem today trying to find a person's userId value from a list of values using "listFindNoCase".

Here's the code:

<cfset allowedValues = "33333a, 44444b, 55555c, 66666d, 77777e, 88888f, 99999g">

<cfif listFindNoCase(allowedValues,session.userId)>
   This person is allowed in.
<cfelse>
   This person is not allowed in.
</cfif>

Its difficult to see on this page, but there is a space after each comma in "allwedValues". This causes coldFusion to compare "33333a" to " 33333a", resulting in a false response. Removing the space between each value solved this, although it seems to be a bug to me.

SOLUTION:

<cfset allowedValues = "33333a,44444b,55555c,66666d,77777e,88888f,99999g">

What happened to the variables I set?

Here's a question for everyone out there.

I created a query:

<cfquery dbtype="query" name="companyInfo">
   SELECT *
   FROM companyList
   WHERE companyId = #url.companyId#
</cfquery>

Then without really thinking tried to set some new variables so my page wouldn't error out:

<cfset companyInfo.newVariableOne = "">
<cfset companyInfo.newVariableTwo = "">

I did a CFDUMP of companyInfo, and it dumps the query result without the additional variables. What exactly happened to the new variables? If I try to declare the structure with a StructNew() it overwrites the query.

Now before anyone gets anxious, I realize you can't set a static variable like this into a complex object type, especially a query. I'd have to create the new column in the query, and specify what row this value is for, and blah blah blah.

I'm just curious if anyone knows how Coldfusion handles this situation, and how I would retrieve a static value set like this. Thanks.

cftextarea bug

Came across an interesting bug today with CFTEXTAREA. Not a bug with ColdFusion, but a bug with the Homesite update files from Adobe. Below is how Homesite filled in the tag using their WYSIWYG:

<cftextarea name="commentmessage" message="Please enter a comment" disabled="No" required="Yes" enabled="Yes" visible="Yes" richtext="Yes" skin="default" width="550" height="300" toolbar="Basic"></cftextarea>

As you can see, it has enabled="Yes", and disabled="No". Kind of strange to have them both as options, and I've never really recognized it before this problem came up. I had simply updated my Homesite files with the tag and help files from Adobe.

When I went to submit the form, the "commentmessage" form variable was not passed in the form scope. I believe this is from the browser interpreting having "disabled" anywhere in the textarea.

I simply removed both variables(since ColdFusion defaults CFTEXTAREA to enabled="yes"), and all is well.

<cftextarea name="commentmessage" message="Please enter a comment" required="Yes" visible="Yes" richtext="Yes" skin="default" width="550" height="300" toolbar="Basic"></cftextarea>

Hope this helps someone out there.

setting a dynamic variable name

This is probably known to many, but you can set a variable with a dynamic name. I've only come across one or two instances in ten years where this is necessary. Those times have always been to quickly fix existing code and remove hard-coding of variable names.

There's always 10 ways to get to the same destination with programming, and I usually don't take this one. However, it is an option, so I'm demonstrating it here.

An example is perhaps when you need to set a variable for each student (Mark_classes, Tom_classes), and then assign a value to that new variable. This can be done with the code below:

<cfoutput query="myQuery">
   <cfset "#myQuery.Name#_classes" = myQuery.numberOfClasses>
</cfoutput>

Just be sure to put the quotes around the dynamic variable name.

CFWINDOW and CFFORM don't like hidden form variables named "action"

I kept getting an error with a CFFORM that I was using within a CFWINDOW. The error was:

error: http: Error retrieving markup for element editWindow_body : Not Found

This error message would go away if I would use a regular HTML form tag. After a bit of searching I found the solution. I had a hidden variable in the form named "action". Such as:

<input type="hidden" name="action" value="editCompany">

It appears that the Javascript/Ajax libraries for coldFusion 8 have the form variable "action" as a reserved word, and this was conflicting with the normal operation of the page. I quickly changed the name of the hidden variable to "myAction" along with the code and everything works normally.

<input type="hidden" name="myAction" value="editCompany">



CFLOOP inside of a CFOUTPUT

Previously, I wrote about using a CFLOOP inside of a CFLOOP. Here's another solution for a quirky problem you might encounter.

Sometimes a situation exists where you need to use a CFLOOP inside of a CFOUTPUT. I had two queries, the first was the main query (queryOneList), and the second (queryTwoList) was going to be used to dynamically create the columns in a table for an administration area.

This is a pretty unique situation, and it created a unique problem. Below is the code I initially wrote:

<table>
<cfoutput QUERY="queryOneList">
<tr>
   <td>#queryOneList.MEDIUM_NAME#</td>
   <td>#queryOneList.MEDIUM_DESC#</td>
   <cfloop query="queryTwoList">
   <td><A href="xyz.cfm?mn=#queryOneList.MEDIUM_NAME#&code=#queryTwoList.CODE#">#queryTwoList.CODE_NAME#</A></td>
   </cfloop>
</tr>
</cfoutput>
</table>

The problem was that since I scope all variables, the queryOneList.MEDIUM_NAME value INSIDE THE CFLOOP was always the first value returned from "queryOneList". Obviously, I needed to reference that row's value. I quickly solved this problem by referencing the value as so in the url link:

<table>
<cfoutput QUERY="queryOneList">
<tr>
   <td>#queryOneList.MEDIUM_NAME#</td>
   <td>#queryOneList.MEDIUM_DESC#</td>
   <cfloop query="queryTwoList">
   <td><A href="xyz.cfm?mn=#queryOneList.MEDIUM_NAME[queryOneList.currentRow]#&code=#queryTwoList.CODE#">#queryTwoList.CODE_NAME#</A></td>
   </cfloop>
</tr>
</cfoutput>
</table>

Another solution would have been to create another variable on the first line after the CFOUTPUT with the value, and referencing it:

<cfoutput QUERY="queryOneList">
<cfset theNameIs = queryOneList.MEDIUM_NAME>
<tr>
   <td>#queryOneList.MEDIUM_NAME#</td>
   <td>#queryOneList.MEDIUM_DESC#</td>
   <cfloop query="queryTwoList">
   <td><A href="xyz.cfm?mn=#theNameIs#&code=#queryTwoList.CODE#">#queryTwoList.CODE_NAME#</A></td>
   </cfloop>
</tr>
</cfoutput>
</table>

Either way will work I guess, but I prefer the first method. It's more pro in my opinion.

Creating a hierarchy list with Coldfusion

I came across a stored procedure that returns data in the following format:

The dilemma was how to display this so that each level was shown as a "sublevel" of the one above it. I easily accomplished this by keeping a list of the current levels. Each time a new level was added, I'd add this value to the "levelList". When that level was ended, I'd remove that value from "levelList". With this list, I would always know where I was. I would be able to end each unordered list and start new ones where needed.

[More]

Coldfusion query of queries with a reserved word in SQL

My client has a stored procedure that was returning a column named "level". While trying to execute a query of queries on the resultset, I ran into some issues because "Level" is a reserved word in T-SQL. The stored proc simply returns a column aliased as "level". Its not actually that in the table, so this problem wasn't an issue previously.

I was going to change the stored procedure itself, but other applications rely on the naming structure already in place. Any change would be a pain.

I was able to work with the query of queries by putting brackets around my reserved word column. Now ColdFusion and Sql are quite happy!

<cfquery dbtype="query" name="shortenedQuery">
   SELECT categoryName, [level], name
   FROM queryResults
</cfquery>

Checking for child node in xml document with coldfusion

Problem:
The xml document I was trying to invoke would sometimes return child nodes, and sometimes not. Since I would reference the values of the child nodes in my result set, I needed to first check to see if they existed.

isDefined doesn't work with Xml documents, and I didn't want to convert it to another object type just for that. I could have tried to reference the child node with a try/catch around it and if it broke, then I knew it didn't exist. Thats a bit messy and more of a hack than I'm comfortable with.

Solution:
After a bit of searching, I remembered "XmlChildPos". It returns the location of the child node, and if no child is found, returns a "-1"! Mission accomplished.

XmlChildPos(elem, childName, N)

Here's an example xml document where one person has children, and another does not.

<employees>
   <employee>
      <name>Bob</name>
      <title>Rock Star</title>
      <children>3</children>
   </employee>
   <employee>
      <name>Tom</name>
      <title>Accountant</title>
   </employee>
</employees>

Now, I don't know if this is properly formatted xml or what, but its being sent this way from a very, very big company who aren't going to change it.

So, I bring in the xml and store it in a variable called "xmlResult" that starts at the "employees" level.

I need to see if children exists for employee "Tom" and display the amount if it does.

<cfset myXMLDoc = XMLParse("http://www.xmlUrl.com/xml.rss")>
<cfset xmlResult = XMLSearch(myXMLDoc, "/employees")>

<cfloop from="1" to="#arrayLen(XMLSearch(xmlResult, '/employees'))#" index="i">
<cfif xmlChildPos(xmlResult[i].employee,"children", 1) GT 0>
   #xmlResult[i].employee.children#
</cfif>
</cfloop>

Thats it. Enjoy!

CFLOOP inside of a CFLOOP

I ran into a problem today and it turned out to be a simple naming conflict.

I had a loop that was looping through a session variable. I had named the index "i", which is my default loop index name. Inside the loop was a structDelete command which wasn't working.

<cfset maxValue = StructCount(session.formVars)>
<cfloop from="1" to="#maxValue#" index="i">
   <cfinclude template="act_ProcessFormVars.cfm">

   <cfset temp = structDelete(session.formVars,i)>
</cfloop>

After a bit of looking, I dug into the included file "act_ProcessFormVars.cfm" and found that there was a loop within it, that also used "i" for an index. This was causing a conflict and causing the variable "i" to be overwritten during each iteration of the loop. "i" would literally become the last value plus one of the inside loop at the time for structDelete to execute.

Here's an example:

<cfoutput>
<cfloop from="1" to="3" index="i">
   first: #i#<br>
   <cfloop from="1" to="3" index="i">
   &nbsp;&nbsp;&nbsp;&nbsp;inner:#i#<br>
   </cfloop>
   last: #i#<br><br>
</cfloop>
</cfoutput>

"i" in the above loop would become:

first: 1
    inner:1
    inner:2
    inner:3
last: 4

first: 2
    inner:1
    inner:2
    inner:3
last: 4

first: 3
    inner:1
    inner:2
    inner:3
last: 4

The solution is to simply rename one of the two loop's indexing names ("i" to "z"), and there won't be any conflicts!

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.