Remoting for ColdFusion Flash Forms
We had given for granted that it was not possible to use Flash Remoting with ColdFusion Flash Forms because of the ActionScript language restrictions that they have. All workarounds used external .swf loaded into the form, so we never used them and we never investigated any further. Otherwise, we would’ve found that there is a simple way to get remoting in ColdFusion Flash Forms sooner. In any case, here it is, better late than never. Note that this does not use external swf and therefore it is not a hack.
As an introduction, we made a simple example in which we call a cfc that returns a formatted string according to the parameter passed.
<cfsavecontent variable="getData"> //create connection, replacing the gateway url with yours var connection:mx.remoting.Connection = mx.remoting.NetServices.createGatewayConnection( &quot;http://www.example.com/flashservices/gateway/&quot;); //declare service var myService:mx.remoting.NetServiceProxy; //put the controls in scope to avoid calling _root var mask = mask; var display = display; //make an object that will handle the response var responseHandler = {}; //function that receives the response responseHandler.onResult = function( results: Object ):Void { //when results are back, we show the text received display.text = results; } //function that receives any error that may have occurred during the call responseHandler.onStatus = function( stat: Object ):Void { //if there is any error, show an alert alert(&quot;Error while calling cfc:&quot; + stat.description); } //get service. First parameter is path to component and the second it's the object that will handle the response myService = connection.getService(&quot;blog.examples.flashRemotingResponder&quot;, responseHandler ); //make call, passing one parameter myService.getDate(mask.text); </cfsavecontent> <!--- then the form ---> <cfform format="Flash" name="myform"> <cftextarea label="Mask" name="mask" type="text">mmmm dd of yyyy hh:mm:ss</cftextarea> <cfinput label="Result" name="display" type="text"> <cfinput name="getDataBtn" onclick="#getData#" type="Button" value="Get Date"> </cfinput></cfinput></cfform>
This is what the cfc does, as you can see it’s a very simple function.
<cffunction access="remote" description="Returns the current time" name="getDate" output="false" returntype="string"> <cfargument default="" name="mask" required="false" type="string"> <!--- get the current time ---> <cfset time="now()" var=""> <cfif> <!--- format the date according to mask ---> <cfset time="dateformat(time,arguments.mask)"> </cfset></cfif> <cfreturn time=""> </cfreturn></cfset></cfargument></cffunction>
A live example
Download the source
A couple of notes on Remoting:
The component that you call has to be web accessible for the Remoting gateway to find it, just like when you create a web service, and the method has to have access="remote".
The path to the component is the directory structure as viewed from the root of your website, separated by dots, followed by the component name. For example, if your component is located at http://www.example.com/somedir/components/myComponent.cfc, then the path would be somedir.components.myComponent
That being said, I never have my components in the root of my website, but in a mapping called com, where I have directories with the names of my domains. I then call my components com.blueinstant.somepackage.myComponent
This, however, won’t work with remoting, so what I do is create a façade component that exposes only the methods that flash needs, and can even format the data specifically for flash, separating this from my other components that know nothing about the views. In addition, from that component I can enforce security or call an already instantiated object that I keep in a shared scope.
Lastly, the documentation warns that Application.cfc should not implement the “onRequest” method if we have “any CFC files that are intended to be accessed as web services, using Flash Remoting, or using an event gateway”
Brian Sloan
Brian Sloan
Philippe
Brian Sloan
1. Does the cfc have to be in the root of site? It appears it does and all mine are under a components directory. Is there any way around this or do I have to put the cfc in the root?
2. If my application.cfc file is present I get an event handler exception. It appears something in it is stopping the flash remoting from working. Any ideas or solutions to this problem? I need the application.cfc for security reasons.
Steve Walker
I don't know if this will help in your scenario, but I point to my components in the Application.cfc file (e.g. <cfset Request.libcfc = root.folder.file>) and then using their example :
myService = connection.getService("<cfoutput>#REQUEST.libcfc#</cfoutput>", responseHandler );
and everything works fine
Steve Walker
2. Is there a way to present an empty grid without using queryNew()? Having to do this sort of defeats the purpose of using reusable components.
Brian Sloan
Thanks... I will try putting them under a completely different site. As far as I know you need the queryNew at this point for the grid to function. If there is no query= in the grid tag you can not add rows.
Brian Sloan
Thanks,
Brian
Steve Walker
Todd
Pedro Claudio
WebService,HTTPService,RemoteObject
Laura
the class mx.remoting.Connection
is a Flash remoting class, not specifically Flex. It does come with Flex, since Flash Forms use the remoting packages.
Was that your question?
Nahuel
I don't know why you don't have bindings anymore. I would suggest you to check the column names of your data.
Pedro Claudio
mx.core.*
mx.charts.*
mx.Remotig.*
mx.Service.W*
mx.Service.*
mx.servicetags.*
Philippe Maegerman
I was just wondering how you did find out about these classes, no doc I guess?
Todd
I'm sure I'm doing something wrong, but bindings are still not working. I thought I'd try your source code since I may have goofed my column names, and still no luck. Here is my code - the only thing I added to your example was the bound text box:
<cfform name="myform" height="350" width="400" format="Flash" timeout="300" >
<cfgrid name="contactList" query="memberList" height="200" rowheaders="false">
<cfgridcolumn name="name" header="Name" />
<cfgridcolumn name="age" header="Age" />
<cfgridcolumn name="gender" header="Gender" />
</cfgrid>
<cfinput type="button" name="getValues" value="Populate data grid" onClick="#getData#">
<cfinput type="text" name="test" bind="{contactList.dataProvider[contactList.selectedIndex]['name']}">
</cfform>
Thanks for any possible advice you may be able to give. Keep up the amazing work - I really hope you guys are making some money off this - You really deserve it!
Steve Walker
Try:
bind="{(contactList.selectedItem.name ==undefined)?'':contactList.selectedItem.name}"
It is working for me. The first part ensures that the field is blank instead of the word undefined.
Todd
Paul Roe
Nahuel
You don't need to buy anything. ColdFusion already comes with Remoting :)
Paul Roe
Error /CFIDE/scripts/cfform.swc
Unable to resolve library location.
Error /cfgrid-remoting.cfm:4
Unable to load runtime shared libraries.
Does Flash remoting require any setup?
Laura
Remoting setup is not the problem, at least not yet. Your Flash forms do not work because you don't have the cfide folder web accessible. You can either copy the CFIDE folder (without the administrator if you don't need it) to your web root or make a virtual directory pointing to it.
Hope that helps
Paul Roe
CarlosM()
OK, here’s my question….
I'm running CFMX7 Standard w/Apache2 on Suse9ENT , can I still do the remoting or do I need CFMX7Ent running on a Java Server???
Now I was able to get:
CFMX7ENT .WAR running with TomCat4 with the Apache hook on SuSe9Ent but I had problems with the RDS so I went back to the CF Standard Edition. Is this going to haunt me?
Marcus
CarlosM()
Isn't it great when thing just work.
Ok, I hope I'm not asking too much but is it possible to create a custom tag for this?
Nahuel
Yes, you can pass as many as you want.
Carlos,
We'll add that to the wish list :)
Neil Bailey
Also, the object that gets passed into onResults - I can't find ANYTHING on this object. Does anyone know where I can see soms docs on this?
Nahuel
These are the docs
http://livedocs.macromedia.com/flashremoting/mx2004/index.html
Neil Bailey
Thanks - I actually managed to figure this out, too (this one on my own!) Actionscript won't take a structure back (at least according to the docs), but it WILL take an array. So, I got it straightened out. Thank you again for your help, and keep up the good work.
Marcus
Thx
Marcus
Marcus
Laura
ActionScript does take structures back. We use it all the time. In fact, we use it the MXNA application (check mxna.cfc for example). All of the functions there return structures, not plain queries. The problem you must have had is the case in the structure. When you create a structure and set up the keys as myStruct.key1, CF will make it uppercase, myStruct.KEY1. Because ActionScript is case sensitive, it will not find it.
In order to keep your desired case, you must create your structure keys as
<cfset myStruct["key1"] = "" />
<cfset myStruct["msg"] = "" />
and so on.
Kola
I've really just started putting flash forms through their paces (while learning flash at the same time). Question I have is does anyone envisage this being disabled in anyway in one of the new releases? I imagine that MM didn't really want cfdevelopers to be able to utilise remoting in this way and would rather we all use flash?
Kola
Neil Bailey
Neil Bailey
I am literally pulling my hair out here! I simply cannot get the actionscript code in the main page to see the values returned in a structure.... I created the struct in the CFC as you suggested above, and at this point........ haha I'm sure you've been at this point once or twice..
responseHandler.onResult = function( results: Object ):Void {
//when results are back, populate the data fields
_root.first_name.text = results.first_name;
}
PLEASE let me know what I am doing wrong here.....
Liz
I currently call my myservice.getProduct ({spc_product_code_id:oi_product1.value}) which should return a row of data. This is my component function:
<cffunction name="getProduct" output="Yes" returntype=Query access="remote">
<cfargument name="spc_product_code_id" type="String" required="True">
<cfquery name="getdata" datasource='#DataBse#' timeout='30'>
select SPC_PRODUCT_CODE_ID,
SPC_PRODUCT_NAME,
SPC_UNIT_PRICE_MN,
SPC_ACCTG_CODE_ID
from T_SUPP_PRODUCT_CODES WITH (NOLOCK)
where SPC_PRODUCT_CODE_ID = #val(spc_product_code_id)#
Order by SPC_PRODUCT_NAME
</cfquery>
<cfreturn getdata>
</cffunction>
(The query works fine non-remotely.)
However, when I try to access the results from the responseHandler I get garbage displayed in my oi_price1.text display field.
responseHandler.onResult = function( results: Object ):Void {
oi_price1.text = results.spc_unit_price_mn;
}
What is the correct syntax to access the data returned in the results variable? Please help!
Liz
Neil Bailey
Laura
It is not the same if you are returning a structure than a query. If you return a structure, this should work as long as the case is correct:
oi_price1.text = results.spc_unit_price_mn;
if you are returning a query, then you receive a recordset in flash, which has its own syntax for accessing the elements. In your example above, you can access it as:
var record = results.getItemAt(0);
_root.oi_price1.text = record.spc_unit_price_mn;
or simply
_root.oi_price1.text = results.getItemAt(0).spc_unit_price_mn;
but make sure spc_unit_price_mn has the correct case. It should be like it is in your db (is it all caps?)
Neil Bailey
However, when I access results[0] I get the first value. Go figure.......
Liz
Neil Bailey
However, when I access results[0] I get the first value. Go figure.......
Neil Bailey
Neil Bailey
Anyway, last question, is there anyway to pass the entire form to a CFC?
Aaron Longnion
/flashservices/gateway/ should be correct for my site. I was told if I go to [mySite]/flashservices/gateway/ and I get a blank page, then that confirms that the directory is correct...
What am I doing wrong?
Jock S
Neil Bailey
I would think you would be able to do something with the setInterval function.... have it call a CFC, which returns whatever, every.....however often....
This is the way I would start. Course, I am fairly far down the totem pole when it comes to experience......
Joe
Philippe Maegerman
myService.myMethod(field.text,combo.selectedItem.label,...);
Then in your CFC, you declare them as arguments:
<cfargument name="field1">
<cfargument name="field2">
...
Joe
Anyone have a good example of how to parse through a ColdFusion query recordset in actionscript? I'm getting the query from a cfc call (remoting).
Philippe Maegerman
... recordset.getItemAt(i).PROPERTY
}
Philippe Maegerman
<a href="http://livedocs.macromedia.com/flashremoting/mx/Using_Flash_Remoting_MX/asDict.htm" target="_blank">http://livedocs.macromedia.com/flashremoting/mx/Using_Flash_Remoting_MX/asDict.htm</a>
Chip Mayan
Neil Bailey
I asked the exact same question above. In the cfc, instead of setting the structure up as structName.keyName = whatever, set it as structName["keyName"] = whatever. Then in the cfSaveContent variable, access it as result.keyName.
You need to do it like this to preserve case-sensitivity. As will not see results.keyName if ColdFusion returns it as results.KEYNAME or results.keyname or whatever.
I had a LOT of trouble getting through this, but make sure your CFC has a return type set to struct, make sure that you set your structure keys correctly in the CFC, and you shouldn't have any problems.
Stephen Moretti
wms05 is a CF Mapping to the appropriate folder.
The "flashservices/gateway" folder exists.
Here's a snippet of the actionscript :
//set variables
var AccountNo = '#session.User.AccountNo#';
var dsn = "myDSN";
//get service
myService = connection.getService("wms05.orders.OrderForm", responseHandler );
//make call
myService.getCarriage(dsn,AccountNo,total.text);
And here is the cfinvoke for the same cfc.
<cfinvoke component="wms05.orders.OrderForm" method="getCarriage" returnvariable="qryCarriage">
<cfinvokeargument name="DSN" value="#request.productdsn#">
<cfinvokeargument name="AccountNo" value="00027">
<cfinvokeargument name="OrderValue" value="1000">
</cfinvoke>
I'm at a loss! Any help would be much appreciated.
Stephen
Stephen Moretti
Dave Watts pointed out that although I have a CF mapping to wms05 I probably didn't have a mapping in the webserver to wms05 for the direct call to the cfc by URL (which is what the "connection.getService()" function is actually doing.)
Laura
From the notes about remoting in the post:
"The path to the component is the directory structure as viewed from the root of your website, separated by dots, followed by the component name."
That means the path has to be web accessible and also, the directory structure has to exist, either by real directories or by web server virtual directories. You must be able to browse to that folder and cfc. CF mappings are not enough, as the web server has no idea of their existence.
Tim
In one CFFORM, I have a CFGRID that contains rows from a query. Then I have three textarea elements. When you click on a row in the grid, I want the textarea elements populated from the result of a method call to my CFC.
I think I understand the "getData" code, but how do I trigger the remote call when I click on a row in my cfgrid? The method I am calling expects an ID (which is one of my columns in the cfgrid).
Nahuel
Cfform has an event on the grid that is called "onchange". This gets executed everytime the user selects a row. You need to make the call to your cfc inside that event.
Muzak
Just add the following line at the top of the cfsavecontent block:
// enable NetDebugger
mx.remoting.debug.NetDebug.initialize();
Open the NetConnection Debugger before opening the .cfm page and watch the data displayed in the Debugger ;-)
regards,
Muzak
Nahuel
Mark
var responseHandler = {};
var Type = Type.value.split(",").join("|");
responseHandler.onResult = function( results: Object ):Void {
//when results are back, populate the cfgrid
searchResults.dataProvider = results;
}
responseHandler.onStatus = function( stat: Object ):Void {
//if there is any error, show an alert
alert("Error while calling cfc:" + stat.description);
}
//get service
myService = connection.getService("ssLite", responseHandler );
//make call
myService.getSerchResults(Type);
<cfselect enabled="Yes" name="Type" size="3" label=" Type:" multiple="yes">
<option value="0" SELECTED>All Types</option>
<option value="typea">A</option>
<option value="typeb">B</option>
<option value="typec">C</option>
<option value="typed">D</option>
</cfselect>
Nolan Dubeau
I am having some serious problems deploying my app to a live server and wonder if you could explain about the façade component with regards to Remoting. It appears that there are some comments on this issue, but I am at a loss to resolve. On my local machine the path to my components is www_mysite_com.com.concrete.somecomponent.cfc, and on the live server I created a CF mapping called www_mysite_com, and pointed it to the root directory of the site. Everything seems to be working correctly except for the Remoting calls. Any help is appreciated.
Matt
http://www.talkingtree.com/blog/index.cfm?mode=entry&entry=25AA89CA-45A6-2844-79F890861E204161
One issue I am having is applying a filter after calling the onClick="#getData#;applySomeOtherFilter()". The getData gets called, but the applySomeOtherFilter doesn't work. Without the #getData# call the filter does work. Any suggestions?
Laura
Flash remoting ignores CF mappings. The path has to be exactly your path from the root to the cfc, as if you were browsing it, just replace the slashes with dots. (Check the notes on remoting in the post) As a side note, you can have a virtual directory in IIS and that would be fine, because you can browse it, but not CF mappings.
Matt,
I think your problem is that you are calling the filter before the data gets back. You need to have your filter in the onResult or myFunction_Result function. These are asynchronous calls, so the data is not available as soon as you make the function, and there is no guarantee about when it will arrive.
Matt
clientGrid.dataProvider = results; // where results have 7 records
clientGrid.dataProvider.length is equal to 7
However, I am not able to iterate over the newly populated data grid for some reason. ie clientGrid.dataProvider[1]["columnname"] is empty.
Any suggestions?
Laura
For your example to work, you need to set the dataProvider as:
clientGrid.dataProvider = results.items;
Mike
I want to return just one row of a query from a cfc. But I can't figure out the correct way to get it from the cfc back to the cfm. It always comes up as undefined. If I go from returntype="string" I get a different error. Any help would be appreciated.
Mike
Laura
If you are sending the query directly, then access the first (and only) item by:
var item:Object = results.getItemAt(0);
then item is a structure with columns as keys.
item.myColumn
Mike
Thanks alot, that worked well.
Mike
colin
I am trying to display the data returned from a cfdirectory query, for some reason i get the headers back, but not the actual data list.
any reason that you may know of ? Everything works fine if i use an actual db query name.
Thanks in advance :)
NetConnectDebugInfo:
--------------------------
Result (object #2)
.....mRecordsAvailable: 0
.....serverInfo: (undefined)
.....uniqueID: 0
....._items (object #3)
..........No properties
.....mTitles (object #4)
..........[0]: "Name"
..........[1]: "Size"
..........[2]: "Type"
..........[3]: "DateLastModified"
..........[4]: "Attributes"
..........[5]: "Mode"
..........[6]: "Directory"
Ken
I need to check if a value entered into a text box already exists in the db.
No problem there I have modified your great example of flash remoting to do this.
But if the value is found, I would like to display to the user an alert message (plus disable the submit button, which I have done)
But I have also used your alert example and the problem I encounter is that it just hangs until a message come back saying that the script is causing the player to run slowly.
Can you shed some light on this problem ?
I should also say that if I don't use your alert example and just use
alert('my alert text');
it works, but as the form is long the alert message is not displayed on the screen, the user has to scroll down to it. I have also not been able to "move" this alert.
Ken
I have found that the problem with this is the scope setting of "this", if I change this to "_root" it all works as expected. But of cause the alert box will not close. I have tried replicating the deletePopup() code from flash but no luck as yet.
Ken
Philippe Maegerman (Pim)
Ken
But it's most probably where I have to put it is the problem.
Here is my code
responseHandler.onResult = function( results: Object ):Void {
//when results are back, we show the text received
display.text = results;
var alertSettings:Object = {closeButton:true, title:'Warning', message: "My Message", width:350, x: 60, y: 10, headerHeight: 27};
var myTW = mx.managers.PopUpManager.createPopUp(_root, FormErrorException, true, alertSettings);
var windowListener = {};
windowListener.click = function(){
_root.myTW.deletePopUp();
}
myTW.addEventListener("click", windowListener);}
I have tried a number of combinations all with no result.
Ken
Heres the code that works
var msg = 'A simple alert with position x:60, y:10';
var alertSettings:Object = {title:'Off center', message: msg, headerHeight:27, x: 60, y: 10};
_root.errorpopup = mx.managers.PopUpManager.createPopUp(_root, FormErrorException, true, alertSettings);
Ken
Laura
I am glad you got it working.
However, as I said the post http://www.asfusion.com/blog/entry/customizing-a-cfform-alert-with-pictures-and
I would strongly recommend *against* using the errorpopup variable. It depends too much on current cfform implementation code. If you use it, you must be willing to accept that your code may break in future CF releases.
Ken
Thanks for the response. Yes, I did read your comments in your example and yes I do agree.
But as the form I have is long (I have no option here, clients !!), I have to resolve the alerts being displayed in a position that you have to scroll down to them. If I could find a way to move the normal "alert" then I would use them.
Just have to be aware that the code may break.
Ken
Nelly
"Error while calling cfc: Service threw an exception during method invocation:null"
Is there something wrong with my Flash Remoting configuration? I am using ColdFusion MX 7.0.1 (merged with Flex). Both files are in my root folder and the server name is cfusion.local (for development use). So I set the connection and get service values as follows:
var connection:mx.remoting.Connection = mx.remoting.NetServices.createGatewayConnection("http://cfusion.local/flashservices/gateway/");
myService = connection.getService("flashRemotingResponder", responseHandler );
Can anyone tell me what the source of the error is?
REB
Thank you for explaining remoting! This has helped me to understand the requirements for returning results. Thanks!
-Richard
MJE
I am hoping that this example can solve my woes. I'm losing it over here! Here is the issue - I need to be able to filter an item in a select list based on an item that is selected in a datagrid (which in turn binds three of the grid fields to text boxes).
In my mind, the easiest way to do this would be to have a query that basically says select * from table where value="{mydata.text}" - of course, that would be in a perfect world, and I have not, for the life of me, been able to figure out how to query using cf.query or cfscript, or this example, so that I can filter the select box based on either the item selected in the data grid, or the text box that it is bound to.
Here is what I am working with so far - the job guide section below is what needs to be made dynamic based on the publication chosen:
<cfgrid name="grid" query="getPublications" selectmode="single" rowHeaders="false" height="100" tooltip="Choose a source reference from the list below">
<cfgridcolumn name="publication" width="300" header="Source Reference" >
<cfgridcolumn name="pubDate" header="Pub Date" display="false" mask="MM/DD/YY">
<cfgridcolumn name="changeTitle" width="75" header="Change Title" display="false" >
<cfgridcolumn name="changeDate" header="Change Date" display="false" mask="MM/DD/YY">
</cfgrid>
</cfformgroup>
<cfformgroup type="Horizontal" label="Publication:">
<cfinput tooltip="Choose a publication/source reference from the list above" type="text" name="taskPublication" bind="{grid.selectedItem.publication}"
required="no" message="Please select a task publication" editable="false">
</cfformgroup>
<!--- pub date, change title and change date --->
<cfformgroup type="HBox">
<cfformgroup type="VBox">
<cfinput type="text" name="pubDate" label="Pub Date:" bind="{grid.selectedItem.pubDate}" editable="false">
</cfformgroup>
<cfformgroup type="VBox">
<cfinput type="text" name="changeTitle" label="Change Title:"bind="{grid.selectedItem.changeTitle}" editable="false">
</cfformgroup>
<cfformgroup type="VBox">
<cfinput type="text" name="changeDate" label="Change Date:"bind="{grid.selectedItem.changeDate}" editable="false">
</cfformgroup>
</cfformgroup>
<!--- job guide - THIS IS THE AREA that needs to be filtered by publication selected - all I need to be able to do is figure out how to get the taskPublication field, or the publication field selected in the grid to be used as a variable to filter the job guide - Please help! --->
<cfformgroup type="HBox">
<cfformgroup type="VBox">
<cfselect name="jobGuide" label="Job Guide No:">
<option value="">Select a job guide</option>
<cfoutput query="getJobGuides">
<option value="#jobGuide#">#jobGuide#</option>
</cfoutput>
</cfselect>
</cfformgroup>
MJE
Now, I'm getting the same issues with the binding mentioned earlier, but the posted resolve did not work for me. All I did was copy and paste the code that worked into my test page with the cfselect. This is the final missing piece - is there another 'foolproof' binding format that I can use?
MJE
Don
Ed
Laura, you are the MA... er,well you ROCK! Thanks so much for the post!
David
Was there an option to install the flash service during CF installation that I could have deselected?
Laura
/flashservices/gateway are not actual directories. They are a servlet mapping defined in the web.xml file and it is installed by default. In previous versions, you could see a blank screen if you browsed directly, but that is not the case anymore, the simplest way to make sure you have it properly installed is to run the code and see if it works :)
daniel fredereicks
What if I am trying to insert a swf file into say an accordion? I can get it to display using the <img> tag, but, i am also using flash remoting, which for some reason does not seem to bring bacm my data and display.
Is there any conflict between cf flash forms and the swf?
I really need to find this answer.
dan
Tom
"Element USERNAME is undefined in VARIABLES"
Daniel Fredericks
Help me on this....
Gerald
Brian
Checklist:
-Coldfusion mx 7
-I see the flash form and form elements
-Click on "Get Data"
-Then error is called with flash pop-up.
Thanks, Brian
Laura
It is very difficult to say what exactly your problem with the swf is. It should work fine, but remember there will be no communication between the form and your swf unless you program it to do so.
Tom,
That means you have an error in your cfc.
Gerald,
You could loop over the records of your datagrid and create an array with the data you need or if you loaded the grid normally (not manually via remoting), you could send the dataprovider directly and receive it as an array in CF.
Brian,
The example assumes you have your file in the root of your site (http://www.example.com/simple-remoting.cfm ) If that is not your path, then you need to change it in the line that calls the service (getService())
Rey
<cfsavecontent variable="checkValues">
if (emp_NAMEa.text == '')
{
mx.controls.Alert.show('Employee Name is required!');
}
else if (FTa.text == '')
{
mx.controls.Alert.show('Employee Status is required!');
}
else if (TITLEa.text == '')
{
mx.controls.Alert.show('Employee Title is required!');
}
else if (DM_NAMEa.text == '')
{
mx.controls.Alert.show('District Manager Name is required!');
}
else if (DOHa.text == '')
{
mx.controls.Alert.show('Date of Hire is required!');
}
else if (SVC_MGR_NAMEa.text == '')
{
mx.controls.Alert.show('Service Manager Name is required!');
}
else
{
//create connection, replacing the gateway url with yours
var connection:mx.remoting.Connection = mx.remoting.NetServices.createGatewayConnection("http://localhost/flashservices/gateway/");
//declare service
var myService:mx.remoting.NetServiceProxy;
//put the controls in scope to avoid calling _root
var emp_NAMEa = emp_NAMEa.text;
var FTa = FTa.text;
var TITLEa = TITLEa.text;
var DM_NAMEa = DM_NAMEa.text;
var DOHa = DOHa.text;
var SVC_MGR_NAMEa = SVC_MGR_NAMEa.text;
//make an object that will handle the response
var responseHandler = {};
//function that receives the response
responseHandler.onResult = function( results: Object ):Void {
//when results are back, we show the text received
var msg = results;
}
//function that receives any error that may have occurred during the call
responseHandler.onStatus = function( stat: Object ):Void {
//if there is any error, show an alert
alert("Error while calling cfc:" + stat.description);
}
myService = connection.getService("cfc.add_emp", responseHandler );
//make call, passing one parameter
myService.addEmp(emp_NAMEa.text,FTa.text,TITLEa.text,DM_NAMEa.text,DOHa.text,SVC_MGR_NAMEa.text);
}
</cfsavecontent>
and here is my cfc:
<cfcomponent>
<cffunction name="addEmp" access="remote" returntype="string">
<cfargument name="TITLEa" type="string" required="false" default="">
<cfargument name="emp_NAMEa" type="string" required="false" default="">
<cfargument name="FTa" type="string" required="false" default="">
<cfargument name="DOHa" type="string" required="false" default="">
<cfargument name="DM_Namea" type="string" required="false" default="">
<cfargument name="SVC_MGR_NAMEa" type="string" required="false" default="">
<!---Add employee--->
<cfswitch expression="#form.TITLEa#">
<cfcase value="Bio Sys Service Supervisor">
<cfset TechCode = "Sup">
</cfcase>
<cfcase value="Bio Sys Service Manager">
<cfset TechCode = "Man">
</cfcase>
<cfcase value="Bio Sys Service Specialist">
<cfset TechCode = "Tech">
</cfcase>
<cfcase value="Bio Sys District Manager">
<cfset TechCode = "DM">
</cfcase>
</cfswitch>
<cfquery datasource="stcycle">
INSERT INTO dbo.payroll (TechCode, emp_NAME, FT, DOH, TITLE, DM_Name, SVC_MGR_NAME) VALUES ('#form.emp_Namea#','#form.FTa#','#form.DOHa#','#form.TITLEa#','#form.DM_Namea#','#form.SVC_MGR_NAMEa#','#TechCode#')
</cfquery>
<cfset msg = 3>
<cfreturn msg>
</cffunction>
</cfcomponent>
Any thoughs as to why it's not working correctly, meaning it's not inserting the values passed by the form into the database, I have been at this for 2 days now, Please Help!!!
Ed
Providing you are not getting an error...
Try removing the form. in front of your cold fusion variables in the insert statement... Remoting does not use the form scope. For example try this:
INSERT INTO dbo.payroll (TechCode, emp_NAME, FT, DOH, TITLE, DM_Name, SVC_MGR_NAME) VALUES ('#emp_Namea#','#FTa#','#DOHa#','#TITLEa#','#DM_Namea#','#SVC_MGR_NAMEa#','#TechCode#')
Also, remove the .text in the call below...
myService.addEmp(emp_NAMEa.text,FTa.text,TITLEa.text,DM_NAMEa.text,DOHa.text,SVC_MGR_NAMEa.text)
You are referencing the variable that already holds the text in the variable calls above...
Also..
In your insert call your variables appear to be out of order. Try putting '#TechCode#' in the beginning of the values call to match the column name list.
If you are getting a remoting error... Let me know.
Hope this helps!
Ed
Rey
Rey
Ed
A couple of other things i see here that may help...
In the myService.addEmp it appears that your variables you are passing are out of order with the component...
The variables you pass must be in the same order as the arguments listed in the component... So I would change the call to this...
myService.addEmp(TITLEa, emp_NAMEa, FTa, DOHa, DM_NAMEa, SVC_MGR_NAMEa);
Again make sure your query is correct...
<cfquery datasource="stcycle">
INSERT INTO dbo.payroll
(
TechCode, emp_NAME, FT, DOH, TITLE, DM_Name, SVC_MGR_NAME
)
VALUES
(
'#TechCode#', '#emp_Namea#','#FTa#','#DOHa#','#TITLEa#','#DM_Namea#','#SVC_MGR_NAMEa#'
)
</cfquery>
In your result handler responseHandler.onResult you are just setting a variable var msg = results;. If you want to see the results coming back from the remoting call perhaps you should use alert( String(results)); Also, is you are returning a string bypt from the component then you should thange the results:Object type to results:String.
In my components I use the following component tags
<cfcomponent name="item_info" access="public" description="">
I don't think that makes a difference but thought I would pass it along.
Make sure that your component is physically located within the web root of the web server. In this case it looks like you are using localhost so that would mean you are using your machine to develop on..? So therefore your, based on your connection.getService call you cfc's should be located <C>:/<webroot>/cfc/. Basically in the cfc directory off the webroot for your web server.
The power of remoting is the fact that you can update the database from flash forms without refreshing the page and it really makes your application significantly quicker and appear more like an application than a web page. I use it a lot and really like the way it makes the applications cleaner and quicker.
Hang in there... Once you get it you will dig it!
Hope this helps,
Ed
Rey
Ed
That is correct however in your call..
createGatewayConnection("http://localhost/flashservices/gateway/";);
you have localhost which should be
createGatewayConnection("http://www.stericycleweb.com/flashservices/gateway/";);
or actually even better:
createGatewayConnection("http://#cgi.HTTP_HOST#/flashservices/gateway/");
then the cf server will put in the host of the server. Make sure to wrap it in a cfoutput..:>
Hope this helps.
Ed
Any more questions email me at [email protected]...
Tom
Laura
See this post: http://www.asfusion.com/blog/entry/how-to-transfer-data-with-flash-remoting in the section: Structures and objects. I wrote another workaround in this comment too: http://www.asfusion.com/blog/entry/how-to-transfer-data-with-flash-remoting#comment-426
Basically, the idea is that if you send a sole structure, each key gets converted to an argument, so you are actually receiving as many arguments as your original object had. This would be similar to myFunction(argumentCollection=myStructure)
Court
Basically, in the root of the admin website... I have an application.cfc (C:\inetpub\wwwroot\admin\application.cfc).
On one of my pages I have a CFFORM using CFGRID and Flash Remoting to populate the grid. The cfform calles a cfc located at admin._model.cfc.cfformRemote (C:\inetpub\wwwroot\admin\_model\cfc\cfformRemote.cfc)
When it makes the call, it get the error. If I put the cfformRemote.cfc in the root of the website (
C:\inetpub\wwwroot\) I dont get any errors and the call to the cfc is successfull.
Help?!? Please :(
Laura
From what you show, the path seems to be ok as long as you use it in connection.getService(). What does the error say exactly? Could there be anything in the cfc that fails when it is moved?
Court
Court
Demetrius Pinder
Sowmya Nayak
The index.cfm file is under another website on the same machine. It does have CFIDE as a virtual directory. When I try to run the example, it gives me an error: Service com.asfusion.flashRemotingResponder not found.
But when I run the example under the web root, it works perfect without any problems. Any ideas to this problem?
Thanks.
Laura
See the second paragraph on "A couple of notes on Remoting" in the post. If you use something like: com.asfusion, then your folders from the webroot must match that (com/asfusion/) and have the component there.
Sowmya Nayak
Laura
What do you mean by "the index.cfm file is under another website on the same machine"?
michael white
Jason
Jason
Maggie
Mark
bind="{(data.selectedItem!=undefined)?data.selectedItem.location:''}"
I'm running this on localhost and using Access and Unicode. Could this be a problem??
Please, if anyone can help I would be very grateful.
Robert C
I had been banging my head against a wall trying to update a grid this way using a database query and was just utterly stumped.
When implementing this method first ran into the "Event Handler Exception" problem and then read and re-read all the comments and finally realized I was using onRequest in my Application.cfc for logging people off the site. So had to recode the site a little to fix that issue.
One I figured out it was onRequest everything just worked the way it was supposed to.
kll57
In the onchange for the master grid I'm trying to call the function that will get the datat from the component. I need to pass the key from the master grid to the function that makes the function call to the function in the component so the query will only pull the records associated with the key. I've read through most of the posts and still can't seem to figure this out.
The master grid is called userGrid and the child grid is userIdGrid.
The onChange event calls the following function:
getUserid(userGrid.selectedItem.SSN)
The getUserid function makes the call to the component: This is were I get really confused and know I'm not doing it right. I've tried various ways of doing this. This is what I currently have:
public function getUserid(grid:mx.controls.DataGrid):void
{
var userArgs:Objec t= {};
<cfoutput>
userArgs.ssn = userGrid.selectedItem.ssn;
</cfoutput>
_global.listingService.queryUserid(userArgs);
setMode('add');
mx.managers.CursorManager.removeBusyCursor();
}
listingService is the name of the service that I connect to - which is working for the master grid and all inserts, updates and deletes.
querUserid is the name of the function that makes the query to the child table and is in the same listingService.
I've set up another response Handler for this and it looks like this:
var userIdGrid:mx.controls.DataGrid = userIdGrid
responseHandler.useridResult = function( results:Object);Void
{userIdGrid.dataProvider = results.items;
setMode('add');
mx.managers.CursorManager.removeBusyCursor();
}
when I run the page and click on the master record I get the message The parameter SSN to funciton queryUserid is required but was not passed in.
This is all new to me so I'm sure I have plenty wrong with the code.
I would appreciate any help, this has been driving me crazy for days.
Thanks in advance for any help.
Kim
Ed
This may be scoping issue. When you call userGrid.selectedItem.ssn try using _root.userGrid.selectedItem.ssn. Depending on where your function is located sometimes flash forms looses scope. The one thing to consider here is that _root is kinda a hack and may not be compatible in future releases. You could scope the grid in a more global way. I believe Laura has addressed this in the original text of this post.
Hope this helps,
Ed
kll57
Thanks for the response. I did scope the grid in a global var - _global
but I didn't pass it that way to the function, I'll gave it a try and I
still got the same error. I think the way I passing it is not right or the
way I'm receiving it in my function is wrong. If you think of anything else
I'll give it a try.
Thanks,
Kim
kll57
The two grids are populated by 2 different queries that reside in the same CFC.
I first populate the Master grid (userGrid) then when a row is selected I pass the selected rows primary key to the function that calls the detail query in the cfc. This query selects only the records where the Master primary key = the foreign key in the detail table.
This is a sample of the code that is in the script tag that deals with the grid:
var responseHandler:Object = {};
var userGrid:mx.controls.DataGrid = userGrid; (this is the master grid)
var userIdGrid:mx.controls.DataGrid = userIdGrid; (this is the detail grid)
responseHandler.onResult = function ( results: Object):Void
{userGrid.dataProvider = results.item;
_root.setMode('add');
mx.managers.CursorManager.removeBusyCursor();
}
responseHandler.queryUserid_Result = function (results: Object):Void
{userIdGrid.dataProvider = results.item;
_root.setMode('add');
mx.managers.CursorManager.removeBusyCursor();
}
On form load calls the getData() that populates the Mastergrid using the master query in the CFC - this works.
the getData() looks like this:
public function getData():Void
{
var qArgs:Object {};
<cfoutput>
qArgs.status = '#session.status#';
</cfoutput>
_global.listingService.queryAll(qArgs);
_root.setMode('add');
mx.managers.CursorManager.removeBusyCursor();
}
The master grid makes the call to populate the second grid (getUserid() in the onchange event, the PKNO column is the primary key:
<cfgrid name="userGrid" ........ onchange="userGridChanged();getUserid(userGrid.selectedItem.PKNO)">
The getUserid () looks like this:
public function getUserid(pkno:String):Void
{
var userArgs:Object {};
<cfoutput>
userArgs.pkno = pkno;
</cfoutput>
_global.listingService.queryUserid(userArgs);
_root.setMode('add');
mx.managers.CursorManager.removeBusyCursor();
}
This function is populating the detail grid with the correct data. When I select a row from the master userGrid.
The right hand panel has textinput fields for the master record that are bound to the master grid- userGrid. Below these textinput fields I have the detail grid - userIdGrid that can contain 1 or more rows. I can only get one or the other to populate, not both.
Is there a problem with the resultHandlers each specifing the .dataprovider?
Any help would be greatly appreciated.
Thanks in advanced for any help,
Kim
Pp
Db
Ambika Dayal
I tried the tutorial to load data in the grid from an Access database and it worked great! However, when I try it loading it from an Oracle database - the grid appears as though it is loaded, but I am unable to see the data. I can tell that the grid seems loaded, because the scroll bar size changes.
All examples I have seen on the web are with Access databases. Is there a problem with Oracle? Has anyone had the same experience?
I would appreciate any help, suggestions, comments.
Thanks a lot
Ambika Dayal
Thanks anyway and keep up the great work!
chaita
I am new to ColdFusion flash remoting. I downloaded the files and copied in my sys. it’s not showing the date. When I am pressing GET DATE button its simply sitting there.
My system structure is ColdFusion software is in 'c' folder and the default web sites are in’d’ folder.
I had a doubt its really looking for cfc file are not I don't know. I remove the CFC file from that path even though it’s not throwing the error at all.
Appreciated for early response
Tim
Any ideas?