Thursday, October 15, 2015

Print Lightbox made easy.

Spent several hours on this request and with the assistance from colleagues on printing a lightbox, finally succeeded in that. It was ironical that I had to struggle printing a print summary with the styles. Let me give you the steps here which can ease this process for you. Jquery api has been used.

1. Create the Lightbox and have that section with class as "printable".
2. Have a button for Print. <input type="button" id="print">
3. In the click event, use this following code

    $('#print').click(function(e){
          $('head').append('<link href="/assets/css/themes/myprintstyle.css" rel="stylesheet"            type="text/css" media="print">');
         setTimeout(function(){
         $( ".printable" ).print();
         //printDiv('print-preview');
     },2000);
    e.preventDefault();
});

     

Configuring Multiple Server instances in ColdFusion11

It's always better to have separate instances for each web application than having the source code made to be available in the cfusion. Just follow these steps to get this going.

1. In the CF admin for your localhost, under the Enterprise Manager >> Instance Manager, create a new instance. After the instance is created you would notice the following information there


2. In this following path(Applications/ColdFusion11/{Instance name}/runtime/conf) you would find the server.xml. You would find this following tag towards the end of this xml file. Make sure you comment it out.
 <!--<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8500" executor="tomcatThreadPool" redirectPort="8443" connectionTimeout="20000"/>-->

3. In the following path (/Applications/ColdFusion11/config/wsconfig/1/) create this  uriworkermap_{Instance name}.properties similar to uriworkermap.properties. Just replace the cfusion with {Instance name}.

4. In this file /Applications/ColdFusion11/config/wsconfig/1/workers.properties add one more set of records for the new instance you created.

worker.list=cfusion, {Instance name}


worker.cfusion.type=ajp13
worker.cfusion.host=localhost
worker.cfusion.port=8014

worker.{Instance name}.type=ajp13
worker.{Instance name}.host=localhost
worker.{Instance name}.port=8013 (The Remote Port number assigned to this instance when the new instance was created).

5. In this file /private/etc/apache2/mod_jk.conf, the new virtual host has to be created. Assumption is that, httpd.conf is configured for multiple instances. Refer this for more information. 

# New Instance
<VirtualHost *:80>
ServerName local.newInstance.com
JkMountFile "/Applications/ColdFusion11/config/wsconfig/1/uriworkermap_{Instance name}.properties"
DocumentRoot "/Users/test/Sites/newInstance" # This should be the path to Application.cfc
Alias /CFIDE "/Applications/ColdFusion11/newInstance/wwwroot/CFIDE"
     
    <Directory "/Applications/ColdFusion11/newInstance/wwwroot/CFIDE">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

</VirtualHost>

6. To provide necessary access to the document root, the following code can be added in the httpd.conf

<Directory "/Users/test/Sites">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

7. Add an entry in the hosts file (/etc/hosts) for this new site which has been created
  
 127.0.0.1 local.newInstance.com

 8. Now restart the Coldfusion and the apache. The following commands can be used.
    sudo ./coldfusion restart (should be done from the instance/bin or cfusion/bin)
    sudo apachectl restart

The CF admin should run successfully. Now configure the site by adding the necessary data sources, mappings etc to make the site work right. 

Please comment here should you have any questions.

PS: These are 2 important Adobe documents which would be very useful.
1. Preparing to install Coldfusion.
2. Installing the server configuration.

Installing Coldfusion11 in El Capitan

As soon as El Capitan was released, mesmerized by its features I was tempted to upgrade my workstation which was running the faithful and old Mountain Lion, to El Capitan. It was all well and good until I tried reaching my cfadmin. Though I was able to start the Coldfusion services, I was not able to run the web applications. Especially the java path was corrupted.  I didn't have any choice but to uninstall my ColdFusion10(Also delete the ColdFusion10 Folder, rename or delete /etc/Apache2/mod_jk.conf). It just took me less than an hour in installing the ColdFusion11 and configure the Apache. Decided to blog about it.

1. Downloaded this ColdFusion11(ColdFusion_11_WWEJ_osx10.dmg) dmg from Adobe site.

2. Double click on it to get it going. Selected the developer edition, opted for Server Configuration (Install ColdFusion11 as self contained server running a single instance with an embedded JEE server).

3. Select the ColdFusion profile as "Developer Profile", provide the necessary passwords and keep going.

4. Under the Section configure Web Servers/Websites, provide the path to the Apache and finish the installation.

