HOME | FERGUSON Digital Blog

Line 248

ColdFusion · By Michael Ferguson No Comments »

After creating a non-flashᅠCFREE in ColdFusion8 and clicking on an expandable branch (only tested with the top branch), the browser receives an error on line 248 stating that 'style' is null or not an object.ᅠ You could dig through all your code all you want, but it isn't your line 248 error.

If you investigate the following folder in your ColdFusion web-root "CFIDE\scripts\ajax\package\" and open the "cftree.js" file you'll discover the bit of bad code that escaped the quality inspection effort before delivery to production.ᅠ The actual error is on line 247 where it calls _68.style.backgroundColor="lightblue"; which should mean when you select the branch it will turn the background color a light blue by default.

So what's the problem?ᅠ Why the error?ᅠ This line of code is fine; it's not mal-formed at all.ᅠ The real problem is that it is out of place.ᅠ Take a look above this code and lines 244-245, these lines of JavaScript deal with testing the existence of objectᅠ_68, which will govern if a style can be applied.ᅠ Line 247 is not obeying the script's error handling and must be corrected.

The easiest thing to do is just remark out the line and press on with life, the light blue is forced upon you anyway and chances are it will not conform to your design style and color scheme.ᅠ Commenting out the problem on line 247 has no ill side-effects; there are no other errors just a cooperative CFTREE.

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

Line 803

ColdFusion · By Michael Ferguson No Comments »

The browser throws an error durring execution of a CFC page: "Exception thrown and not caught" the offending page is "cfajax.js" in the folders "CFIDE\scripts\ajax\package", specifically line 803. Careful investigation leads you to an offending HTML comment that lands into the CFC thanks to an Application CFM inclusion.ᅠ The easy route might be to rid the file of all comments, but if the code isn't just for yourself and you must have those comments in place here is a workaround for you.

Simply surround each set of comments with a conditional statement to determine the file extension of the current file.ᅠ If the condition tests the file name and determines that it isn't a CFC, then the comments are included.

Example:

<cfif Right(CGI.SCRIPT_NAME, 4) NEQ ".cfc">
   <!-- comment -->
</cfif>

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

CF9 Google Style AUTOSUGGEST

ColdFusion · By Michael Ferguson 1 Comment »

If we want to use AJAX so that the visitor can remain on the same page while the search parameters are continuously refined, then the AUTOSUGGEST attribute of the CFINPUT tag can be utilized. This way when requesting the user to provide data it makes it easier to pull consistent statistics from that data when it is uniform. If many of the appointment remarks are going to start off with the same phrase, then we don't necessarily want to make them type that portion over and over.

<cfform>
   <cfinput type="text" name="AppointRemark" autosuggest="cfc:SuggestAppointRemark.getSuggest({cfautosuggestvalue})" maxresultsdisplayed="15" showautosuggestloadingicon="false" />
</cfform>


The AUTOSUGGEST triggers the SuggestAppointRemark CFC, specifically the getSuggest function, sending it the text typed into the AppointRemark field in our CFM page. As the letters are typed, the GetRemark query is populated with the information and returns an array of possibilities (limited to 15 in this example by the MAXRESULTSDISPLAYED attribute of the CFINPUT tag). If you add the matchcontains="true" attribute into the CF INPUT you will get a list containing the letter groups you type into the field instead. That is fine for short lists, but can be cumbersome for longer lists of information.

<cffunction name="getSuggest" access="remote">
   <cfargument name="SuggestRemark" type="string" required="true">
   <cfset var GetRemark="">
   <cfscript>
      GetRemark=QueryNew("Remark");
      QueryAddRow(GetRemark, 4);
      QuerySetCell(GetRemark, "Remark", "Apples", 1);
      QuerySetCell(GetRemark, "Remark", "Almonds", 2);
      QuerySetCell(GetRemark, "Remark", "Alaska", 3);
      QuerySetCell(GetRemark, "Remark", "Aladin", 4);
   </cfscript>
   <cfreturn ListToArray(ValueList(GetRemark.Remark))>
</cffunction>


When you run the form and type the letter A in the field, you will be presented with a list of all possibilities in our pseudo database. Add the letter L and the list drops off Apples. Add the letter A and the list drops off Almonds.

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

Replace JavaScript Alert/Confirm with CFWINDOW

ColdFusion · By Michael Ferguson No Comments »

Although I have Googled the Earth to a great extent, I could not find a straight forward method in which to use the CFWINDOW as a replacement for the JavaScript confirm-alert box. In this example, the replacement could used as a Custom Tag but was written to explain how to call and execute.

First is the test form we will use to gather and submit data.

<cfdump var="#FORM#">
<form action="<cfoutput>#CGI.SCRIPT_NAME#</cfoutput>" method="post" name="TestForm">
   <input name="TestData" type="hidden" />
   <input name="TestSubmit" type="submit" onClick="fnAlertBox(this); return false;" />
