Keep updated with crazedCoders news and events

Edmonton Events...

Find out about all upcoming events in the city

read full article »

CO-OP Team...

Available for free in the Adobe Marketplace

read full article »

Harvest is ready

Harvest is now available for your iPhone!

read full article »

Harvest - by...

Coming soon to the iTunes AppStore

read full article »

Pik Pik Pik

More Revenge in the iTunes AppStore.

read full article »

Social Web Meetup

February's Social Web Meetup will be held at our office again.

read full article »
View All
crazedCoders adobe solution partner

Vic on Flex


Entries 2125 out of 255, 10, or 20 per page

« Previous   1   2   3   4   5   Next »



Wednesday - April 25, 2007
SizeableTitleWindow & Custom Skins



Most of you are probably familiar with the SizeableTitleWindow.as that the CF code generator for Flexbuilder spits out, along with a plethora of other useful tidbits of code. In fact that was the only reason I initially installed Coldfusion and the tools - I saw a modal resizable window in Flex and absolutely had to have it!

That was like 8 months ago. Recently I started working a lot more closely with skinning and runtime loading of css. I created some really funky UI's using run time style sheets that I found at http://www.scalenine.com, in particular I like using the Obsidian Theme Skin. However, this skin, like many others, replaces the skins for the Panel control - which, though very cool, breaks the resize function of the SizeableTitleWindow.

In simple terms, an event listener attached to the MouseOver event checks the coordinates of the mouse and if the coordinates fall within the right range, a cursor image is assigned. When the user clicks the mouse, the mouse down event checks which cursor is active and acts accordingly. The only problem is that all the coordinate calculations are based on event.localX and event.localY and those relate to event.target. However when using skins, the event.target isn't the SizeableTitleWindow but rather the skin, so it throws everything off. The result? The east and south cursors don't appear and even when they do, the drag functionality is buggy at best.

I fixed the problem by replacing all localX and localY with event.currentTarget.mouseX and event.currentTarget.mouseY. Also I no longer check to see if event.target is SizeableTitleWindow, and that seems to have fixed it.

You can find this code in action here and the source here. Enjoy.

Posted by Vic Rubba at 5:26 PM Comments

Friday - April 20, 2007
Flex Modules, Compile and Run Time CSS



I've recently become involved in building a very module based Flex app, where the question of css and css inheritance came up, particularly with respect to how Flex handles run time loading of style sheets when they are loaded within not only the shell application but also the therein loaded modules.

Essentially, there are 3 rules that prevail:

  1. The most recent style to be loaded always wins.
  2. Run time overrides compile time styles
  3. StyleManager is a global Manager
  4. Style inheritance is granular to the attribute level
  5. Compile time css will only compile styles found in Application
Let me explain further, and to do so I'm just going to use our trusty <mx:Button>

The most recent style loaded always wins
Say you load a runtime style sheet with the following:

Button {
fillColors: #ff0000, #ff0000, #ffffff, #eeeeee; /*red */
letterSpacing:3;
}

Then in a (rather large) module you load another runtime style sheet with this:
Button {
fillColors: #006600, #009900, #ffffff, #eeeeee; /*green*/
letterSpacing:1;
}

You'll notice that the first color style is applied right away, to any buttons in the shell application. However, when the second module finishes loading, all Buttons will change from Green to Red, and spacing will be reduced to 1. To make it even more interesting, you could add an additional module of roughly the same size as the first and have it load its own style sheet. Then the end result is pretty much random, whichever module takes the longest to load wins, the shell run time style never to be heard from again.


Run time overrides compile time styles
In your shell application you add the following:
<style>
Button{
fillColors: #9900ff, #9900ff, #ffffff, #eeeeee;
letterSpacing:1;
}
</style>

Once your app loads the run time css, this will be overwritten. Now if you have a huge run time css swf with massive fonts or images embedded in, there's a chance you might even see your original color first and then have it overwritten later. This can cause for some funky effects in your app, in which case you might want to attach an eventListener to StyleEvent.COMPLETE, and hide your interface until that event has triggered using a ViewState or the like.

StyleManager is a global Manager
It that does not distinguish between <Applications> and <Modules>. Say you create a custom style class called .myDogAteMyHomeworkButton for Buttons in your module. You then place a corresponding style entry in your compile time or run time styles for this module. Now someone else happens, just happens to use the same exact style class in their module. Or the shell application developers happens to do so. Well again, the last one loaded wins. Your custom style class is never safe. But then again neither are their's. The best thing you can do is be very very unique in your style class naming conventions, and hope for the best.

Style inheritance is granular to the attribute level
Getting back to our original example, you'll notice the style attribute letterSpacing was defined explicitly in both style sheets. Because inheritance is on the attribute level, if you do not specify an attribute in say your run time style sheet for your application, then that attribute can be set in compile time style tags and it will override the default values. What's the lesson to be learned here? If you want to make sure that your runtime css has the final word, then get detailed and explicitly list every style attribute and its value, even if the default will suffice.

