Archive for the ‘ColdFusion’ Category

CF AJAXPROXY

Posted: May 10, 2016 in ColdFusion

Here is the example code for populating two dropdowns based on another dropdown.

var UserLangue=”#session.Langue#”;
function GetAllPakages(plateforme) {

GetAllPackagesEn(plateforme);
GetAllPackagesFr(plateforme);

}

function GetAllPackagesEn(plateforme) {
opEn = new ObjProgrammationJs();
opEn.setCallbackHandler(Callback_getPackagesEn);
opEn.setQueryFormat(‘column’);
opEn.getPackages(“#application.dsLocal#”, plateforme,’En’);
}

function GetAllPackagesFr(plateforme) {
opFr = new ObjProgrammationJs();
opFr.setCallbackHandler(Callback_getPackagesFr);
opFr.setQueryFormat(‘column’);
opFr.getPackages(“#application.dsLocal#”, plateforme,’Fr’);
}

function Callback_getPackagesEn(response) {
$(“##FamilleIDEn”).empty();

var opt = document.createElement(“option”);

var select = document.getElementById(‘Plateforme’);
var options = select.options;
var selected = select.options[0].text;
//alert(selected)

if(UserLangue == ‘en’)
opt.text = “Make a selection”;
else
opt.text = selected;

opt.value = “-1”;
opt.selected=true;
document.getElementById(‘FamilleIDEn’).options.add(opt);

for(i=0; i<response.DATA.length; i++) {
var opt = document.createElement("option");

// Assign text and value to Option object
opt.text = response.DATA[i][1];
opt.value = response.DATA[i][0];

// Add an Option object to Drop Down List Box
document.getElementById('FamilleIDEn').options.add(opt);
}

}

In case you don’t have CF10, this is my preferred way to remove duplicates from a list.

<cfset newlist = [] />
<cfloop list=”#combination#” index=”i”>
<cfif NOT arrayFind(newlist,trim(i))> // can also use arrayFindNoCase
<cfset arrayAppend(newlist,trim(i))>
</cfif>
</cfloop>

<cfoutput>
#arraytolist(newlist)#
</cfoutput>

Use REReplace

#reReplace(testString,”\s+”,” “,”All”)#

This a regular expression replace.
The first param is the string that the extra white space is to be stripped
from.
The second param is a regular expression which you are looking to replace.
The regular expression “\s+” means one or more white space characters.
The third param is the string that you will be putting in place of the
previous.
The fourth param is optional, “All” indicates that you would like to replace
all instances of the reg expression. The default for this param is “One” which
will replace only the first occurance.

The code below will allow you to see it in action.
<cfset testString = “my cold fusion server”>
<pre>
#testString#
#reReplace(testString,”\s+”,” “,”All”)#
</pre>


Suppose you have a list of items arranged in a table and you want to change the order of the items -Jquery UI has a wonderful and easy to use plugin for this – know as Sortable. The sortable plugin allows us to do the sorting using drag and drop with mouse click. In this article we will see the sortable plugin in action using drag and drop and also using separate UP / DOWN buttons.

Consider the following html markup for our sample table:

HTML Page
<table class="table table-striped">
    <tbody id="tabledivbody">
        <tr class="sectionsid" id="sectionsid_1">
                <td>Overview</td>
                <td><a href="javascript:void(0)" class="movedownlink">
                     <span class="glyphicon glyphicon-arrow-down"></span></a></td>
                <td></td>
        </tr>
        <tr class="sectionsid" id="sectionsid_2">
                <td>History behind OOPS</td>
                <td><a href="javascript:void(0)" class="movedownlink" >
                     <span class="glyphicon glyphicon-arrow-down"></span></a></td>
                <td><a href="javascript:void(0)" class="moveuplink" >
                     <span class="glyphicon glyphicon-arrow-up"></span></a></td>
                <td></td>
        </tr>
        <tr class="sectionsid" id="sectionsid_3">
                <td>Summary</td>
                <td><a href="javascript:void(0)" class="moveuplink" >
                     <span class="glyphicon glyphicon-arrow-up"></span></a></td>
                <td></td>
        </tr>
    </tbody>
</table>

CFM Page

Use the ajaxonload() function to trigger the sortable function.
Syntax : <cfset ajaxonload('FunctionName')>

example: <cfset ajaxonload('dragTableRow')>

This markup when rendered looks like this –

Now, as you can see that there are 3 items in the table and if needed we can rearrange and change their order using the up / down arrow keys or simply dragging one row and placing over another row. It may look fancy and tough, but it is actually very easy to achieve the same. Just read on…

Step 1: Include the following jquery scripts for Sortable to work:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>

 

Step 2: Following javascript code is required to make the table rows sortable:

Option 1

function dragTableRow(){
$(“#Tableid tbody”).sortable({
helper: fixHelperModified ,opacity: 0.6, cursor: ‘move’, update: function() {
var order = $(this).sortable(“serialize”) + ‘&action=updateRecordsListings’;
$.post(“cfm page”, order, function(theResponse){
//alert(theResponse)

});
}
});
}

Option 2

    $("#tabledivbody").sortable({
        items: "tr",
        cursor: 'move',
        opacity: 0.6,
        update: function() {
            sendOrderToServer();
        }
    });
   
    function sendOrderToServer() {
        var order = $("#tabledivbody").sortable("serialize");
   
        $.ajax({
        type: "POST", dataType: "json", url: "/path/to/updateorder/script",
        data: order,
        success: function(response) {
            if (response.status == "success") {
                window.location.href = window.location.href;
            } else {
                alert('Some error occurred');
            }
        }
        });
    }


To make the rows sortable, you need to use table body (tbody) as the selector. Sortable plugin also provides a way to let us know the current order of the rows. For this, the sortable plugin expects us to provide them some info in the form of id attributes of the rows. See – id=”sectionsid_1″ in our html example. Once you get this step correct, you can get the current order of items in a serialized array using – $(“#tabledivbody”).sortable(“serialize”) statement. This ordering information can also be passed on to the server to be updated in a Database too. Here in this example we are using an AJAX call to our backend so that as soon as the order changes we update the same in our database and once the response has come back from server, we refresh the page to display the recently updated order from the Database. The POST data may look like – sectionsid[]=1&sectionsid[]=2&sectionsid[]=3

Step 3: processing order array at the backend:

The following is an example in php to demonstrate how to handle this ordering information and store it in Database:

PHP Code

        $sectionids = $_POST('sectionsid');
        $count = 1;
        if (is_array($sectionids)) {
            foreach ($sectionids as $sectionid) {
                $query  = "Update sections SET display_order = $count";
                $query .= " WHERE id='".$sectionid."'";
               
                // your DB query here
               
                $count++;
            }
           
            echo '{"status":"success"}';
        } else {
            echo '{"status":"failure", "message":"No Update happened. Could be an internal error, please try again."}';
        }

Coldfusion Code

<cfset s=Form[‘SECTIONSID[]’] >
<cfset listingCounter = 1>
<cfloop list=”#s#” index=”recordIDValue”>
<cfquery name=”Qry_Name” datasource=”DSN”>

Update Table SET  display_order =#listingCounter#

WHERE  id==#recordIDValue#
</cfquery>
<cfset listingCounter=listingCounter+1>
</cfloop>
The above code assumes that you have a column – ‘display_order’ to maintain order for each item in database table.

How to handle separate UP / DOWN arrow keys:

Add the following javascript code to reorder the table rows using individual buttons:

    $(".moveuplink").click(function() {
        $(this).parents(".sectionsid").insertBefore($(this).parents(".sectionsid").prev());
        sendOrderToServer();   
    });
   
    $(".movedownlink").click(function() {
        $(this).parents(".sectionsid").insertAfter($(this).parents(".sectionsid").next());
        sendOrderToServer();
    });

What is happening here, is that as soon as an arrow button is clicked(whether it is up or down identified by their classes – moveuplink and movedownlink respectively) – the rows are dynamically updated in the table DOM hierarchy. And as before, upon clicking of these buttons the information is again sent back to the backend, where the same can be updated in the Database.

That’s all what is needed to get the table rows sorted either by drag and drop or by clicking specific buttons.

PS: While working with this, you might observe a wierd issue while dragging a table row. Sometimes, the width of the row gets collapsed and the row looks shrinked than the actual width. The issue can be fixed(courtsey ) by providing a custom helper callback as follows:

    var fixHelper = function(e, ui) {
        ui.children().each(function() {
            $(this).width($(this).width());
        });
        return ui;
    }
   
    $("#tabledivbody").sortable({
        ------
        helper: fixHelper,
    });

<cfset to_email=”ServiceDesk@Wabtec.com”>
<cfset subject_text=”PC Problems”>
<cfset body_text=””>

<cfoutput> <a href = “mailto:#to_email#?subject=#subject_text#&body=#body_text#”>Send Mail</a></cfoutput>

<CFSET foo = listDeleteAt(list, ListLen(list,”,”), “,”)>

ColdFusion Ajax : Auto-Suggest

Posted: November 16, 2012 in ColdFusion

Auto-suggest is a modified text input box, one that displays suggestions as the user types. The auto-suggest control in ColdFusion 8 can be used in two ways, with local client-side data, and with asynchronous calls back to ColdFusion.

Here’s a simple client-side data example (which uses one of the CF8 example databases, so this should work for you as is):

<!— Get data —>
<cfquery datasource=”cfartgallery” name=”data”>
SELECT artname
FROM art
ORDER BY artname
</cfquery><!— The form —>
<cfform>
Art:
<!— Populate auto-suggest control —>
<cfinput type=”text”
name=”artname”
autosuggest=”#ValueList(data.artname)#”>
</cfform>

This form displays a simple text box, but as text is entered, suggestions are displayed. The list of suggestions are passed to the autosuggest attribute which accepts a comma delimited list. The list could be hardcoded, but here ValueList() is being used to dynamically build a list based on a prior database lookup.

This is not an Ajax control in that lookups are not asynchronous, there is no communication back to the server to retrieve data, all data is local. This is actually a preferred form of auto-suggest for smaller lists.

For longer lists asynchronous interaction is indeed preferred, and the auto-suggest control supports this by allowing asynchronous calls to a ColdFusion component. Here is a sample CFC:

<cfcomponent output=”false”><cfset THIS.dsn=”cfartgallery”><!— Lookup used for auto suggest —>
<cffunction name=”lookupArt” access=”remote” returntype=”array”>
<cfargument name=”search” type=”any” required=”false” default=””><!— Define variables —>
<cfset var data=””>
<cfset var result=ArrayNew(1)>

<!— Do search —>
<cfquery datasource=”#THIS.dsn#” name=”data”>
SELECT artname
FROM art
WHERE UCase(artname) LIKE Ucase(‘#ARGUMENTS.search#%’)
ORDER BY artname
</cfquery>

<!— Build result array —>
<cfloop query=”data”>
<cfset ArrayAppend(result, artname)>
</cfloop>

<!— And return it —>
<cfreturn result>
</cffunction>

</cfcomponent>

This CFC has a single method named lookupArt which accepts a string and performs a query to find all matches that start with the specified value. Auto-suggest requires that results be returns in a single dimensional array (for now, hopefully this will change before we ship the final product), and so the code populates an array with the results which are then returned.

Now for the modified form code to use this CFC and method:

<cfform>
Art:
<cfinput type=”text”
name=”artname”
autosuggest=”cfc:art.lookupArt({cfautosuggestvalue})”>
</cfform>

Here the autosuggest points to a CFC, and as the CFC (I named it art.cfc) is in the current folder, no path needs to be specified. When a user enters a value, generated JavaScript code triggers an asynchronous calls to the lookupArt method in art.cfc. {cfautosuggestvalue} gets automatically replaced with whatever value the user has entered, and that value is then used by the CFC in the lookup. When an array of results get returned the auto-suggest list gets populated.

Use ListQualify function.

Example code:

<cfset FilterListItems=”Rail Road,Type,Phase”>
<cfquery name=”qry_filterList” datasource=”#dsn.intranet#”>
select * from tbl_track_FilterTable
WHERE FilterName IN (#ListQualify(FilterListItems,”‘”)#)
</cfquery>

The only way to dynamically evaluate code that you are creating at runtime is via writing it out to a file, and then executing it.

here is some psuedo code:

<cfset uuid=createUUID()>
<cfset fileName=”#ExpandPath( ‘./’ & uuid & “.cfm” )#”>
<cfset fileWrite( fileName, qry_filterList.FilterBody)>
<cfinclude template=”#uuid#.cfm”>
<cfset fileDelete( fileName )>

I have used code like this before with no problems. Anything in the Virtual File System flies as it is all run in RAM. For best practice do remember to delete the files created 😉

Introduction

For a few releases now ColdFusion has supported the addition of extensions to the ColdFusion Administrators. Basically this is just the ability to add to the navigation menu of your Administrator. Only a few people have done it and I thought that a simple guide to create an extension and an set of tips would perhaps encourage others to write their own extensions.

Adding Links

At a basic level, the documented support for extending the Administrator is based on adding links. You have two ways of doing this.

The first, and older method, is to create a file named extensionscustom.cfm. This file is saved in the administrator folder. The file should only contain links. Since the Administrator uses frames, you should specify a target of content to keep any content you create within the frame:

view plain print about

1<a href=”foo.cfm” target=”content”>Foo</a><br/>
2<a href=”goo.cfm” target=”content”>Goo</a><br/>

You can add any number of links and they will appear in the left hand navigation under a section called Custom Extensions. Here is an example:

While this works, a better method was added to ColdFusion 8. (Props go to Jason Delmore for “sneaking” this in. Shhh, don’t tell anyone!) Inside your administrator folder you will find a file named custommenu.xml. If you open this in an editor you will see:

view plain print about

1<?xml version=”1.0″ encoding=”iso-8859-1″?>
2<menu>
3<!– To use the xml custom menu extension simply copy and modify the following example <menu> block. Treat menuitem as you would an anchor tag. The submenu label attribtute will be shown as a top-level button on the menu.
4    The first menuitem is an example of targetting the main content frame.
5    The second menuitem is an example of opening up new window.
6    The third menuitem is an example of using javascript to open up new windows with size specifications or tabs
7
8    <submenu label=”Custom Server Settings”>
9        <menuitem href=”settings/server_settings.cfm” target=”content”>Settings</menuitem>
10        <menuitem href=”settings/limits.cfm” target=”_blank”>Request Tuning</menuitem>
11        <menuitem href=”javascript:var newwin = window.open(‘settings/caching.cfm’,’newwin’,’height=200,width=400,status=yes,toolbar=no,resizable=yes,titlebar=no’);” target=”_self”>Caching</menuitem>
12    </submenu>
13–>
14
15</menu>

This is a simple XML file that you can use to add your own links. Unlike the previous method, however, you can add your own sections as well. You could create one section for various security tools and another for items related to server management. Here is a simple example:

view plain print about

1<submenu label=”My Tools”>
2    <menuitem href=”spoolmail/” target=”content”>SpoolMail</menuitem>
3</submenu>

This creates a section named My Tools with one link to a folder with the name SpoolMail. This renders in your browser like so:

Creating Extensions

Now that you know how to create the link, how do you actually create the extension? In general you can write any code you want to for your extension. So for example, you could add a basic clock to your Administrator like so:

1. Add this to custommenu.xml

view plain print about

1<submenu label=”My Tools”>
2    <menuitem href=”time.cfm” target=”content”>The Time</menuitem>
3</submenu>

2. Create a new file named time.cfm and use this code:

view plain print about

1<cfoutput>The time is #timeFormat(now())#.</cfoutput>

3. Reload your ColdFusion Administrator and click on The Time:

That’s it! Of course, it looks rather ugly. There are two quick tweaks we can do to pretty things up a bit. First, we can include header.cfm and footer.cfm:

view plain print about

1<cfinclude template=”header.cfm”>
2
3<cfoutput>The time is #timeFormat(now())#.</cfoutput>
4
5<cfinclude template=”footer.cfm”>

These two files exist in the Administrator folder and create – as you can guess, the top and bottom UI used in the rest of the site. Unfortunately the Administrator code is encrypted so we can’t see how they build pages, but we can easily view source. Doing so reveals that a particular class is used for page titles. We can add that as well:

view plain print about

1<cfinclude template=”header.cfm”>
2
3<h2 class=”pageHeader”>The Time</h2>
4
5<cfoutput>The time is #timeFormat(now())#.</cfoutput>
6
7<cfinclude template=”footer.cfm”>

Now we are getting somewhere!