James Brown (yes, him) asks:
Is there a way to assign a value to a client variable using JavaScript? I know JavaScript runs on the client side and ColdFusion on the server, but with AJAX allowing remote calls to ColdFusion I wonder if it might be possible. Thank you for your help.
Yep, and it's so easy, it's rather trivial. As long as you can make a HTTP request with Ajax, then you can run any code you would imagine.
I've been blogging about jQuery pretty extensively lately so let's do this one just using what ships in ColdFusion 8. First, I'll create a simple form:
<form>
Set Name: <input type="text" name="name" /> <input type="button" value="Set" id="btn" />
</form>
Next I'll use the cfajaxproxy to bind to the name form field.
<cfajaxproxy bind="url:setname.cfm?name={name}">
This simply says: Generate JavaScript that watches for a change to the name value and pass it to the url: setname.cfm?name={name}, where {name} will be the value of the form field. The tag also allows you to run CFC methods or JavaScript functions. setname.cfm is simply:
<cfparam name="url.name" default="">
<cfset client.name = url.name>
And that's it. You may want to change when the Ajax call is made. By default it is fired with the onBlur event. So if you click the set button, or anything else on the page, the Ajax call is made. You could modify things a bit and tell it to fire just on the button click:
<cfajaxproxy bind="url:setname.cfm?name={name@none}&{btn@click}">
This bind expression means: Pass name, but don't monitor it (none), and monitor the btn button's click event. Why is there a & between the two binds? I needed a valid URL for the request and the bind has to actually be in the URL itself. Not quite as obvious and simple as the first example, but it gives you a bit more control by running just when the button is clicked.
Archived Comments
Ray, thank you so much!
on the same sort of wave length 'but the other way around' if you need to get server side data via Javascript for example a query inside a CFC you can create the CFC as a JavaScript object e.g.
<cfajaxproxy cfc="components.something" jsclassname="callsomething"/>
this has been my life saver over the last few weeks, I love ColdFusion!
Are there any security concerns with this logic? I know this example simply uses a "name" variable, but, it doesn't seem safe to be setting session or client variables with a URL param. Would it be possible/safer to use a CFC with arguments to do this?
Using a CFC would be no safer at all. It would just be a different way to do it. It would be no safer than switching to using a form either. By the same token, it is no less safe. Any session/client variable that you let someone set should be secured if it needs to be. There is no need to worry about someone setting their favorite color, for example. Letting them set their discount for a shopping cart would be a problem though.
Security in both cases would only be as good as the developers code. a CFC would have to be access remote for this to work, but anything passed to the server needs to be checked and cleaned regardless of the methoud being used.
In the case of a shopping cart, I have used a CFC as a Javascript object, but nothing gets written to the cart directly using the object, everything is checked against the a database so price and description have to match also its cleaned from injection etc... but the same goes for anything like cfhttp calls etc.
Yes, it makes sense now. I forgot that in order for AJAX to call a CFC, it would have to be remote. I should know that, because that's what I've been doing for my Flex apps for the past two years.
Thanks.
I wouldn't have thought of that list trick with "&{btn@click}". I would have thought that would have returned some value like 1. Cool.
I have recently had CF8 installed and now trying to get to grips with the news features.
When i try the script above and click the 'set' button, I get a big popup error saying 'Error parsing JSON response:' followed by the HTML of the page.
Any idea where I'm going wrong?
Use Firebug and take a look at what CF returned. It is probably an error and it will tell you more about what went wrong.
Wowza, super fast response thanks Raymond.
I will start a topic in the forum about this, so I don't pollute the comments area here.
I'm having trouble working this out.
I created a similar script as above and added an onsuccess attribute to perform a javascript function if the bind is successful. But the bind was not performed. My code is as follows:
File temp.cfm
function test1()
{
alert("hello");
}
<form>
set name : <input type="text" name="name" /><input type="button" id="btn" />
</form>
<cfajaxproxy bind="url:test.cfm?name={name@none}&{btn@click}" onSuccess = "test1();">
File test.cfm
<cfset session.temp = "url.name">
But it not working as the variable session is being set url.name and not the value from the input.
Please help as it is very important
Your button uses an ID of "btn". Switch that to name="btn".
Ray! YOu are a lifesaver!!!!!
Ray, I'm using jqGrid and I want use CFwindow to pop a modal window to display dynamic data. I'm having trouble passing the value of the grid to my window.
How do I bind to a non form object?
Thanks, Jim
This is what I have.
<cfajaxproxy bind="url:ShipDetail.cfm?thisSN={SN}"> <!--- my bind --->
// my grid event
onCellSelect: function(rowid,iCol,cellcontent){
var SN = +cellcontent; // trying to set the bind here
if (iCol == 0) {
ColdFusion.Window.show('Shipments'); // display my cfwindow
}
},
My cfwindow:
<cfwindow name="Shipments"
title="Shipments"
modal="true"
resizable="true"
center="true"
initshow="false"
source="ShipDetail.cfm"> </cfwindow>
ShipDetail.cfm contains the cfc and code to display value based on thisSN, which is what I'm trying to bind.
I wouldn't. Remember there is a JS api to create/manipulate CFWINDOWs. Just use that.