Compile time css will only compile styles found in Application
Ever seen this warning "The type selector 'HDividedBox' was not processed, because the type was not used in the application."? Until the dawn of Modules, this was a message I generally ignored. Made sense to me, if I didn't have an HDividedBox anywhere in my application, why include the style? But what would happen to modules that perhaps do use the HDividedBox control but rely solely on the shell application styles for their look and feel? The application doesn't know at runtime that one or more of its modules will need this style defined, so therefore it just ignores it. End result, your HDividedBox in your module will not be styled properly. The solution? Use run time stylesheets. (and that's how this all began!)

Posted by Vic Rubba at 7:19 PM Comments

Tuesday - April 10, 2007
A closer Look at IFrames and ExternalInterface in Flex



Well I've been super busy as usual, working on some pretty cool stuff, still managing to only put food on the table but also sticking to my guns and doing only Flex projects. Of course, my blogging has suffered dearly.

In one of my current projects, I am faced with the challenge of somehow embedding IFrames inside my flex app, however without having any control over the html wrapper that my Flex app will sit in. Sure I could 'advise' users on adding the appropriate javascript functions and the hidden div element at the bottom of the body, as we've seen in other Flex Iframe examples out there. But I figured there had to be a way to do this without needing to rely on this external dependency.

As it turns out I can do inline Javascript function calls within my ExternalInterface.call, an example of this would be:

ExternalInterface.call("function(){return window.location.href;}");
which is a simple little function to quickly get the address of the current page. Another handy example is this one:

ExternalInterface.call("function(){document.location.href=document.location;}");
This is a quick way for a user to 'logout' of the flex application, it simply reloads the web page. So as you can see, we can do a great deal without ever needing to touch the html wrapper. So why not do the same thing with Iframe support? Here's what I came up with:
ExternalInterface.call("function(){" +
"var tempIFrame=document.createElement('div');" +
"tempIFrame.setAttribute('id','vyFrame');" +
"tempIFrame.style.position='absolute';" +
"document.body.appendChild(tempIFrame);" +
"tempIFrame.style.backgroundColor='transparent';" +
"tempIFrame.style.border=0;" +
"tempIFrame.style.visibility='hidden';}");
I am going to try and create a div element in memory and append it to the DOM. It's best to run this code during the application preinitialize() event. However, before I move on to explain the rest I just want to mention that I did run into some issues here with IE6. As you'll notice I appendChild and then I set the styles. Turns out that if I manipulate a new element too much prior to adding it to the DOM, it just gets all flaky and will not work. Believe me, this was not an easy bug to track down!

Now, we need to change the remaining externalInterface calls as well... things like move, hide, show and source. Building on the example at deitte.com that first got me started ages ago, I changed all the calls as they are found in his IFrame.mxml component:

ExternalInterface.call("moveIFrame",globalPt.x ,
globalPt.y, this.width, this.height);
Becomes:
ExternalInterface.call("function(){" +
"var frameRef=document.getElementById('vyFrame');" +
"frameRef.style.left=" + globalPt.x + ";"+
"frameRef.style.top=" + globalPt.y + ";" +
"var iFrameRef=document.getElementById('vyIFrame');" +
"iFrameRef.width=" + this.width + ";" +
"iFrameRef.height=" + this.height + ";}");
ExternalInterface.call("loadIFrame", source);
Becomes:
ExternalInterface.call("function(){vyFrame.innerHTML='" +
"<iframe id=\"vyIFrame\" src=\"" + source +
"\" frameborder=\"0\"></iframe>';}");
ExternalInterface.call("showIFrame");
Becomes:
ExternalInterface.call("function(){" +
"document.getElementById('vyFrame').style.visibility='visible';}");
ExternalInterface.call("hideIFrame");
Becomes:
ExternalInterface.call("function(){" +
"document.getElementById('vyFrame').style.visibility='hidden';}");

After a bit of testing I did manage to get this to work, sort of. I ended up spending some time playing with the compiler options in Flexbuilder. I found that if I turned off history management, my Iframes wouldn't appear. However removing the script reference to history.js seemed to have no real effect. For those of you that are not Flash-savvy :) it turned out that the only things to really watch out for, and again I am at the mercy of the users who embed my flex app into their html pages, is that the AC_FL_RunContent() has a final parameter setting of "wmode", "opaque" and the object embed tag also contains wmode="opaque". If this setting is not there or set incorrectly the Iframe will appear behind your flash player.

Posted by Vic Rubba at 1:32 AM Comments

Thursday - February 15, 2007
Export Data from Flex App using Coldfusion



It's been a while since I blogged, just so amazingly busy these days that I barely have time to breathe, let alone blog. I'm currently up to my neck in building a flex app that uses Coldfusion 7.02 and DB2 v8/9 on the back end. I've never used Coldfusion before so it's been one hell of a time. I managed to figure something out today that I think is definitely worth sharing. In the app I was required to find a way for users to 'export' or 'save' their work to their drive, in a format they could easily open directly. That eliminated shared objects and I wasn't allowed to use a third party tool like swfStudio to build a helper app and use Localconnection to get the job done (can't wait for Apollo!)