5. If you are going to configure the server for multiple instances /etc/Apache2/httpd.conf. Add the following lines.

   NameVirtualHost *:80 #This is to mention that there would be multiple instances.

Include /private/etc/apache2/other/*.conf
Include "/private/etc/apache2/mod_jk.conf" # This would contain the actual virtual hosts configuration.

6.  Update the mod_jk.conf with the virtual host configuration for the localhost. This is a sample mod_jk.conf for the localhost. Make an entry in the hosts(/etc/hosts) like this

127.0.0.1 localhost

# Load mod_jk module
LoadModule    jk_module  "/Applications/ColdFusion11/config/wsconfig/1/mod_jk.so"

# Where to find workers.properties
JkWorkersFile "/Applications/ColdFusion11/config/wsconfig/1/workers.properties"


# Where to put jk logs
JkLogFile "/Applications/ColdFusion11/config/wsconfig/1/mod_jk.log"

# custom environment variables
JkEnvVar REDIRECT_URL
JkEnvVar REDIRECT_REMOTE_HOST
JkEnvVar REDIRECT_PATH
JkEnvVar REDIRECT_QUERY_STRING
JkEnvVar REDIRECT_HTTP_ACCEPT
JkEnvVar REDIRECT_HTTP_USER_AGENT
JkEnvVar REDIRECT_REMOTE_ADDR
JkEnvVar REDIRECT_SERVER_NAME
JkEnvVar REDIRECT_SERVER_PORT
JkEnvVar REDIRECT_SERVER_SOFTWARE

# Where to put jk shared memory
JkShmFile "/Applications/ColdFusion11/config/wsconfig/1/jk_shm"

# Set the jk log level [debug/error/info]
JkLogLevel info

# Select the timestamp log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
AddHandler jakarta-servlet .cfm .cfml .cfc .cfr .cfswf

DirectoryIndex index.cfm

<Files ~ ".hbmxml$">
Order allow,deny
Deny from all
</Files>

# cfusion
<VirtualHost *:80>

ServerName localhost
JkMountFile "/Applications/ColdFusion11/config/wsconfig/1/uriworkermap.properties"

DocumentRoot "/Applications/ColdFusion11/cfusion/wwwroot/"


<Directory "/Applications/ColdFusion11/cfusion/wwwroot/">
        Options Indexes FollowSymLinks
        AllowOverride all
        Order allow,deny
        Allow from all
   </Directory>

Alias /CFIDE "/Applications/ColdFusion11/cfusion/wwwroot/CFIDE"
   
    <Directory "/Applications/ColdFusion11/cfusion/wwwroot/CFIDE">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

</VirtualHost>

7. Start the Coldfusion server after navigating to /Application/ColdFusion11/cfusion/bin through the terminal using this command sudo ./coldfusion start

8. Start the apache by running this command sudo apachectl start.

Now you should be able to access the CF admin of your localhost.

Friday, March 27, 2015

Returning a structure containing an array of Structures from ColdFusion Webservice

Encountered this issue when I was trying to return a structure containing an Array of structures. The structure I returned contained the array but with empty structures. Though it was accessed from another Coldfusion system, the web service interprets the complex data structure in a different way.

There are couple of useful documents at the adobe help docs on how to handle the complex data types in case of web services.

This is how the code looked when I encountered the issue.


  1. <cfcomponent>

  2.     <cffunction name="testStructReturn" access="remote" returntype="struct">
  3.          
  4.           <cfset var resultStruct = StructNew() />
  5.           <cfset resultStruct.testArray = ArrayNew(1) />
  6.           <cfset var tempStruct = StructNew() />

  7.           <cfset var qryResult = QueryNew("") />

  8.           <cfquery name="qryResult" datasource="testDSN">
  9.                Select first_name, 
  10.                           last_name 
  11.                from employee
  12.           </cfquery>

  13.          <cfset resultStruct.companyName = "zzz company" />
  14.          <cfset resultStruct.companyLocation = "Gandhi Bazaar, Tirunelveli - 2" />
  15.          
  16.          <cfloop from="1" to="#qryResult.RecordCount#" index="i">

  17.                <cfset tempStruct = StructNew() />
  18.                <cfset tempStruct.firstName = qryResult[i][0] />
  19.                <cfset tempStruct.lastName = qryResult[i][1] />
  20.                 
  21.                 <cfset ArrayAppend(resultStruct.testArray, tempStruct) />
  22.           
  23.           </cfloop>

  24.           <cfreturn resultStruct />
  25.     </cffunction>
  26. </cfcomponent>



The above code returned the resultStruct with the array, but empty structures within it. To resolve this. I had to change this line of code 26 to read like this..

<cfset ArrayAppend(resultStruct.testArray, serializeJSON(tempStruct)) />.

Happy coding!

Friday, September 12, 2014

Creating excel report by manipulating the Query result set

There was a situation where in I had to generate a report of team members of different teams, where in a single record should be there for each team with team member names in the same row. But then the database has 4 records for each team.

It was a bit of a challenge for me. Usually in these situations I would use the group attribute to loop through, but I used this query of queries to solve this.

<cfset filename = expandPath("./teamsReport.xls")>
  
 
  <cfset s = spreadsheetNew()>
  <cfset spreadsheetAddRow(s, "Team Id, Member 1,  Member 2,  Member 3 ,  Member 4 ")>
   
   <!--- Loop through the Query result set--->
  <!--- -Create a query header-->
    <cfset qryListTeam = QueryNew("Team_Id,Member_1,Member_2, Member_3,Member_4","Integer,VarChar, VarChar, VarChar,VarChar") />
    <cfset i=0 />
    <cfset j=1 />

Make a Query Of Queries call which would fetch the  4 records of the team.

      <cfoutput query="teamList" group="TEAM_ID">
      
            <cfset queryAddRow(qryListTeam,1) />
            <cfset querySetCell(qryListTeam,"Team_Id",#TEAM_ID#) />
                <cfinvoke component="tag_report" method="listTeamMembers" returnvariable="teamMemberList">
                      <cfinvokeargument name="team_id" value="#TEAM_ID#" >
                      <cfinvokeargument name="teamList" value="#teamList#">
             </cfinvoke>
      
 Build the  qryListTeam which we had already declared.

        <cfset i = 1 />
      
  <cfloop query="#teamMemberList#" startrow="1" endRow="#teamMemberList.RecordCount#">
                <cfif i eq 1>
                    <cfset querySetCell(qryListTeam,"Member_1",#MEMBER_NAME#) />
                    </cfif>
                <cfif i eq 2>
                    <cfset querySetCell(qryListTeam,"Member_2",#MEMBER_NAME#) /> 
                 </cfif>
                <cfif i eq 3>
                    <cfset querySetCell(qryListTeam,"Member_3",#MEMBER_NAME#) />
                 </cfif>
                <cfif i eq 4>
                    <cfset querySetCell(qryListTeam,"Member_4",#TA_MEMBER_NAME#) />
                    </cfif>
                <cfset i++ />
        </cfloop>
    </cfoutput>

    <!--- format header --->   
     <cfset spreadsheetFormatRow(s,
            {
                bold=true,
                fgcolor="lemon_chiffon",
                fontsize=14
            },
            1)>

Now using the custom built Query result set is ready to be used in our spreadsheet.

  <cfset spreadsheetAddRows(s, qryListTeam)>
  <cfset spreadsheetWrite(s, filename, true)>
    <cfheader name="content-disposition" value="attachment; filename=TeamsReport.xls">
   <cfcontent type="application/msexcel" variable="#spreadsheetReadBinary(s)#" reset="true">

Escape pound sign(#) in Coldfusion

There came a scenario, where in the query string which carried the address of the users to another application had a # sign, which broke the system. Pound sign(#), having a special meaning in coldfusion, I had pretty tough time solving it. The solution is just simple.

eg If the address goes like this

    <cfset var address1 = #447, North Avenue />(Probably this is coming from the database)

    Doubling the hash would work if it's displayed in the cfm, wrapped in <cfoutput></cfoutput>. In this case I had to use this

    <cfset queryString = queryString & Replace(address1,"##","CHR(35)","all") />

  •   ## - Here pound sign is escaped by doubling it.
  • CHR(35) is the ASCII equivalent of  pound(#) sign.

Wednesday, August 6, 2014

New line string not appearing in Javascript(Jquery) alert

The error message had multiple lines. But the new line character I had inserted in the string was not recognized.

Eg.
To have a successful authentication, please ensure you have fulfilled the requisites.\nBecome a member by paying the membership amount.\nNot all services come free.

But the newline character was not at all recognized. Instead it alerted the string along with \n.

The reason being while the string reaches ajax from the controller, '\n' becomes '\\n'. The solution for this issue is this...

alert(msg.replace(/\\n/g,"\n"));

This would alert the message as intended.