cfchart displaying white spaces - coldfusion

I am counting response of a specific question and wants to display its response count through charts. I am using this code for counting response.
<cfquery name="questions">
SELECT
questions.id,
questions.question as question,
questiontypes.name as questiontype,
questiontypes.template as template,
surveys.name as surveysname
FROM
questions
LEFT JOIN answers ON questions.id = answers.fkquestionid
INNER JOIN questiontypes ON questions.fkquestiontypeid = questiontypes.id
INNER JOIN surveys ON questions.fksurveyid = surveys.id
WHERE fksurveyid = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.surveyid#">
</cfquery>
<cfset response.question = questions>
<cfloop query="questions">
<cfswitch expression ="#questions.template#">
<cfcase value="truefalse">
<cfquery name="gettotaltruefalse">
SELECT COUNT( IF(result.truefalse = 1,1,NULL )) AS totaltrue,
COUNT( IF(result.truefalse = 0,0,NULL )) AS totalfalse,
COUNT( IF(result.truefalse = 1,1,NULL ))/COUNT(0)*100 AS trueperc,
COUNT( IF(result.truefalse = 0,0,NULL ))/COUNT(0)*100 AS falseperc
FROM results result
WHERE fkquestionid = <cfqueryparam cfsqltype="cf_sql_integer" value="#questions.id#">
AND NOT ISNULL(result.truefalse)
GROUP BY result.fkquestionid
</cfquery>
<cfset response.totaltruefalse = gettotaltruefalse>
</cfcase>
I am using this code to display charts.
<cfoutput query="rc.data.questions" group="id">
<cfchart format="flash" chartwidth="575" chartheight="575" show3d="yes">
<cfchartseries type="pie" paintstyle="raise" seriescolor="blue" datalabelstyle="pattern">
<cfchartdata item="true" value="#rc.data.totaltruefalse.totaltrue#">
<cfchartdata item="false" value="#rc.data.totaltruefalse.totalfalse#">
</cfchartseries>
</cfchart>
</cfoutput>
my problem is, it is showing white space instead of chart even i have tried this in all browsers.

My other answer has to do with server configuration settings based on if you have blocked access to the CFIDE directory. Another approach would be to bypass that behavior by saving the generated chart yourself (a flash file .SWF) to the web server and then displaying that file instead.
It's really easy with ColdFusion. Just add the name attribute to your <cfchart> tag. This will tell ColdFusion to store the binary chart data into the variable named with that attribute. Like this:
<cfchart format="flash" name="chartname" chartwidth="575" chartheight="575" show3d="yes">
<cfchartseries type="pie" paintstyle="raise" seriescolor="blue" datalabelstyle="pattern">
<cfchartdata item="true" value="#rc.data.totaltruefalse.totaltrue#">
<cfchartdata item="false" value="#rc.data.totaltruefalse.totalfalse#">
</cfchartseries>
</cfchart>
In that code I have named the variable chartname. Next, write the data to a file with a .SWF extension. You need to write this file to a browsable directory on your server (like an images folder or some such). Like this:
<cffile action="write" file="C:\webroot\images\mychart.swf" output="#chartname#" />
In that code I wrote the file mychart.swf to the C:\webroot\images\ folder. It can be any directory you wish as long as it is accessible under your web root. The output attribute must match the variable name given in the <cfchart> tag's name attribute and must be within #.
Next, include that SWF file in your HTML code. Like this:
<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,2,0"
WIDTH="575" HEIGHT="575">
<PARAM NAME="movie" VALUE="/images/mychart.swf"/>
<PARAM NAME="quality" VALUE="high"/>
<PARAM NAME="bgcolor" VALUE="#FFFFFF"/>
<EMBED src="/images/mychart.swf"
quality="high" bgcolor="#FFFFFF" WIDTH="575" HEIGHT="575" TYPE="application/x-shockwave-flash"
PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">
</EMBED>
</OBJECT>
In that code the value attribute of the <param> tag and the src attribute of the <embed> tag must match the location of the written .SWF file above (the images folder in this example).

