- I am processing information from a third party. They hit a specific ColdFusion cfm page with some HTTP Post parameters.
- One of those Post parameters contains some XML. The XML contains the data that I am interested in.
- I get the XML from the HTTP Post parameters using GetHTTPRequestData(). This takes the information from the Post, and puts it into a struct.
- <cfset variables.parameter_raw="getHTTPRequestData()">
- I take the XML and pass it into xmlParse(). This parses the XML, and dumps the XML into a very usable struct.
- <cfset variables.parameter="xmlParse(variables.parameter_raw)">
- Then, before doing anything else, I dump the XML into a log file. This way, even if everything else goes wrong, I still have a copy of the XML for debugging or whatever.
- <cflog file="foo" text="#serializeJSON(variables.parameter)#">
- Then I extract the variables I need from the XML, and pass them into a CFC. This is the tricky part. For some reason, if you try to pass the parameter into the CFC only by name, it will add a bunch of invisible XML stuff to it, making it too long for the database column I want to save it to. So, in order to just get the value, without all the other wacky XML added on, add ".xmlText" to the end. See example below:
- <cfset data_access_object.save_data(data_id="variables.parameter.data_idb.xmlText,
data_value=variables.parameter.data_value.xmlText, data_code=variables.parameter.data_code.xmlText)>
- That should do it. That ".xmlText" is really hard to debug in this context if you don't know about it. Hopefully this will help somebody else out there.
My technical blog. Hard won knowledge, Useful info, and even occasional Wit and Wisdom. If it takes me a while to figure something out, I will usually post it here and (hopefully) save someone else the trouble. -Neil Moncur
Friday, July 15, 2011
Saving XML to Database By Way of HTTP Post
Sunday, October 03, 2010
Simple Java to make sure a directory exists before doing a cffile upload
Simple Java to make sure that a directory exists before doing a cffile upload:
<cfset CreateObject("java", "java.io.File").init("C:\Inetpub\wwwroot\myNewDirectory\images").mkdirs() />
So, for example, you might do something like this:
<cfset CreateObject("java", java.io.File").init("c:\uploads\#dateformat(now(), 'yyyymmdd')#") />
You can just do the above before every upload. The first time it will create the directory, and every time after that it will just do nothing.
Thanks to cfgears for reminding me how to do this:
http://www.cfgears.com/index.cfm/2009/5/19/Tapping-in-to-ColdFusions-underlying-Java-capabilities
Thursday, September 30, 2010
listFind vs. listContains
listContainsNoCase(list, substring)
This function just finds the substring, and tells you which item contains that sub string. It is important to understand that this item is not searching for a list item, just for a sub string. Consider the following example:
listContainsNoCase("Date,Decimal,Image,Integer,Long Text,Rich Text,Simple Text", "Text")=5Notice how it found that item number 5 has the word "Text" in it, even though "Text" is not the complete item.
listFindNoCase(list, value)
This function finds a value in a list, and tells you which item matches the value. It compares the value to the list item, and only accepts complete matches. So, consider the following examples:
listFindNoCase("Date,Decimal,Image,Integer,Long Text,Rich Text,Simple Text", "Text")=0Notice how in the first example above, no item was found. This is because there is no single item with value = "Text". However, it did find "Simple Text" in the second example above.
listFindNoCase("Date,Decimal,Image,Integer,Long Text,Rich Text,Simple Text", "Simple Text")=7
Of course the same is true for listFind, and listContains, but those are case-sensitive.
Incidentally, I put this one in the "duh" category, because I think that the names are reversed. The first usage should be named listFind, and the second should be named listContains.
Hope this helps.
Thursday, September 09, 2010
ORM is not configured for the current application
ORM is not configured for the current application
Very mysterious, and took a while to troubleshoot. In my Application.cfc, in the onRequestStart method, there was a <cfset ormreload()> . I had put it there thinking that while I was doing some development it would be nice to have the ORM reloading all of time as I make changes. However, it looks like it was interfering with the ORM's sequencing, and on Ajax page loads it was causing ColdFusion to erroneously report back that the ORM was not loaded. I simply moved the ormReload to onApplicationStart, and the problem seems fixed.
Wednesday, March 03, 2010
KB927917
- Main Page starts with style sheets, javascript & ajax library, starting body tag, etc.
- Login Management Custom Tag occurs in middle of page, between begin and end body tags.
- Login Management Custom Tag launches login cfwindow, navigates window to login form.
- End of page winds things down, includes closing body tag.
So, lots of searching, and I found this helpful post:
http://blogs.msdn.com/ie/archive/2008/04/23/what-happened-to-operation-aborted.aspx
and additionally this helpful post:
http://social.msdn.microsoft.com/Forums/en/iewebdevelopment/thread/db34068c-5307-4ab7-be03-15b86c2604bb
So, I tried moving my custom tag to the end of the page, outside of the body tag, and that worked great. From what I can tell, the cfwindow, or maybe the ColdFusion.navigate was trying to add elements to the body of the page, before the body had closed.
Whether or not the reason provided above is exactly correct, it makes some sense. After all, our new, ajaxy websites launch the cfwindow from within a container (usually cfdiv), meaning that the main-page's body tag has closed before the cfwindow ever tries to load.
In any case, whether my diagnosis is right or wrong, the medicine worked. This one was a tricky one, so I thought that I would share it with the world.
Monday, November 02, 2009
cfwindow css bug workaround
The Problem
Research and testing has shown that the problem was caused by the ext-all.css file. When you use or import cfwindow or cflayout-border on your page, ColdFusion automatically adds a few css and ajax files into your page's output HTML. One of these css files, ext-all.css, appears to be causing the problem.
If you open ext-all.css, you will find the following towards the very beginning of the file (emphasis and whitespace added for easier viewing):
html, body, div, dl, dt, dd, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, p, blockquote, th, td {margin:0; padding:0;}This line appears to be causing the table padding problems.
Two lines farther down the file, you will find this:
address, caption, cite, code, dfn, em, strong, th, var {font-style:normal; font-weight:normal;}This line appears to be causing text surrounded by <em> and <strong> tags to display as plain text.
The Workaround
The workaround is simple. In CSS, which ever style declaration comes last, wins. So, simply add the following to the bottom of your page:
<style>Line 1 is a style open tag.
strong { font-weight:bold; }
em { font-style:italic; }
em.strong {font-weight:bold;}
strong.em {font-style:italic;}
</style>
Line 2 modifies the strong tag back to bold.
Line 3 modifies the em tag back to italics.
Line 6 closes the style tag.
So what are lines 4 and 5 for? Simple. Lines 2 and 3 of the workaround cause text to render bold or italics, but not both. So, Line 4 allows you to modify an em tag to be both italics and bold. Line 5 does the same in reverse.
A Simpler Workaround
Incidentally, you probably noticed that there is a simpler (though more extreme) workaround. You could just remove td, th, strong, and em from the offending lines of ext-all.css . If you are going to do this, however, you probably want to backup your copy of ext-all.css first; how this will affect the ajax controls and/or pages that use them is unknown.
Why Bother? Who cares? Why not just use inline styles? Who uses strong or em tags anymore anyway?
Good question. The answer is: Adobe, or, more importantly, their products. ColdFusion has the slick CKEditor (formerly called FCKEditor) built into it. CKEditor uses strong and em tags to modify text. This means that any content that you generate using the CKEditor (e.g. in a homegrown CMS), will be rendered plain text by ext-all.css. This is a problem.
Also, when coding with DreamWeaver, if you hit Ctrl-b for bold, or Ctrl-i for italics, DreamWeaver is going to insert em and strong tags to enforce the bold & italics. If ext-all.css renders that text plain, you now have a lot of pages on your site unexpectedly showing up with a lot of plain text, and unpadded table cells. This is an even bigger problem.
Please Vote
Workaround notwithstanding, if you think that this bug is as big of a problem as I do, please vote for Adobe to fix it here:
http://cfbugs.adobe.com/cfbugreport/flexbugui/cfbugtracker/main.html#bugId=80530
Also, you may like to vote to have Adobe fix a related bug here:
http://cfbugs.adobe.com/cfbugreport/flexbugui/cfbugtracker/main.html#bugId=80421
Thanks for your votes. I am looking forward to seeing Adobe fix this problem.
Friday, October 30, 2009
CF 9 Ajax breaks site CSS and formatting
JavaScript/CSS includes for cfwindow, cflayout-border (and possibly others), kill some formatting elements, such as <strong> & <em> tags, and negatively affects table display such as padding / margins. This is a problem.
The details
Consider the following simple cfm page:
<p>Not Bold</p>Not unexpectedly, the above displays one line of plain text, and one line of formatted text. The above works in both CF8 and CF9, and looks something like this:
<p><em><strong>Bold and italics</strong></em></p>
Not BoldNow we try importing the javascript & css for cfwindow. Consider the following small but important change:
Bold and italics
<cfajaximport tags="cfwindow" />
<p>Not Bold</p><br>
<p><em><strong>Bold and italics</strong></em></p>
In the above, the formatting for the page breaks. All you get is plain text on both lines, something like this:
Not Bold
Bold and italics
The "strongs" and "ems" are completely ignored. Some testing has shown that this also happens when you import "cflayout-border". Worse, it also seems to goof-up table formatting and padding. Oh, and the same problem occurs when using the <cfwindow> tag directly, instead of just importing the cfwindow ajax and creating thru JavaScript.
Although I don't really use strong or em tags anymore, this will break a lot of legacy pages. Also, since the CKEditor included with ColdFusion uses <strong> and <em> tags instead of inline styles, any pages that use content generated by CKEditor will stop showing formatted text. This is a problem if you have implemented a homebrew CMS (as we have on a few pages).
I'll post a fix/workaround if I find one.
Notes
I am hesitant to post about this; last time I publicized what I thought was a bug in ColdFusion it turned out that I was just an idiot, and was doing something wrong (duh). So, on the one hand I hope that I am just an idiot (again), and that there is a simple workaround for this. Unfortunately I fear that I may have found a legitimate bug this time, and it complicates our plans (already in progress) to move to CF 9.
If this is a legitimate bug, I am surprised that something like this could have made it into final release code. It is easy to reproduce, and is immediately apparent in both FireFox and IE. I have read thru the CF 9 release notes, and performed an hour of two of testing, and haven't found any obvious workarounds. If you have an idea, please let me know. Otherwise, I think that we are going to have to look at waiting to upgrade to CF 9 for a little while. Bummer.
Thursday, October 29, 2009
ColdFusion 9 ORM One to Many Complete Example
You can find the post here:
http://www.manjukiran.net/2009/07/15/coldfusion-orm-define-one-to-many-and-many-to-one-relationships/comment-page-1/#comment-2551
Thanks Manju!
Saturday, August 29, 2009
Getting cffile to work in a cfwindow
Easy work around? Embed an iframe in the cfwindow, put your form in the iframe, and have the form submit within the iframe using a simple submit button (rather than using ColdFusion.navigate). If you submit the form using a submit button in an iframe, the form's enctype will submit properly, and ColdFusion will correctly receive your file and pass it onto cffile.
This technique will also work with putting a cfpresentation tag in a cfwindow.
Wednesday, September 24, 2008
*Update to previous post* CF-Ajax gets jealous
Create Spry Data Sets Using Inline Data
It turns out that the above doesn't work inside of a bound CFDiv. For instance, if your Spry dataset lives on a pages called data.cfm, and you include data.cfm on another page using a bound cfdiv, it breaks. For the below example, you can put the guts of my previous post on this subject (referenced above) into data.cfm if you want. See the example below:
<----------- data.cfm ----------->
...
Create a spry dataset
...
Show dataset in a dynamic region
...
<----------- End data.cfm ----------->
<----------- view_data.cfm ----------->
...
<cfdiv bind="url:data.cfm" />
...
<----------- End view_data.cfm ----------->
I have spent almost two entire days trying to get the above to work. Interestingly, my research into the above with FireBug shows that I can get it to actually create and populate the dataset. However, try as I might, I can't get the dynamic region in view_data.cfm to show any data. I have researched on the web, and found others with the same finding; for example:
Spry + CFDIV = No Love
I love the CF Ajax goodness, but this is very frustrating and a major limitation. It makes it so that I can't use Spry (and possibly other Ajax frameworks) on big apps that include CF-Ajax (especially bound cfdivs). I work for a government agency, and we write some very large, powerful, complicated apps using ColdFusion. If the CF-Ajax makes it so that I can't extend the CF goodness with other Ajax frameworks, then this is a problem
I am hopeful that Adobe will address these sorts of CF-Ajax quirks in CF 9. If they don't, I will probably think twice in the future about using the CF Ajax features in the future.
Tuesday, September 23, 2008
Create Spry Data Sets Using Inline Data
To create a Spry dataset using inline data, you can just create a javascript array, and give the array to the dataset object using the Data Set's setDataFromArray(array) function. I have tested it in both FireFox and IE. You can find more information about the setDataFromArray(array) fuction here: http://labs.adobe.com/technologies/spry/articles/data_api/apis/dataset.html#setdatafromarray
The example below uses ColdFusion syntax to get data from the database and to populate the array. However, this would work with whichever language you like, or even with static data. See the following example:
Example:
<cfquery name="get_users" datasource="ds">
SELECT last_name, first_name, phone, address
FROM user
</cfquery>
<script type="text/javascript" src="Spry_1_6_1_022408/includes/SpryData.js"></script>
<script>
user_array = [<cfloop query="get_users">{last_name: "#get_users.last_name#", first_name: "#get_users.first_name#", phone: "#get_users.phone#", address:"#get_users.address#"}<cfif currentrow="" neq recordcount="">, </cfif></cfloop>]
user_dataset = new Spry.Data.DataSet();
user_dataset.setDataFromArray(user_array);
</script>
<div id="users_region" spry:region="user_dataset">
<table border="1">
<tr>
<th spry:sort="last_name">Name</th>
<th spry:sort="phone">phone</th>
<th spry:sort="address">Address</th>
</tr>
<tr spry:repeat="personnel_dataset">
<td>{last_name}, {first_name}</td>
<td>{phone}</td>
<td>{address}</td>
</tr>
</table>
</div>
You may have noticed that the above example doesn't var scope its JavaScript variables. This was on purpose, and it will still work. Experience has shown that var scoping variables can make them incompatible with some of the ColdFusion 8 CF-ajax stuff.
Thursday, May 01, 2008
ColdFusion Ajax Functions
https://acrobat.com/#d=0xInJpmQt0NgwOGzthNHuQ
Thursday, March 27, 2008
CFEclipse Newbie questions answered
You can find it here: http://www.slcfug.org/fusetalk/messageview.cfm?catid=5&threadid=639
Monday, March 03, 2008
Coldfusion Application Server service terminated with service-specific error 2
This morning I checked the cool new ColdFusion Server Monitor included with CF8. I saw several hung threads, which are a sure sign that your server is inching towards becoming unresponsive (the more hung threads, the fewer resources available to working threads). I decided that rather than waiting for our server to stall in the afternoon, I would restart the ColdFusion service right then, and the hung threads would evaporate. So I did. And the service never restarted.
Our main server guy was out of town, and the other server guys were busy, so I dug in to try to figure out what was going wrong myself. I did some research.
In the Event Viewer, I found an error that looked something like this:
"Coldfusion Application Server service terminated with service-specific error 2"A bit of time on Google taught me that one of the causes of this error is services starting too slowly. This can be mitigated by giving them more generous timeouts. For more information, see the below:
http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_18799
I did what it said there (adjusting for ColdFusion 8), restarted the server, and nothing changed. The ColdFusion service still didn't come up. By now I started to suspect that my JVM Heap changes of the previous week had precipitated the problem. Some more time spent with Google, and I found this useful link:
http://www.coldfusionmuse.com/index.cfm/2005/10/28/jvm.gc
This little gem teaches you how to go into the server's jvm.config and adjust JVM args directly, including the Max and Min Heap sizes. Server restart, and problem solved.
Tuesday, January 15, 2008
Getting dates to appear correctly in an HTML cfgrid
Although the Adobe livedocs say that you can mask / format values that go into a grid, I haven't had much success with getting it to work; especially in the case of HTML grids.
A great work-around is just to use the SQL Server CONVERT function. How? If you plug a date/time/timestamp column name into CONVERT, and tell it what you want to convert it to, it will change the data-type of the date/time column (just in the resulting recordset, not in the actual table) to the data-type of your choice, and format the date for you to one of many predefined formats. Lots of examples of this and other techniques here:
http://www.oreilly.com/news/sqlnut_1200.html
For a list of predefined formats, and some more (not very useful) examples, look here:
http://msdn2.microsoft.com/en-us/library/ms187928.aspx
So, if you need to use a date/time column in a cfgrid, just preformat it in the actual query like so:
SELECT CONVERT(VARCHAR(11), date_column, 102) AS formatted_date
FROM table
...etc.
I hope that makes more sense.
Wednesday, January 09, 2008
Binding to an HTML cfgrid
bind="{gridName.columnName}"
I searched for a couple of hours, and could only find the flash forms syntax. Then I found it documented here:
http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=ajaxui_5.html#1137151
Here is an example using cfinput to bind to the cfgrid :
<cfgrid name="user_grid" query="get_users">
<cfgridcolumn name="last_name">
<cfgridcolumn name="first_name">
<cfgridcolumn name="age">
</cfgridcolumn>
<cfinput type="text" name="the_last_name" bind="{user_grid.last_name}">
There you go. Enjoy.
Friday, August 31, 2007
cfwindow source and cfdiv URL bind strip out <script> tags
Consider the following:
<!-------- page.cfm -------->
<cfwindow name="myWindow" source="content.cfm" />
<input type="button" onClick="ColdFusion.Window.show('myWindow')" value="Show the Window">
<!-------- End page.cfm -------->
And the following content page, called by page.cfm
<!-------- content.cfm -------->When page.cfm tells the cfwindow to load conten.cfm, here is the HTML that will be sent to the browser for content.cfm
<script>
function tellMeSomething (somethingToTell) {
alert('somethingToTell');
}
</script>
<input type="button" onClick=" tellMeSomething('yadda-yadda-yadda'); " value="Tell me Something.">
<!-------- End content.cfm -------->
<div style="overflow: auto; height: 253px; width: 474px;" id="myWindow_body" class="x-dlg-bd">Notice that the <script tag and its associated function was completely stripped out.
<input onclick=" tellMeSomething('yadda-yadda-yadda'); " type="button" value="Tell me Something.">
</div>
Obviously, this is a problem if the page that you are loading needs to call a JavaScript function. There is a workaround, albeit a very imperfect one. If you put your JavaScript in the calling page (i.e. in the example above, you would put it in page.cfm), it will work.
The problem with the above workaround is that it encourages poor programming practices, and very high coupling between page.cfm and content.cfm.
Wednesday, August 22, 2007
cfajaxproxy and the head tag
Ok, so slight modification. It appears that your JavaScript only has to appear after the opening <head> tag. And, this only applies to JavaScript that makes calls against the JavaScript proxy generated by the cfajaxproxy tag (Any other JavaScript can appear anywhere you want). However, if you are going to make JavaScript calls against the proxy generated by the cfajaxproxy tag, then you had better do them after the opening <head> tag.
One other caveat: The above only applies to pages with a <head> tag. If your page doesn't have a <head> tag, then you can put any of your JavaScript anywhere you want. The above only applies to pages with a <head> tag.
It would take too long to explain why the JavaScript behaves this way. However, if anyone wants to know the reason that I believe the JavaScript behaves this way, let me know, and I will post it. It has more to do with where ColdFusion posts its JavaScript on the page than with any quirks in the JavaScript itself.
*** END UPDATE ***
Recent experience has shown that the JavaScript proxy generated by cfajaxproxy will not work if you have any user-generated JavaScript that appears outside of the <head> tag. For example, consider the following pages:
Here is the main page:
<!-------- index.cfm -------->
<cfajaxproxy cfc="component.cfc" jsclassname="component_proxy">
<script>
var js_component_proxy = new component_proxy();
var result = js_component_proxy.a_function();
</script>
<cfinclude template="top.cfm">
Some content
<cfinclude template="bottom.cfm">
<-------- End index.cfm -------->
The "Top" include follows. Notice that it has the HTML header in it.
<!-------- start.cfm -------->
<html>
<head>
Header Content
</head>
<body>
<!-------- End start.cfm -------->
And a nice little bottom.cfm to tie everything up nicely.
<-------- end.cfm -------->
</body>
</html>
<-------- End end.cfm -------->
The above will not work. When you run the JavaScript generated by cfajaxproxy, you will get the following JavaScript error:
window:global: mark_arrived has no properties
However, if you copy the user generated JavaScript into the header area marked "Header Content", suddenly everything works fine.
This was a bit of a problem for us. Our site has a page similar to the "start.cfm" page mentioned here, that in addition to many other things, contains the page header data. This means that cfajaxproxy will not work for us if we use any other JavaScript on the page.
We did find a moderately painless workaround. If anyone is interested, post a comment, and I will post the workaround here.
Tuesday, August 21, 2007
cfajaxproxy, Application.cfm, and pain
<!-------- Application.cfm -------->
<cfapplication name=""blah">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-------- End Application.cfm -------->
<!-------- Component.cfc -------->
<cfcomponent>
<cffunction name="test_proxy" access="remote" returntype="string">
<cfreturn "success" />
</cffunction>
</cfcomponent>
<!-------- End Component.cfc -------->
<!-------- index.cfm -------->
<cfajaxproxy
cfc="component"
jsclassname="component_proxy">
<cfoutput>
<script>
var js_component_proxy = new component_proxy();
function js_test_proxy() {
alert(js_component_proxy.test_proxy());
}
</script>
<input type="button" name="a_button" value="Click Me" onclick="js_test_proxy();" />
</cfoutput>
<!-------- End index.cfm -------->
If you run index.cfm?cfdebug, and click the little button, the following error will appear in the little debug window:
window:global: parseJSON
This error took a long time to isolate, and a while to fix. I don't know of anywhere in the livedocs where this is documented. However, if you have any output in your Application.cfm, even a doctype declaration, beware!!!
Incidentally, we did find a moderately difficult fix. If you are interested in knowing how we fixed this problem, post a comment, and I will post the fix.
CF Ajax goodness and SSL
Researched this one for hours. Finally emailed Damon, and he got me a snappy response. Thanks, Damon!