HOME | FERGUSON Digital Blog

Entries Tagged as 'ColdFusion'


Using a CSS Sprite as a CFTree Icon

ColdFusion · By Michael Ferguson 1 Comment »

I've been going through icon libraries on my websites and combining images into CSS Sprite libraries. The master image file, or sprite, holds all the individual images in it. You then call them out by coordinates in style statements instead of using an IMG tag. Why? Using a sprite instead of 20 images can save space, but I think the real advantage is the download.

When creating a GUI with many different icons, the visitor's connection may not be as good as yours, or the internet just hiccups and their browser tries to display your application but has a few empty IMG placeholders. If you were to use a sprite instead the visitor's browser only downloads one file and your style statements just call it over and over for the different coordinates.

The bad new is that the img attribute of the CFTREEITEM tag does not allow you to use sprites. Not to worry, there is a workaround. Instead of using the img attribute, put a floating span in the display attribute instead.

For example:

<cfset ImageIcon="<span style='margin: 1px; float: left; width: 32px; height: 32px; background: URL(SpriteIcon.png) -32px -32px;'></span>">

You may find a better method, but I had to float the sprite and the text to the left to get a good tree alignment. Also, I've chosen to make my icons 32 pixels square, which also made it easier to map the coordinates in the sprite.

<cfform>
   <cftree name="MyTree" format="html">
      <cftreeitem value="Test" display="#ImageIcon#<span style='float: left;'>test</span>" >
   </cftree>
</cfform>

Obviously this tree is more of a telephone pole, but I hope you get the idea. For a more useful CFTREE, build a query to populate your ColdFusion tree and map to different coordinates in your CSS sprite library image. The example above has only been tested with Internet Explorer 8.

For more information on how to create CSS Sprites, try an internet search for: "css sprites".

If you find this post useful please leave a comment and let me know how you used the information.

Internet Explorer Favorites are INI files

ColdFusion · By Michael Ferguson No Comments »

If you didn't already know, the favorites used by Internet Explorer are actually INI files.ᅠ I found this out, if I didn't know it previously and just forgot, when I was working on a file manager program and needed a way for Mozilla users to be able to read URL files uploaded by Internet Explorer users.

When I used CFDUMP to review the contents of an uploaded URL file, I found a perfectly formed INI layout that I could then use to redirect any browser to the intended website!

For example an Internet Explorer URL file to this site would look like this:

[DEFAULT]
BASEURL=http://fergusondigital.com/blog/
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,2
[InternetShortcut]
URL=http://fergusondigital.com/blog/
IDList=
IconFile=http://fergusondigital.com/favicon.ico
IconIndex=1

In a ColdFusion application, you can use GetProfileString and retrieve the value of InternetShortCut URL. Not sure this would be helpful anywhere else, other than to just read the contents of an Internet Explorer URL.ᅠ The contents of any URL can be read using Notepad.

If you find this post useful please leave a comment and let me know how you used the information.

Reduce CFLDAP Timeouts When PDC Is Down

ColdFusion · By Michael Ferguson No Comments »

Once upon a time, I used to hard code my user authentication mechanism of choice against an Active Directory Primary Domain Controller (PDC). These were applications in a Microsoft environment (No Apache, Linux, or Firefox). The problem was that the PDC was not correctly maintained. It failed to failover (ironic). Now, I realize that the structure of PDCs and BDCs is not the same in an Active Directory as it was a thousand years ago under Windows NT, but the premise of a primary being automatically replaced by secondary controllers is essentially the same.

Anyway, when the PDC would flake out or become too slow to be useful, the user authentication mechanism would be unusable because it had been hard coded for that bad server. I've used CFEXECUTE to determine the machine name of the current PDC in the domain by calling the JoeWare program called FindPDC. This helped when the fix for the bad server was for the technicians to rush another box into production with a seemingly random machine name. Times have changed, and the servers are under different management and there are about seven pre-named omnipresent domain controllers.

To drop using the FindPDC call through CFEXECUTE, the list of domain controllers is just added to a database and the query cached for 30 days. To determine if the first machine in the query was available, the PING command is issued through CFEXECUTE and the result examined. If the machine fails to be contacted, the next is contacted and so on through the list.

GetPDC is the name chosen for the query, DomainController is the record containing the predefined domain controller machine name. Before this loop, the NamePDC variable is defined as an empty string.

<cfloop index="LoopIndex" list="#ValueList(GetPDC.DomainController)#">
   <cfexecute name="ping.exe" arguments="-n 1 -4 -f #LoopIndex#" timeout="10" variable="GetResultPDC" />
   <cfif FindNoCase("Request timed out", GetResultPDC) EQ 0 AND FindNoCase("Ping request could not find host", GetResultPDC) EQ 0>
      <cfset NamePDC=LoopIndex>
      <cfbreak>
   <cfelse>
      <cfset NamePDC="FAIL">
   </cfif>
</cfloop>

The loop goes through the query result, converted to a list in this case and issued a PING command through CFEXECUTE. I've limited the PING echo results to just 1, this is much faster than waiting for the default 4 results. It may make little difference, but I only want IPV4 communication in this example so the -4 and -f options were added.