I am guessing it has to do with setup/security on your ColdFusion server. Can you navigate to http://yourserver.com/CFIDE/GraphData.cfm (replace yourserver.com with your domain)? In order for <cfchart> to work it needs access to the CFIDE directory (NOTE - that file does not actually exist. It is merely an alias for the ColdFusion charting).
It also needs access to the CFIDE/scripts directory and the CF_RunActiveContent.js JavaScript file found there.
If you view the source of your generated page (with the blank chart) you will see something like:
<html>
<head><title>Test</title></head>
<body>
<div>
<NOSCRIPT>
<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,2,0"
ID="Images_5281548670100005_SWF" name="Images_5281548670100005_SWF" WIDTH="575" HEIGHT="575">
<PARAM NAME="movie" VALUE="/CFIDE/GraphData.cfm?graphCache=wc50&graphID=Images/5281548670100005.SWF"/>
<PARAM NAME="quality" VALUE="high"/>
<PARAM NAME="bgcolor" VALUE="#FFFFFF"/>
<EMBED src="/CFIDE/GraphData.cfm?graphCache=wc50&graphID=Images/5281548670100005.SWF"
quality="high" bgcolor="#FFFFFF" WIDTH="575" HEIGHT="575" TYPE="application/x-shockwave-flash"
PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">
</EMBED>
</OBJECT>
</NOSCRIPT>
<script type="text/javascript" charset='utf-8' src='/CFIDE/scripts/CF_RunActiveContent.js'></script>
<script type="text/javascript" charset='utf-8'>
CF_RunContent('<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" \r\n codebase="http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,2,0"\r\n ID="Images_5281548670100005_SWF" name="Images_5281548670100005_SWF" WIDTH="575" HEIGHT="575">\r\n\t<PARAM NAME="movie" VALUE="/CFIDE/GraphData.cfm?graphCache=wc50&graphID=Images/5281548670100005.SWF"/>\r\n\t<PARAM NAME="quality" VALUE="high"/>\r\n\t<PARAM NAME="bgcolor" VALUE="#FFFFFF"/>\r\n<EMBED src="/CFIDE/GraphData.cfm?graphCache=wc50&graphID=Images/5281548670100005.SWF" \r\n\t\tquality="high" bgcolor="#FFFFFF" WIDTH="575" HEIGHT="575" TYPE="application/x-shockwave-flash"\r\n PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">\r\n</EMBED>\r\n</OBJECT>');
</script>
</div>
</body>
</html>
Notice the references to the CFIDE directory. If that directory is not accessible the <cfchart> tag will not work correctly (you will get a blank chart).
Two relevant discussions about this with potential work arounds:
On the Adobe forums
By Brandon Purcell

Related

Using cfimage to display a file that doesn't have an extension

curious one this.
I'm working on a process that generates PDF files, combining data from various sources. The last piece of this process I need to complete is merging in image files.
This is actually fairly straightforward but the problem I have is the image files aren't stored with file extensions. Locally, I can change the filename, but in production this isn't an option.
So because a filename looks like : B71637CB-A49C-0653-EF813918736BDEB7
This will not work:
<cfimage action="writeTobrowser" source="#FilePath#>
Same with
<img src="#FilePath#">.
So, any ideas on how I can work around this? Here's the code in context:
<cfdocument format="PDF" name="report" filename="#fileToDownloadimage#" overwrite="yes">
<cfdocumentsection>
<cfimage action="writeTobrowser" source="#FilePath#.jpg">
</cfdocumentsection>
</cfdocument>
So here's what ended up working:
<cfdocument format="PDF" name="report" filename="#fileToDownloadimage#" overwrite="yes">
<cfdocumentsection>
<cfset fileObject = fileReadBinary('#FilePath#') />
<cfset imageObject = imageNew(fileObject) />
<cfimage action="writeTobrowser" source="#imageObject#">
</cfdocumentsection>
</cfdocument>
Alex's answer got me down the right path so I'm perfectly happy to leave the kudos in place, cos I wasn't getting anywhere near this!
If you need to embed the images into the PDF document, try HTML's inline image capabilities:
<cfset fileLocation = "/path/to/images/B71637CB-A49C-0653-EF813918736BDEB7">
<cfset imageContent = fileReadBinary(fileLocation)>
<cfset imageContentAsBase64 = toBase64(imageContent)>
<cfoutput>
<img src="data:image/jpeg;base64, #imageContentAsBase64#" />
</cfoutput>
You can try creating a cfm page that outputs your content using cfcontent as in:
<cfcontent type="image/jpg" file="path/#fielpath#">
Then you would you include THAT cfm page as the source for your image as in
<img src="myFancyImageOuputer.cfm?image=#filepath#">
This should work but it may require some trial and error. :)
Ray has some additional tips here:
http://www.raymondcamden.com/2007/09/14/Serving-up-CFIMages-via-Image-Tags-and-a-NonCF-Friday-contest