</form>


The CFDUMP will confirm if the data is being passed, the form is submitting to itself and the submit button has been set to stop (or return false) to force the rest of the code to execute. If you leave off this part, the form will automatically submit when the button is depressed.

Next we will need to include some code on the page before the form to handle calling the CFWINDOW and giving the user a choice.

<cfif StructKeyExists(URL, "AlertBox")>
   <div class="AlertBox">
      Are you sure you want to do that?<br /><br />
      <input name="AlertBoxYes" type="button" value="YES" onClick="fnConfirm('<cfoutput>#URL.AlertBox#</cfoutput>');" />
      <input name="AlertBoxNo" type="button" value="NO" onClick="ColdFusion.Window.hide('AlertWindow');" />
   </div>
   <cfabort>
</cfif>


In this example I am calling the CFWINDOW and building the CFWINDOW contents with the same file by checking for the existence of a URL variable. The two choices presented will be a YES and a NO. No will simply cancel the box and since we have already issued a return false from the form, the visitor can continue with edits or make a new selection. YES will receive the name of the form field (dynamically through JavaScript so we don't have to hard code a form name).

<cfsavecontent variable="head">
   <style type="text/css">
      @import "/CFIDE/scripts/ajax/ext/resources/css/xtheme-aero.css";
      .AlertBox, .AlertBox INPUT {
         font: Verdana, Geneva, sans-serif;
         font-size: 16px;
         font-weight: normal;
         color: #000;}
      .AlertBox {
         height: 100%;
         overflow: hidden;
         text-align: center;
         background: #96B9E6;}
      .AlertBox INPUT {
         width: 80px;}
   </style>
</cfsavecontent>

<cfhtmlhead text="#head#">


As a suggestion, the style statements are interjected to make the CFWINDOW more pleasant.

<script type="text/javascript">
   function fnWinCleanUp() {
      ColdFusion.Window.destroy("AlertWindow", true);}

   function fnAlertBox(obj) {
      try {
         ColdFusion.Window.destroy("AlertWindow", true);}
      catch(e) { }
      ColdFusion.Window.create("AlertWindow", "Confirm?", "cfConfirmBox.cfm?AlertBox=" + obj.form.name, {width:250,height:110,modal:true,closable:false,draggable:false,resizable:false,center:true});
      ColdFusion.Window.onHide("AlertWindow", fnWinCleanUp);}

   function fnConfirm(obj) {
      document.forms[obj].submit();}
</script>

<cfajaximport tags="cfwindow, cfdiv">


The function that handles the YES button submits the form thanks to the URL variable sent to it from the form submit button.

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

Backup with Foreign Key Constraints

MS SQL2008 · By Michael Ferguson No Comments »

Work on development assets, then deploy to production. How can you work on development assets without realistic duplicates from production? I have actually heard bush-league ColdFusion programmers brag on faking the data on development. What? So, you are an expert in your customer's field too? Although I have had to learn a lot more about my customer's processes than I ever cared to over the years, I will never fool myself into believing I can create realistic pseudo-data by which to code to their needs. That's why I would always recommend forcing a daily copy of the database(s) from the production server to the development server and work from there.

The projects I have inherited at work were created by someone who thought far too highly of Foreign Keys (FK), they are everywhere. An FK constraint forces a link between data for two tables. Normally this would be a good thing, but the problem was that these databases were created without master-storage tables with numeric representation tying them to list tables.

Through Microsoft SQL 2008, an automation (job) can be easily created using SQL Server Integration Services (SSIS) to schedule a copy task for each database, except when they are bound together with FK constraints. Using the MATER table, you can scan the "sys.databases" table for all your databases (excluding the MATER, MODEL, MSDBDATA, and TEMPDB system databases). You could hard-code for specific database, but this solution will copy any new ones added later.

Create a CURSOR, which we'll use to parse through the total of all your database names and determine which tables are tied together using foreign key constraints and store the results (I'm storing them in the MASTER and not the TEMPDB because I need access to them later). After the results are stored, we can kill the FK's and copy the databases unconstrained.

USE [master];

IF OBJECT_ID('dbo.ForeignKeysList') IS NOT NULL DROP TABLE ForeignKeysList

CREATE TABLE ForeignKeysList (
   DBName varchar(25),
   FK_Table varchar(50),
   FK_Column varchar(50),
   PK_Table varchar(50),
   PK_Column varchar(50),
   Constraint_Name varchar(100))

DECLARE DBNames CURSOR
FOR
SELECT      [name]
   FROM      sys.databases
   WHERE      Len(owner_sid) > 1
   ORDER BY   [name]

OPEN DBNames

DECLARE @Name varchar(50)
DECLARE @SQL varchar(max)

FETCH NEXT FROM DBNames
INTO @Name

WHILE (@@FETCH_STATUS <> -1)
BEGIN
EXEC ('USE [' + @Name + ']')

   SET @SQL='';
   SET @SQL=@SQL+'SELECT ''' + @Name + ''' AS DBName,FK_Table = FK.TABLE_NAME,';
   SET @SQL=@SQL+'FK_Column = CU.COLUMN_NAME,';
   SET @SQL=@SQL+'PK_Table = PK.TABLE_NAME,';
   SET @SQL=@SQL+'PK_Column = PT.COLUMN_NAME,';
   SET @SQL=@SQL+'Constraint_Name = C.CONSTRAINT_NAME ';
   SET @SQL=@SQL+'FROM [' + @Name +
'].INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS C INNER JOIN ';
   SET @SQL=@SQL+'[' + @Name +
'].INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME INNER JOIN ';
   SET @SQL=@SQL+'[' + @Name +
'].INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME INNER JOIN ';
   SET @SQL=@SQL+'[' + @Name +
'].INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME INNER JOIN ';
   SET @SQL=@SQL+'(SELECT   i1.TABLE_NAME, i2.COLUMN_NAME ';
   SET @SQL=@SQL+'FROM [' + @Name +
'].INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS i1 INNER JOIN ';
   SET @SQL=@SQL+'[' + @Name +
'].INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME ';
   SET @SQL=@SQL+'WHERE (i1.CONSTRAINT_TYPE = ''PRIMARY KEY'')) AS PT ON ';
   SET @SQL=@SQL+'PT.TABLE_NAME = PK.TABLE_NAME ';
   SET @SQL=@SQL+'ORDER BY   1,2,3,4,5';

   INSERT INTO ForeignKeysList
   EXEC (@SQL);

FETCH NEXT FROM DBNames
INTO @Name
END

CLOSE DBNames
DEALLOCATE DBNames

DECLARE ForeignKey CURSOR
FOR
   SELECT   *
   FROM   ForeignKeysList

OPEN ForeignKey

DECLARE @DBName varchar(25)
DECLARE @FK_Table varchar(50)
DECLARE @FK_Column varchar(50)
DECLARE @PK_Table varchar(50)
DECLARE @PK_Column varchar(50)
DECLARE @Constraint_Name varchar(100)

FETCH NEXT FROM ForeignKey
INTO @DBName, @FK_Table, @FK_Column, @PK_Table, @PK_Column, @Constraint_Name

WHILE (@@FETCH_STATUS <> -1)
BEGIN
   SET @SQL='';
   SET @SQL=@SQL+'ALTER TABLE [' + @DBName + '].dbo.' + @FK_Table + ' ';
   SET @SQL=@SQL+'DROP CONSTRAINT ' + @Constraint_Name;

   EXEC (@SQL);

FETCH NEXT FROM ForeignKey
INTO @DBName, @FK_Table, @FK_Column, @PK_Table, @PK_Column, @Constraint_Name END

CLOSE ForeignKey
DEALLOCATE ForeignKey

Last in the job, after the databases are copied it's time to add the FK entries back from our MASTER database. Creating a CURSOR again, we loop through the results and ALTER each table based on the results and re-establish the foreign key.

USE [master];

DECLARE @SQL varchar(max)

DECLARE ForeignKey CURSOR
FOR
   SELECT   *
   FROM   ForeignKeysList

OPEN ForeignKey

DECLARE @DBName varchar(25)
DECLARE @FK_Table varchar(50)
DECLARE @FK_Column varchar(50)
DECLARE @PK_Table varchar(50)
DECLARE @PK_Column varchar(50)
DECLARE @Constraint_Name varchar(100)

FETCH NEXT FROM ForeignKey
INTO @DBName, @FK_Table, @FK_Column, @PK_Table, @PK_Column, @Constraint_Name

WHILE (@@FETCH_STATUS <> -1)
BEGIN

   SET @SQL='';
   SET @SQL=@SQL+'ALTER TABLE [' + @DBName + '].dbo.' + @FK_Table + ' ADD CONSTRAINT ';
   SET @SQL=@SQL+@Constraint_Name + ' FOREIGN KEY (' + @FK_Column +
') ';
   SET @SQL=@SQL+'REFERENCES dbo.' + @PK_Table + ' (' + @PK_Column
+ ')'
   
   EXEC (@SQL);

FETCH NEXT FROM ForeignKey
INTO @DBName, @FK_Table, @FK_Column, @PK_Table, @PK_Column, @Constraint_Name END

CLOSE ForeignKey
DEALLOCATE ForeignKey

IF OBJECT_ID('dbo.ForeignKeysList') IS NOT NULL DROP TABLE ForeignKeysList

Don't forget, these kinds of automation could always go wrong if scheduled to happen while you are not present to save the day. Plan accordingly, execute wisely, and back-up often!

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