I have been too busy to blog over the past couple months and this is more of a note than a blog entry. I have come across a few applications in the past 6 months that had your standard CRUD forms.
The problem is that most of them used HBOX and VBOX in attempt to align Labels and TextInput items. ACKKK! These can significantly increase the size of your swf after compile in Flex Builder. For form layout you can almost always use mx:Form. The feature set behind this tag is very intuitive as well.
I've seen developers write code to handle key press of the enter key in an effort to trigger the firing of a default button on the form. This is incorporated in the mx:Form tag also; you just point to the button via the defaultButton property. The default button will fire when you click enter key on text input items.
I have attached a simple example of mx:Form with a default button displaying an alert. Hope this helps and check out the language reference for more info as I didn't touch on all features: mx:Form
Recently Andy Powell won a WII for his submission into the 360 Flex | API Contest.
His winning application is a great example of leveraging multiple APIs that at first glance, one may be challenged in connecting the dots with regard to how they could be integrated into a single intuitive application. When I first looked at Andy's initial layout and functionality as intuitive as it was, I got stoked because I could see that this application could be enhanced visually and functionally; so I am blogging about the enhancements I made to that effect.
First, I had some .css in mind to give it that Ribbit Green theme. I adjusted the layout of the various nested canvases and converted them to use a form which allows for formitem conciseness with regard to alignment etc and allots for a default button (integrated form 'enter key' functionality).
I sized down the respective API images into the main panels control bar (will be applying links shortly) and enhanced the map functionality which allows for a unique icon (hotel) to identify the selected hotel from other hotel POIs on the map. Each time a search is performed the past icon is returned to its initial state and the newly selected hotel gets the new icon (member variables used to allow for this). I will be styling the MapQuest info windows that pop up with selection of a POI shortly as the very customizable MapQuest API is 100% extensible.
I then relocated the RIBBIT dial up interface and adjusted dialing status to persist in the connection labeling area rather than separately at the bottom of the form to save real estate. Lastly, I wrapped it in a panel with the hotel details form and nested it within a panel along with the MapQuest tilemap component. This panel will soon be a slide in that will open/close via grid selection and panel close feature. Please check out the new app on Andy's site here; Ribbit, Kayak, MapQuest Mashup and book your hotel today 8-).
FYI, souce code is located at Andy's Google code site here:
AP's GCode site
A few weeks back a fellow UM-er asked if there had been a look ahead combo created at some point and possibly checked into our library.
To my knowledge such a component didn't exist except for a few components running around that didn't exactly do what he was looking for. So I spent some time extending combo box to create the functionality he was looking for.
This component allows a user to hot key filter the combos list/data provider which means, when the combo box gains focus it becomes editable allowing key entry to filter the list items based on the keys pressed.
It is quite slick and is written entirely as a single class extending ComboBox. Feel free to enhance, chop, criticize... It's yours to use how you wish and I hope it assists you in your efforts. Enjoy!
I would like to thank Adam Flater for adding case sensitivity option and label filtering.
Check out his blog: Here
********* UPDATE: 6/26/2008 ************
Resolved focus issues. Enabled view source (right click on the swf).
public class SmartCombo extends ComboBox
{
private var _trackText:String = "";
private var _caseSensitiveSearching : Boolean = true;
public function SmartCombo()
{ //TODO: implement function
super();
}
public function set caseSensitiveSearching (bool : Boolean) : void {
_caseSensitiveSearching = bool;
}
public function get caseSensitiveSearching () : Boolean {
return _caseSensitiveSearching;
}
override protected function textInput_changeHandler(event:Event):void {
_trackText = this.textInput.text;
// variables used in the loop
var label : String = null;
var matchingIdx : int = 0;
var foundMatch : Boolean = false;
var searchString : String = this.textInput.text;
if ( caseSensitiveSearching == false ) searchString = searchString.toLowerCase();
// using a for each loop on dataProvider does not strongly // couple to it only being an ArrayCollection... simlar // with weak typing on the items in the set
for each ( var item : Object in this.dataProvider )
{ // using itemToLabel() checks a few things like // if the item is a String, or it there's a // labelFunction being used
label = this.itemToLabel( item );
// if searching should not be case sensitive // do a toLowerCase() on label
if ( this.caseSensitiveSearching == false )
{
label = label.toLowerCase();
}
// find the first item that starts with searchString // if there's a match, break out of the loop
if ( label.substr( 0, searchString.length ) == searchString )
{
this.dropdown.selectedIndex = matchingIdx;
this.dropdown.scrollToIndex( matchingIdx );
foundMatch = true
break;
}
matchingIdx++;
}
// if there was no match found set selectedIndex to -1 // (unselect the list)
if ( foundMatch == false )
{
this.dropdown.selectedIndex = -1;
}
}
override public function close(trigger:Event=null):void{
super.close(trigger);
if (this.text == "")
{
this.selectedIndex = 0;
}
this.editable = false;
}
I was recently working with item renderers on a project and wanted to post an example of using an ActionScript (class) based item renderer and compare it with an MXML version.
It is nice to have the option to choose either, but I like the control an ActionScript class gives the coder and it tends to yield a more lightweight approach than MXML.
My first code block below is the AS class approach. The renderer simply applies a currency format to a field of numbers in a data grid. The second is utilizing the MXML approach. As you can see they yield the same results.
Notice how both approaches override the data setter for the label class they extend. Also see how how listData is utilized to associate the drop-in item renderer with the data from the list control.
With this rather basic example you can see how any control can be displayed via MXML or ActionScript and drawn out i.e. rendered in a list based class.
I have attached a zipped project that displays 2 grids using both renderers. I hope this helps you better understand the power of item renders and what you can do with them.
********* UPDATE: ************
I forgot to mention in this blog that a custom label could be applied via the DataGridColumn labelFunction to get the same effect in assigning a currency symbol.
// this function is call via the DataGridColumn labelFunction // and it utilizes the CurrencyFormatter below
private function currencyLabelFunction(item:Object, column:DataGridColumn):String {
return cf.format(item["Cost"]);
}
]]> </mx:Script>
<mx:CurrencyFormatter id="cf" precision="2"/>
<mx:Panel title="Label Function Example" layout="horizontal">