Using layouts, partials, and includeContent() in CFWheels

I'm stumped trying to get static content, partials, and layouts to behave and display. I am trying to create:
1 main layout to hold header/footer data
1 partial view for the homepage since it's body layout is different
1 partial view for all other pages
All partials should feed into the main layout which I will build under views/layout.cfm
Here are the files.
Controller/Home.cfc - contains functions for index and privacy
<cfcomponent extends="Controller">
<cffunction name="index">
<cfset qRecipes = model("tblRecipes").findAll(
select="id, name, image, homepage_order",
where="homepage_order > 0",
order="homepage_order",
maxrows=4
) />
</cffunction>
<cffunction name="privacy">
</cffunction>
</cfcomponent>
views/home/index.cfm - Should display the homepage layout
views/home/privacy.cfm - Contain static text wrapped in cfsavecontent like so.
<cfsavecontent variable="foo">
xxxxxxxx
</cfsavecontent>
<cfset contentFor("foo") />
The documentation doesn't provide enough in-depth examples for me grasp at what I'm missing. The main layout will look like:
<cfoutput>#includePartial("/shared/header")#
#styleSheetLinkTag(source="homepage", head=true)#
</cfoutput>asdfsafd
<body>
<div id="page-wrap">
<header>
<cfoutput>#includePartial(partial="/shared/socialmedia", cache=1440)#</cfoutput>
<nav id="top-navigation">
<cfoutput>#includePartial("/shared/topnav")#</cfoutput>
</nav>
</header>
<cfoutput>#includeContent()#</cfoutput> <!--- All partial data should output here --->
</body>
</html>
Since I'm placing all the text for privacy into a variable would I need another page to output #includeContent("foo")# before the main layout would load? Or can I have a page full of text not have to be wrapped in cfsavecontent?
There is no need to wrap your Privacy page in <cfsavecontent>. Try it without the <cfsavecontent> tags and without the contentFor("foo"). Then its contents should appear where you have #includeContent()# in the main layout.
What are you trying to do with the home page that's different? Anything?

CFGRID, CFGRIDUPDATE and extra values

