March 4th, 2008
I’ve struggled a bit to find out how to access a textarea (and select box) that was presented in a Flex AIR HTML component.
Wasn’t much work in the end, but here’s an example (by using babelfish’s translation page) of how to access multiple elements from Flex:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="1024" height="768">
-
<mx:Script>
<![CDATA[
/**
* This example describes how to access HTML elements from Flex AIR AS3.
* It makes use of the babelfish translation website to access the translation elements
* and then submit the specified translation to babelfish.
*
* @Author: S.Radovanovic
* @Url: http://www.saskovic.com/blog/?p=7
* @Date: 05-03-2008
*/
-
import mx.controls.Alert;
-
//Our access to the HTML Dom
private var domWindow:Object;
private var blnAlertThrown:Boolean = false;
-
/**
* Find the corresponding element and be able to access it from Flex
*
*/
private function initDomWindow(event:Event):void {
//Retrieve a link to the textarea
domWindow = event.currentTarget.domWindow;
-
//Set a trigger (if not done yet)
if( !blnAlertThrown ) {
Alert.show("Click ok to set access HTML elements from Flex", "Access HTML elements", Alert.OK, this, setTranslationValues);
blnAlertThrown = true; //Make sure we don't loop
}
}
-
/**
* Retrieve a reference to a specific HTML element specified by name
*/
private function getElementFromHTML(elementName:String):Object {
var arrayContainingAllFoundElements:Object = domWindow.document.getElementsByName(elementName);
-
//We could do some checks here to see if anything was found, but I leave that up to the you...
-
//Always return the first element (there also should only be one)
return arrayContainingAllFoundElements[0];
}
-
/**
* Set the elements in the webpage to your likings.
*/
private function setTranslationValues(event:Event):void {
//Get access to the translation text area and pre-fill it
var translationTextArea:Object = getElementFromHTML("trtext");
translationTextArea.value = "Set my own values from Flex!";
-
//Loop through the possible language options of the selectbox and set the one we want (in this case english => dutch)
var languageSelectbox:Object = getElementFromHTML("lp");
for( var i:int = 0; i < languageSelectbox.options.length; i++ ) {
trace(i + ' - ' + languageSelectbox.options[i].value);
if( languageSelectbox.options[i].value == "en_nl" ) {
languageSelectbox.selectedIndex = i;
}
}
-
Alert.show("Submit the values for translation by babelfish", "Translate", Alert.OK, this, submitTranslation);
}
-
/**
* Hit submit!
*/
public function submitTranslation(event:Event):void {
//And finally hit translate!
var submitButton:Object = getElementFromHTML("btnTrTxt");
submitButton.click();
-
}
]]>
</mx:Script>
-
<mx:HTML id="htmlTranslate" x="10" y="84" location="http://babelfish.altavista.com/" complete="initDomWindow(event)"/>
-
</mx:WindowedApplication>
- Download this code: accesshtmlcomponentsfromflex.txt
Download code
Posted in AS3, Flex, Flex 3 | 3 Comments »
November 24th, 2007
I’ve been waiting for a release of Flex (AIR) where system tray (systray) options where available and finally with the latest release of Adobe AIR it’s there.
After searching some while on the internet I’ve found my way of minimizing my AIR application to the system tray, including a little menu.
Important to understand is that I wanted a minimize solution for a WindowedApplication. The WindowApplication offers it’s own minimize, maximize and close buttons, so these actions have to be caught if we want to attach our own actions to them.
Flex offers you docking, so that your application can be minimized, this is available for Windows and Mac platforms. The example presented here is for Windows, but close to what it should be for Macs.
I’ve created an Systray test application which contains the basic code, necessary for docking and undocking your application from the systray. The only part you will not need is the dummy label…
To test this you can:
1. create a new Flex project (application type AIR) called Systray.
2. edit Systray-app.mxml and set SystemChrome to none (so that you get the cool app skin
).
2. copy the contents of the presented code into the Systray.mxml.
After testing it (and also without
), you should be able to place the code into your own project and use it.
Here’s the code:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApplication()">
<mx:Script>
<![CDATA[
/**
* This example describes how to dock an AIR application to the system tray
* and then undock it again.
* The minimize and close actions of the WindowedApplication are caught, so
* that we can introduce our own actions.
*
* A simple systray menu is presented, to show the usage of that.
*
* @Author: S.Radovanovic
* @Url: http://www.saskovic.com/blog/?p=5
* @Date: 24-11-2007
* @Author: Jeffry Houser
* @Date: 09-01-2007
* Updated for AIR Beta 3
*/
-
import mx.controls.Alert;
import mx.events.CloseEvent;
-
private var dockImage:BitmapData;
-
/**
* Initialize the application to the default values.
* This method is called upon creationComplete from the Windowed Application
*
* @Author: S.Radovanovic
*/
public function initApplication():void {
-
//Use the loader object to load an image, which will be used for the systray //After the image has been loaded into the object, we can prepare the application //for docking to the system tray
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, prepareForSystray);
loader.load(new URLRequest("http://www.saskovic.com/images/systray_icon_16.png"));
-
//Catch the closing event so that the user can decide if it wants to dock or really //close the application
this.addEventListener(Event.CLOSING, closingApplication);
}
-
/**
* Check if the user wants to close the application or dock it
*
* @Author: S.Radovanovic
*/
private function closingApplication(evt:Event):void {
//Don't close, so prevent the event from happening
evt.preventDefault();
-
//Check what the user really want's to do //Alert.buttonWidth = 110;
Alert.yesLabel = "Close";
Alert.noLabel = "Minimize";
Alert.show("Close or minimize?", "Close?", 3, this, alertCloseHandler);
}
-
// Event handler function for displaying the selected Alert button.
private function alertCloseHandler(event:CloseEvent):void {
if (event.detail==Alert.YES) {
closeApp(event);
} else {
dock();
}
}
-
-
/**
* Check to see if the application may be docked and set basic properties
*
* @Author: S.Radovanovic
*/
-
public function prepareForSystray(event:Event):void {
-
//Retrieve the image being used as the systray icon
dockImage = event.target.content.bitmapData;
-
//For windows systems we can set the systray props //(there's also an implementation for mac's, it's similar and you can find it on the net...
)
if (NativeApplication.supportsSystemTrayIcon){
setSystemTrayProperties();
-
//Set some systray menu options, so that the user can right-click and access functionality //without needing to open the application
SystemTrayIcon(NativeApplication.nativeApplication .icon).menu = createSystrayRootMenu();
}
}
-
/**
* Create a menu that can be accessed from the systray
*
* @Author: S.Radovanovic
*/
private function createSystrayRootMenu():NativeMenu{
//Add the menuitems with the corresponding actions
var menu:NativeMenu = new NativeMenu();
var openNativeMenuItem:NativeMenuItem = new NativeMenuItem("Open");
var exitNativeMenuItem:NativeMenuItem = new NativeMenuItem("Exit");
-
//What should happen when the user clicks on something...
-
openNativeMenuItem.addEventListener(Event.SELECT, undock);
-
exitNativeMenuItem.addEventListener(Event.SELECT, closeApp);
-
//Add the menuitems to the menu
menu.addItem(openNativeMenuItem);
menu.addItem(new NativeMenuItem("",true));
//separator
menu.addItem(exitNativeMenuItem);
-
return menu;
}
-
/**
* To be able to dock and undock we need to set some eventlisteners
*
* @Author: S.Radovanovic
*/
private function setSystemTrayProperties():void{
//Text to show when hovering of the docked application icon
SystemTrayIcon(NativeApplication.nativeApplication .icon).tooltip = "Systray test application";
-
//We want to be able to open the application after it has been docked
SystemTrayIcon(NativeApplication.nativeApplication .icon).addEventListener(MouseEvent.CLICK, undock);
-
//Listen to the display state changing of the window, so that we can catch the minimize
stage.nativeWindow.addEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, nwMinimized); //Catch the minimize event
}
-
/**
* Do the appropriate actions after the windows display state has changed.
* E.g. dock when the user clicks on minize
*
* @Author: S.Radovanovic
*/
private function nwMinimized(displayStateEvent:NativeWindowDisplayStateEvent):void {
-
//Do we have an minimize action? //The afterDisplayState hasn't happened yet, but only describes the state the window will go to, //so we can prevent it!
if(displayStateEvent.afterDisplayState == NativeWindowDisplayState.MINIMIZED) {
//Prevent the windowedapplication minimize action from happening and implement our own minimize //The reason the windowedapplication minimize action is caught, is that if active we're not able to //undock the application back neatly. The application doesn't become visible directly, but only after clicking //on the taskbars application link. (Not sure yet what happens exactly with standard minimize)
displayStateEvent.preventDefault();
-
//Dock (our own minimize)
dock();
}
}
-
/**
* Do our own 'minimize' by docking the application to the systray (showing the application icon in the systray)
*
* @Author: S.Radovanovic
*/
public function dock():void {
//Hide the applcation
stage.nativeWindow.visible = false;
-
//Setting the bitmaps array will show the application icon in the systray
NativeApplication.nativeApplication .icon.bitmaps = [dockImage];
}
-
/**
* Show the application again and remove the application icon from the systray
*
* @Author: S.Radovanovic
*/
public function undock(evt:Event):void {
//After setting the window to visible, make sure that the application is ordered to the front, //else we'll still need to click on the application on the taskbar to make it visible
stage.nativeWindow.visible = true;
stage.nativeWindow.orderToFront();
-
//Clearing the bitmaps array also clears the applcation icon from the systray
NativeApplication.nativeApplication .icon.bitmaps = [];
}
-
-
/**
* Close the application
*
* @Author: S.Radovanovic
*/
private function closeApp(evt:Event):void {
stage.nativeWindow.close();
}
]]>
</mx:Script>
-
</mx:WindowedApplication>
- Download this code: Systray.txt
Download code
Tips on shortening some code or something else are always welcome.
Thanks for Jeffry Houser for updating it for Flex 3 (beta 3).
Posted in AS3, Flex, Flex 3 | 40 Comments »
March 7th, 2007
I recently came across the problem of exporting Datagrid data to an Excel sheet.
Research on the internet brought me to a post on cflex where an solution was presented for Flex < 2.
Together with a (half-visual) comment posted there I refactored the code so that it would be applicable to Flex 2 (And didn’t need to work through the clipboard, since in my opinion this would work only half the time (browser security)).
The following Actionscript code is used for converting the Datagrid to an Excel file and then passing it on to an external Excel exporter:
Download code
The code to export the data to Excel is fairly simple.
I’ve written it in PHP, but it can be written in any language.
<?php
/**
* Export data, delivered in the POST, to excel.
*
* @author S.Radovanovic
* @version $Id$
*/
header('ETag: etagforie7download'); //IE7 requires this header
header('Content-type: application/octet_stream');
header('Content-disposition: attachment; filename="rapportage.xls"');
-
//Add html tags, so that excel can interpret it
echo "<html>
<body>
".stripslashes($_POST["htmltable"])."
</body>
</html>
";
?>
- Download this code: exportexcel.txt
Download code
Posted in AS3, Flex 2 | 60 Comments »