I don't have much time so I'm going to just paste code and explain a bit.

Step 1. Enable session management in the CF app. Create an Application.cfm file in the root of your CF application, put this in it:

<CFAPPLICATION NAME="Name" SESSIONMANAGEMENT="Yes">
Step 2. Create a CFC that takes whatever data you wish to save and sticks it in a session variable, return a boolean to let Flex now this worked(Export.cfc):
<cfcomponent>
<cffunction name="toXml" access="remote" returntype="boolean" output="true">
<cfargument name="data" type="string" required="yes" default="" />
<cfset session.exportData = #arguments.data#>
<cflog text="data to be exported: #session.exportData#"/>
<cfreturn true>
</cffunction>
</cfcomponent>
Step 3. Create a CFM file in the application root that will grab the session variable and output it to http, while flagging it as an attachment (this causes nice save as popup to appear). In my example I'm creating an xml file and I ran into issues with whitespace, hence the cfsetting.. this fixed the problem for me (getFile.cfm)
<cfsetting enablecfoutputonly="true" showdebugoutput="No">
<cfheader name="Content-Disposition"
value="attachment; filename=export.xml"/>
<cfcontent type="xml/text" reset="true"/>
<cfscript>
WriteOutput(session.exportData);
</cfscript>
<cfexit />
Step 4. In flex declare the remote object that will call the cfc:
 <mx:RemoteObject 
id="exportManager"
destination="ColdFusion"
source="com.sample.utils.Export"
showBusyCursor="true">
<mx:method name="toXml" result="login_result(event)" fault="serverFault(event)" />
</mx:RemoteObject>
Step 5. Add your code to call it and handle the result. The result, on success, will make an httpservice call to the CFM you created:
private function test():void{
exportManager.toXml("" +
"" +
"The application has successfully exported this file" +
"Eventually the actual data will be passed into this function" +
"
");
}
private function login_result(event:ResultEvent):void{
if(event.result == "true"){
var request:URLRequest = new URLRequest("getFile.cfm");
flash.net.navigateToURL(request, "_self");
}
}
Conclusion. Basically that's it. I had issues with the session not persisting from setting the variable to getting it, but adding the application.cfm fixed that. I can now push any xml data to the browser for saving. There's lots of other possibilities here as well, such as exporting to Excel or Word, but there's other articles out there that you can google which explain how to do those specific tasks in Coldfusion. Hope this helps!

Posted by Vic Rubba at 4:15 PM Comments

Sunday - December 31, 2006
Setting up Db2 v9 as a Coldfusion Datasource



In the last few weeks I've had the opportunity to get to know Coldfusion just a little bit better. One of the first challenges I faced is getting CF talking to Db2, so I could take advantage of the CF Extensions for Flexbuilder and that funky Wizard. To be precise I used ColdFusion MX 7.02 and DB2 Community Express Edition v9.1

This doesn't just apply to Flex, but maybe others might find this useful. Keep in mind I have only tested this in Windows:

  1. Install the db2 client or get access to a machine that does. I installed db2 in the default folder on my dev machine to get this working.
  2. Copy C:\Program Files\IBM\SQLLIB\java\db2java.zip to C:\CFusionMX7\lib. Important: Make sure db2jdbc.dll is in the path somewhere or copy it to same folder!
  3. Restart Coldfusion MX. Login to CF Admin. Go to Datasources.
  4. Add new Datasource:
  • driver type Other
  • CF DataSource Name: [sourcename]
  • JDBC url: jdbc:db2:[dbname]
  • Driver Class: COM.ibm.db2.jdbc.app.DB2Driver
  • Driver Name: DB2Driver
  • username: [name]
  • password: [password]
  • [Submit]
Couple things to note. Out of the blue the other day suddenly I started getting this db2jdbc not found in java path error... I figure something I installed hooped my system path. Instead of messing around with why, I figured out that just copying the dll into my CF lib folder fixed the problem. The ...app.DB2Driver is specific to Windows OS I believe. The username and password are usually a Windows account... probably best to use the account that has admin rights to db2 at least until you get it working.

I also did spend a good chunk of time trying to get the built in driver to talk to db2... I personally had no luck whatsoever, and I have read in other places that the drivers generally are only backwards compatible... the driver that ships with CF is definitely not v9, I think it might be v7... not sure though. I did test the backward compatibility claim by using the v9.1 jdbc driver against a db2 v8.x datasource and it worked fine.

Posted by Vic Rubba at 3:02 AM Comments

« Previous   1   2   3   4   5   Next »


Entries 2125 out of 255, 10, or 20 per page