I'm using CFGRID and CFGRIDUPDATE to insert values into a database. The problem is, each record needs to get an additional field that isn't in the grid. Is there any way to save that additional field to the record, or do I have to whip up an alternative to CFGRID?
Basically, I have a bunch of users I'm entering into a grid. The page is getting a category id. I want all of the users to be saved with that category id.
Another thing that would work is if I could get a list of all primary keys, including those for the just-created records, and update all of them with the category id. But it looks like CFGRIDUPDATE doesn't return any information about the rows that were created.
-- original answer removed --
Based on your comment to my original answer, there is now an implied assumption that Category_ID is a foreign key, possibly on a join table, that cannot (for whatever reason) be included in the initial display query--or, that you simply wish to include a dynamic variable into the grid which will be included during inline inserts, without the user intervening (ie. physically preventing them from selecting the Category_ID themselves, but that it will still be dynamic in some capacity, say...by being fed from a URL var).
If correct, I believe the true question leans closer to:
Can a CFGRID update multiple tables/dynamic columns via CFGRIDUPDATE?
Short answer: No
Long answer: Yes, but not via CFGRIDUPDATE--rather, via CFQUERY and a little more work on the CFGRID, via CFC binds and the CFAJAXPROXY.
Solution:
1) You'll need two files for this solution. File #1 is your Component which wraps the query functionality; we'll call it cfgrid.cfc
<cfcomponent>
<cfset this.dsn = "gridexample" />
<cffunction name="getUsers" returntype="any" access="remote" output="false">
<cfargument name="page" />
<cfargument name="pageSize" />
<cfargument name="gridsortcolumn" />
<cfargument name="gridsortdirection" />
<cfset var getUsers = 0 />
<cfquery name="getUsers" datasource="#this.dsn#">
SELECT Users.UserID, Users.FirstName, UserCategories.Category_ID
FROM Users
INNER JOIN UserCategories ON (Users.User_ID = UserCategories.UserID)
<cfif arguments.gridsortcolumn neq "" or arguments.gridsortdirection neq "">
order by #arguments.gridsortcolumn# #arguments.gridsortdirection#
</cfif>
</cfquery>
<cfreturn QueryConvertForGrid(getUsers, page, pageSize) />
</cffunction>
<cffunction name="addNewUser" returntype="string" access="remote" output="false">
<cfargument name="fullname" type="string" required="true" />
<cfargument name="category_id" type="numeric" required="true" />
<cfquery datasource="#this.dsn#">
INSERT INTO Users
(
fullname
)
VALUES
(
<cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.fullname#">
)
</cfquery>
<cfquery name="getPkey" datasource="#this.dsn#">
SELECT Max(User_ID) as PKey
FROM Users
</cfquery>
<cfquery datasource="#this.dsn#">
INSERT INTO UserCategories
(
User_ID,
Category_ID
)
VALUES
(
<cfqueryparam cfsqltype="cf_sql_integer" value="#getPKey.PKey#" />
<cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.category_id#" />
)
</cfquery>
<cfreturn "User Added" />
</cffunction>
<cffunction name="editUser" access="remote">
<cfargument name="gridaction">
<cfargument name="gridrow">
<cfargument name="gridchanged">
</cffunction>
</cfcomponent>
Pay attention to these key pieces of the CFC:
a) getUsers() returns the current user data along with their CategoryID. You'll have to re-write this query to match your schema, but the key takeaway is that this is a data population query, so all the data that's necessary for creating a user should also be present for updating the user as well. This also assumes you only have 1 CategoryID per User (which many developers de-normalize by leaving the CategoryID on the Users table--I'll leave that to your discretion).
b) addNewUser() takes expects the form/grid submission to pass along the new name--as well as the category_id--but we know ahead of time we're not going to be asking that the Category_ID be filled out by the person entering the form/grid data--we'll do that programmatically. The end result is still the same, however--the query is going to need to know both values. For brevity, I've left off <CFTRANSACTION> calls, but bear it in mind--you're about to execute three queries in succession, one of which (the 3rd) depends on dynamic data from the other (the 1st and 2nd)--so you'll need to keep concurrency in mind when you move forward with this type of design.
c) Disregard editUser() for now--you will need to populate it at some point--it simply needs to exist for this demonstration to work.
2) The second file you'll need is the front end--the grid itself, we'll call it cfgrid.cfm.
We'll go through this one, top to bottom, as its quite large, and each chunk of code will need explanation:
<cfparam name="URL.Category_ID" default=4 />
The first line of the template parameterizes a URL variable, which we want to use to programmatically provide behind-the-scenes assignment to new users. Use your own mechanism to supply a dynamic Category_ID as needed.
<cfajaxproxy cfc="cfgrid" jsclassname="dataproxy">
This line causes ColdFusion to create a javascript object named 'dataproxy' and wrap it in a container necessary to provide access the core functions that exist in the CFC you point it to...and in this case, you are pointing it to 'cfgrid', which is our first file mentioned above (cfgrid.cfc). Therefore, you can now comfortably expect that you have a javascript object with getUsers() and addNewUser() methods.
<html>
<head>
<script type="text/javascript" src="/CFIDE/scripts/ajax/ext/package/toolbar/toolbar.js"></script>
Here, you begin your HTML document tags, and include a reference to one of the Ajax libraries included in ColdFusion, the toolbar.js file.
<script type="text/javascript">
var dataproxy = new dataproxy();
dataproxy.setCallbackHandler(handleResult);
function handleResult(response)
{
alert(response);
}
Here, you create a local instance of the dataproxy object (remember above, from the <CFAJAXPROXY> call) and assign a callback handler, which points to another javascript function 'handleResult'. This is the process you employ when dealing with asynchronous communication--a fundamental part of working in Ajax.
function init()
{
grid = ColdFusion.Grid.getGridObject("UserGrid");
var gridHead = grid.getView().getHeaderPanel(true);
var tbar = new Ext.Toolbar(gridHead);
tbar.addButton({text:"Add User", handler:onAdd });
}
This init() function creates the javascript objects necessary to drive communication to the cfgrid. You obtain a reference to the cfgrid via ColdFusion.Grid.getGridObject, and from there, access the grid's header, which allows you to target to toolbar, and add a button "Add User", which you then programmatically decide to call a new function when it is clicked...that function is named "onAdd"...
function onAdd(button,event)
{
ColdFusion.Window.show('addUserWin');
}
Unsurprisingly, here is that onAdd() function, which displays a new window to add a user (its the window that contains the input field for the user's fullname).
Finally, the new AddUserWin Window above is going to need its own function to add a user, since we will need to provide the Category_ID dynamically--as opposed to letting the user supply it. So, addUser() will do just that:
function addUser()
{
var f = document.frmUser;
dataproxy.addNewUser(
f.txtFullname.value,
f.txtCategory_ID.value
);
ColdFusion.Window.hide('addUserWin');
grid.refresh();
}
</script>
</head>
In addUser(), we refer to the <FORM> below by its name (frmUser), and call our javascript proxy object's addNewUser() method--which maps to the CFC. As expected, it'll need to know the values of the new user, so we'll pass it the value of txtFullname and txtCategory_ID. We finish by hiding the window and refreshing the grid.
Remember, we're asynchronous now, so we don't need to read a result and display it--that result will fire via the callback handler assigned above in the handleResult() method.
Now, build the arguments that will feed the population of the CFGRID:
<cfset args = StructNew() />
<cfset args.name = "UserGrid" />
<cfset args.format = "html" />
<cfset args.bindOnLoad = "true" />
<cfset args.bind = "cfc:cfgrid.getUsers({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection})" />
<cfset args.selectmode = "edit" />
<cfset args.onchange = "cfc:cfgrid.editUser({cfgridaction},{cfgridrow},{cfgridchanged})" />
Here we:
1. Name the grid "UserGrid" (as we have referred to it by that name in javascript above),
2. Make it render using html,
3. Tell it to bind its data when the page loads,
4. Bind that data via the cfgrid.cfc, calling the getUsers() method (and passing in the current parameters of the cfgrid via its page, pagesize, sortcolumn, and sortdirection values),
5. Make it editable, and
6. Assign an onChange handler, in case we also want to allow the users to be edited. This last part (unfortunately) is necessary, so I was unable to strip it out for this example.
Now, build the <CFFORM> and <CFGRID>:
<cfform>
<cfgrid attributeCollection="#args#">
<cfgridcolumn name="User_ID" display="false">
<cfgridcolumn name="Category_ID" display="false">
<cfgridcolumn name="FullName" header="Full Name">
</cfgrid>
</cfform>
Here, we populate the grid with our arguments specified above, and you'll note we display only the "FullName" field on the grid, yet User_ID and Category_ID are still present, and a part of the dataset; they simply aren't displayed to the front-end.
Last but not least, the window that will pop-up when a user clicks the "Add New User" button, which provides the interface we need to allow user entry, while at the same time, control (behind the scenes) what Category_ID is dynamically supplied:
<cfwindow name="addUserWin" modal="true" resizable="false" title="Add New User">
<form name="frmUser">
<input type="hidden" name="txtCategory_ID" value="<cfoutput>#URL.Category_ID#</cfoutput>" />
<table width="100%">
<tr>
<td>Fullname</td>
<td><input type="text" name="txtFullname" value=""></td>
</tr>
<tr>
<td colspan="2"><input type="button" value="Add User" onclick="javascript:addUser();"></td>
</tr>
</form>
</cfwindow>
This call to CFWINDOW provides the necessary "pop-up" to encapsulate the form. Note that the form name is frmUser, as we have referred to it above in code. Also, note that the name of the fields match (including their case) what are referred to in javascript. This form displays the Fullname field to the user to fill out, while the Category_ID stays hidden, but is still programmatically driven by you--via your URL parameter at the top of this code example. Finally, the button, when clicked, fires the addUser() method, which you'll recall is the one that talks to the javascript object--which in turn--talks to the CFC--and commits your data to the database.
Finally, just before you complete this template, don't forget to fire your init() javascript function!
<cfset ajaxOnLoad("init")>
</html>
Hope this helps.
Adapted from CRUD with cfgrid html format (Source: Anuj Gakhar)
There is another way. It involves handling directly the form variables which are posted by CFGRID. Here's some example code:
form.cfm:
<cfform method="post" action="post.cfm">
<cfoutput><input type="hidden" name="ParentID" value="#ParentID#"></cfoutput>
<cfgrid format="html" name="GridData" query="Records" insert="yes" delete="yes" selectmode="edit">
<cfgridcolumn name="RecordID" display="no">
<cfgridcolumn name="RecordName" width="150" header="Name" headeralign="left" dataalign="left" select="Yes" display="Yes">
<cfgridcolumn name="RecordColor" width="150" header="Color" headeralign="left" dataalign="left" select="Yes" display="Yes">
</cfgrid>
<br />
<input type="submit" value="Save Records" />
</cfoutput>
</cfform>
then in post.cfm
<cfif isDefined("GridData.RowStatus.Action") and isArray(GridData.RowStatus.Action)>
<cfloop from="1" to="#ArrayLen(GridData.RowStatus.Action)#" index="i">
<cfswitch expression="#GridData.RowStatus.Action[i]#">
<cfcase value="I">
<cfquery name="Records_INSERT" datasource="#request.maindatasource#" blockfactor="100">
INSERT INTO Records (RecordName, RecordColor, RecordParent)
VALUES (
<cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(GridData.RecordName[i])#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(GridData.RecordColor[i])#">,
<cfqueryparam cfsqltype="cf_sql_integer" value="#Val(ParentID)#">
)
</cfquery>
</cfcase>
<cfcase value="U">
<cfquery name="Records_UPDATE" datasource="#request.maindatasource#" blockfactor="100">
UPDATE Records
SET
RecordName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(GridData.RecordName[i])#">,
RecordColor = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(GridData.RecordColor[i])#">
WHERE
RecordID=<cfqueryparam cfsqltype="cf_sql_integer" value="#GridData.original.RecordID[i]#">
</cfquery>
</cfcase>
<cfcase value="D">
<cfquery name="Records_DELETE" datasource="#request.maindatasource#" blockfactor="100">
DELETE
FROM Records
WHERE
RecordID=<cfqueryparam cfsqltype="cf_sql_integer" value="#GridData.original.RecordID[i]#">
</cfquery>
</cfcase>
</cfswitch>
</cfloop>
</cfif>

Fancybox does not seem to work with Coldfusion CFGRID tag

I am trying out CFGRID for the first time. While the grid itself works just fine, I can not get a Fancybox link to work inside the columns. I've added relevant code below. Basically, I do a query, add a query column that contains a link, then output the results in a cfgrid:
<cfquery name="qSessions" datasource="">
SELECT id, title
FROM EVENTS
WHERE c_fkid = 1
</cfquery>
<cfset QueryAddColumn(qSessions,"edit_link","varchar",ArrayNew(1))>
<cfset i = 0>
<cfloop query="qSessions">
<cfset i = i + 1>
<cfset thisText = "Edit this session">
<cfset QuerySetCell(qSessions,"edit_link",thisText, currentRow)>
</cfloop>
<head>
<!--- Javascript library/CSS links would go here --->
<script type="text/javascript">
$j = jQuery.noConflict();
/* Reload the page */
function refreshParent(){
window.location.reload(true);
}
/* Initialization actions on doc ready */
$j(document).ready(function() {
$j(".edit-session").fancybox({
'width' : 600,
'height' : 350,
'hideOnContentClick': false,
'transitionIn' : 'elastic',
'transitionOut' : 'fade',
'type' : 'iframe',
'href' : $j(this).href,
'overlayOpacity' : 0.6,
'onCleanup' : function(){refreshParent()}
});
});
</script>
</head>
<body>
<!---Test Fancybox links outside the CFGRID--->
Test FB
<!--- Output the results of the query --->
<h2 class="header">Sessions in the Database</h2>
<cfform id="testForm" name="testForm" method="post">
<cfgrid name="testGrid" format="html" query="qSessions" width="500">
<cfgridcolumn name="id" header="ID">
<cfgridcolumn name="title" header="Session Title" width="300">
<cfgridcolumn name="edit_link" header="Edit">
</cfgrid>
</cfform>
</body>
The thing is that the test link (outside the CFGRID) works just fine. Click it and the Fancybox iFrame opens up. But the links inside the CFGRID don't produce a pup-up - they take you to the page directly. can anyone provide some guidance on this? Is it related to the fact that CFGRID is built on Ext.js or something? Thanks!
Unfortunately, mixing jQuery and cfform's ajax is never a good idea. Maybe consider porting the use of cfgrid to one of the jQuery grid plugin?
Or use <cfwindow> instead of Fancybox?

How to get rid of weird characters in my RSS feed?

I've created a utf8 encoded RSS feed which presents news data drawn from a database. I've set all aspects of my database to utf8 and also saved the text which i have put into the database as utf8 by pasting it into notepad and saving as utf8. So everything should be encoded in utf8 when the RSS feed is presented to the browser, however I am still getting the weird question mark characters for pound signs :(
Here is my RSS feed code (CFML):
<cfsilent>
<!--- Get News --->
<cfinvoke component="com.news" method="getAll" dsn="#Request.App.dsn#" returnvariable="news" />
</cfsilent>
<!--- If we have news items --->
cfif news.RecordCount GT 0>
<!--- Serve RSS content-type --->
<cfcontent type="application/rss+xml">
<!--- Output feed --->
<cfcontent reset="true"><?xml version="1.0" encoding="utf-8"?>
<cfoutput>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>News RSS Feed</title>
<link>#Application.siteRoot#</link>
<description>Welcome to the News RSS Feed</description>
<lastBuildDate>Wed, 19 Nov 2008 09:05:00 GMT</lastBuildDate>
<language>en-uk</language>
<atom:link href="#Application.siteRoot#news/rss/index.cfm" rel="self" type="application/rss+xml" />
<cfloop query="news">
<!--- Make data xml compliant --->
<cfscript>
news.headline = replace(news.headline, "<", "<", "ALL");
news.body = replace(news.body, "<", "<", "ALL");
news.date = dateformat(news.date, "ddd, dd mmm yyyy");
news.time = timeformat(news.time, "HH:mm:ss") & " GMT";
</cfscript>
<item>
<title>#news.headline#</title>
<link>#Application.siteRoot#news/index.cfm?id=#news.id#</link>
<guid>#Application.siteRoot#news/index.cfm?id=#news.id#</guid>
<pubDate>#news.date# #news.time#</pubDate>
<description>#news.body#</description>
</item>
</cfloop>
</channel>
</rss>
</cfoutput>
<cfelse>
<!--- If we have no news items, relocate to news page --->
<cflocation url="../news/index.cfm" addtoken="no">
</cfif>
Has anyone any suggestions? I've done loads of research but can't find any answers :(
Thanks in advance,
Chromis
Get rid of your escaping code and use XMLFormat instead:
<item>
<title>#XMLFormat(news.headline)#</title>
<link>#Application.siteRoot#news/index.cfm?id=#XMLFormat(news.id)#</link>
<guid>#Application.siteRoot#news/index.cfm?id=#XMLFormat(news.id)#</guid>
<pubDate>#XMLFormat(news.date)# #XMLFormat(news.time)#</pubDate>
<description>#XMLFormat(news.body)#</description>
</item>
View XMLFormat livedoc page.
This worked for me, simply combine into one cfcontent tag and append charset=utf-8.
<cfcontent type="text/xml; charset=utf-8" reset="yes" />
Your escaping function is too simple. You need to change & to & first.
If you use named entities (i.e. £) that is cause of the error.
Sanitize every input when it is entered in the database, that way should simplify the display of such data afterwards.
If you are on Adobe ColdFusion 9 or above, consider using CFFEED with the "escapeChars" attribute to create your RSS (CF8 also supports CFFEED, but not that attribute).
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7675.html