The GetResultPDC result from the commanded PING may contain the result of timing out or not finding the server being tested, in this example if the results are zero (0) (did not contain those error messages) then CFBREAK out of the loop, we have a server that is answering. This doesn't mean it's guaranteed to do its job as a domain controller, but that its on, has an operating system, is connected to the network and is responding. The NamePDC string is assigned to the current list result called LoopIndex.

If the machine being tested fails, we reassign the string NamePDC. It receives a FAIL value and the loop continues through. If all results of the GetPDC query return PING errors, then the last NamePDC result will contain the FAIL value. If you check for this condition before calling the CFLDAP, or any other authentication mechanism requiring a call against a network server, then the call should not timeout when the server is unreachable.

If you find this post useful please leave a comment and let me know how you used the information.

CFSCRIPT Query Speed Test

ColdFusion , MS SQL2008 · By Michael Ferguson No Comments »

I was curious about the speed comparisons between an MS SQL Stored Procedure called through ColdFusion, a typical ColdFusion query written in CFM, and a ColdFusion query written in CFSCRIPT. A query of five (5) columns and 58,960 records was chosen. Here is the code used:

<cfstoredproc procedure="GetTestC" datasource="TestData" result="GetResultC" />
<cfdump var="#GetResultC#"> SP<br />

<cfset TestSQL="SELECT * FROM TableName">

<cfquery name="GetTestA" datasource="TestData" result="GetResultA">
   #TestSQL#
</cfquery>
<cfdump var="#GetResultA#"> CFM<br />

<cfscript>
   GetResultB="";
   GetSQL=New Query();
   GetSQL.setDatasource("TestData");
   GetSQL.setName("GetTestB");
   GetSQL.setResult("GetResultB");
   GetSQL.setSQL("#TestSQL#");
   GetResultB=GetSQL.execute();
   WriteDump(GetResultB.getPrefix());
</cfscript> CF9 CFSCRIPT<br />

The results are for a ColdFusion 9 server running Microsoft Server 2008 R2 communicating through a crossover to another Microsoft Server 2008 R2 with Microsoft SQL 2008. The execution times were not consistent, but the variance between the three query configurations was reasonably similar. Running the tests several times then averaging the results seemed to provide a clearer difference. The surprise was how much faster a CFC query actually runs, most of the time it was almost the same as the CFSTOREDPROC.

Average speeds:

CFM 972

CFC 728

SP 629

I was expecting the stored procedure to be the clear winner, especially with 58,960 record results but was impressed by the CFSCRIPT query speeds. Your results may vary.

If you find this post useful please leave a comment and let me know how you used the information.

Using SpreadsheetAddColumn With Looped Query

ColdFusion · By Michael Ferguson No Comments »

To loop through a query result in CFSCRIPT and build a spreadsheet, you can utilize the SpreadsheetAddColumn. This example does not take into consideration a zero-length query result, so you will have to provide your own conditional checks. The idea here is to just show how you can loop through a query and add each column in succession.

First are the basics for creating a spreadsheet:

<cfscript>
   TheFile=GetDirectoryFromPath(GetCurrentTemplatePath()) & "TestDocument.xls";
   TheSheet=SpreadsheetNew("TestDocument");
   SpreadsheetAddRow(TheSheet, "Column A, Column B");

So far I've set the location for the XLS document to be created and stored, and set the name of my spreadsheet. For this example, there are two columns defined in the event I want to call them something other than the name of the records in the query result. I am going to use SpreadsheetAddColumn as an example where the query is being pulled for other processes on the page and may have more column names than I actually want in the XLS document.

For (i=1; i LTE GetQueryResult.RecordCount; i=i+1) {
      SpreadsheetAddColumn(TheSheet, GetQueryResult.FruitColor[i], i+1, 1, false);
      SpreadsheetAddColumn(TheSheet, GetQueryResult.FruitNames[i], i+1, 2, false);}
</cfscript>

We're looping through the query results (assuming there is at least one result for this example) and generating the column data. The result is grabbing the query record by position according to the looped value of "i". So we can keep the header in place we are adding one to the position start row and number our columns. The "false" is for the optional "insert".

Next we need to commit the spreadsheet to a file on the server and in this example, trigger a download of the file.

<cfspreadsheet action="write" filename="#TheFile#" name="TheSheet" overwrite="yes" sheetname="TestDocument">

<cfheader name="Content-Disposition" value="attachment; filename=TestDocument.xls">
<cfcontent type="application/vnd.ms-excel">
<cfcontent file="#TheFile#" reset="yes">

You may want to add a MIME type to the CFCONTENT page for properly generated code, but I've found that it will still deliver the XLS document without it, so its up to you and your situation. The CFHEADER file name location may also need to be tweaked if it is now pointing to the literal location of where the absolute path created our document with the TheFile variable.

If you find this post useful please leave a comment and let me know how you used the information.

© Copyright 1997-2024, All Rights Reserved Coldfusion and MS SQL2008
Powered by Mango Blog.   Design by FERGUSON Digital