how to develop 2 level horizontal menu in flex3? - apache-flex

How can I develop a 2 level horizontal menu in flex 3? I want a sub menu to appear when you mouse over the 1st level.

The Menu control has this functionality built in. Here's Adobe's online documentation with some examples for you to check out.
Example:
<?xml version="1.0"?>
<!-- menus/SimpleMenuControl.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >
<mx:Script>
<![CDATA[
// Import the Menu control.
import mx.controls.Menu;
// Create and display the Menu control.
private function createAndShow():void {
var myMenu:Menu = Menu.createMenu(null, myMenuData, false);
myMenu.labelField="#label";
myMenu.show(10, 10);
}
]]>
</mx:Script>
<!-- Define the menu data. -->
<mx:XML format="e4x" id="myMenuData">
<root>
<menuitem label="MenuItem A" >
<menuitem label="SubMenuItem A-1" enabled="false"/>
<menuitem label="SubMenuItem A-2"/>
</menuitem>
<menuitem label="MenuItem B" type="check" toggled="true"/>
<menuitem label="MenuItem C" type="check" toggled="false"/>
<menuitem type="separator"/>
<menuitem label="MenuItem D" >
<menuitem label="SubMenuItem D-1" type="radio"
groupName="one"/>
<menuitem label="SubMenuItem D-2" type="radio"
groupName="one" toggled="true"/>
<menuitem label="SubMenuItem D-3" type="radio"
groupName="one"/>
</menuitem>
</root>
</mx:XML>
<mx:VBox>
<!-- Define a Button control to open the menu -->
<mx:Button id="myButton"
label="Open Menu"
click="createAndShow();"/>
</mx:VBox>
</mx:Application>

Related

Flex: menu items not being displayed

This is my code, the expected menu would show grandparent > parent > child.
However, the 'parent' item is not being displayed, instead, it shows 'child' directly under 'grandparent'.
<mx:Script>
<![CDATA[
// Import the Menu control.
import mx.controls.Menu;
// Create and display the Menu control.
private function createAndShow():void {
var myMenu:Menu = Menu.createMenu(null, myMenuData, false);
myMenu.labelField="#label";
myMenu.show(10, 10);
}
]]>
</mx:Script>
<!-- Define the menu data. -->
<mx:XML format="e4x" id="myMenuData">
<root>
<menuitem label="grandparent">
<menuitem label="parent">
<menuitem label="child"/>
</menuitem>
</menuitem>
</root>
</mx:XML>
<mx:VBox>
<!-- Define a Button control to open the menu -->
<mx:Button id="myButton"
label="Open Menu"
click="createAndShow();"/>
</mx:VBox>
The funny thing is, when I add a second parent, it does show the menu correctly.
Can anyone explain what is going on here and how I can solve this?
I took your code, threw it in a project of my own and got the same results you did. I then added another parent to your XML and everything works fine. I am guessing that if you only have one parent node there really isnt a need need to show it so it skips to the child.
Added second parent below:
<root>
<menuitem label="grandparent">
<menuitem label="parent1">
<menuitem label="child"/>
</menuitem>
<menuitem label="parent2">
<menuitem label="child"/>
</menuitem>
</menuitem>
</root>
Try some thing like below: -
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<fx:XML id="myMenuData" >
<menuitem label="grandparent">
<menuitem label="Uparent">
<menuitem label="child"/>
</menuitem>
</menuitem>
</fx:XML>
</fx:Declarations>
<fx:Script>
<![CDATA[
// Import the Menu control.
import mx.controls.Menu;
// Create and display the Menu control.
private function createAndShow():void {
var myMenu:Menu = Menu.createMenu(null, myMenuData, true);
myMenu.labelField="#label";
myMenu.show(10, 10);
}
]]>
</fx:Script>
<!-- Define the menu data. -->
<mx:VBox>
<!-- Define a Button control to open the menu -->
<mx:Button id="myButton"
label="Open Menu"
click="createAndShow();"/>
</mx:VBox>
</s:Application>

How can I stop a FlexNativeMenu with keyEquivalents from stealing my keystrokes?

I have a native menu item with a shortcut for a simple letter like "F".
<s:menu>
<mx:FlexNativeMenu id="mainMenu"
dataProvider="{menuData}"
labelField="#label"
keyEquivalentField="#keyEquivalent"
showRoot="false" />
</s:menu>
<fx:Declarations>
<fx:XML format="e4x" id="menuData">
<root>
<menuitem label="Edit">
<menuitem label="Frame Selection" keyEquivalent="f"/>
</menuitem>
</root>
</fx:XML>
</fx:Declarations>
This works great, but when I try to type text in any textfield or textInput
anywhere in the app, I cant ever type f.
How can stop the menu from stealing my keyboard input ?
Perhaps a better pattern to menu accelerators would use the control key, such as CTRL+F in your example.
Your menuitem would therefore include controlKey="true"
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<s:menu>
<mx:FlexNativeMenu id="mainMenu"
dataProvider="{menuData}"
labelField="#label"
keyEquivalentField="#keyEquivalent"
showRoot="false" />
</s:menu>
<fx:Declarations>
<fx:XML format="e4x"
id="menuData">
<root>
<menuitem label="Edit">
<menuitem label="Frame Selection"
keyEquivalent="f"
controlKey="true" />
</menuitem>
</root>
</fx:XML>
</fx:Declarations>
<s:TextInput />
</s:WindowedApplication>

How to listen to a custom event dispatched by a renderer in Flex?

I'm having the following problem: I've implemented a custom headRenderer for my DataGridColumn. The idea is to have a dropdown menu when clicked on the column header. The problem is I don't know how to add a listener or pass a variable to the renderer since the renderer class is instantiated by the ClassFactory.
The renderer class:
<?xml version="1.0"?>
<!-- itemRenderers\dataGrid\myComponents\RendererDGHeader.mxml -->
<mx:HBox xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:fx="http://ns.adobe.com/mxml/2009"
width = "100%"
>
<fx:Script>
// ...
// Event handler for the Menu control's change event.
private function menuHandler(evt:MenuEvent):void {
//Alert.show("Label: " + evt.item.#label, "Clicked menu item");
if (evt.item.#eventName == "typeLat"){
typeIcon.load("assets/type_location.jpg");
evt.item.toggled=true;
//variable.setColumnType(myLabel.text, "type"); // how can I pass "variable" to this renderer?
} else if (evt.item.#eventName == "typeLng"){
typeIcon.load("assets/type_location.jpg");
evt.item.toggled=true;
} else if (evt.item.#eventName == "typeTime"){
typeIcon.load("assets/type_time.png");
evt.item.toggled=true;
}
else if (evt.item.#eventName == "similarity"){
dispatchEvent(new SimilarityEvent("selectSimilarity", null, null)); // how to listen to this event?
}
}
</fx:Script>
<fx:Declarations>
<fx:XML id="myMenuData">
<root>
<menuitem label="Select type..." eventName="copy">
<menuitem label="Other..." eventName="typeOther"/>
<menuitem type="separator"/>
<menuitem label="Order" type="check" eventName="typeOther"/>
<menuitem label="Range" type="check" eventName="typeOther"/>
<menuitem label="Date/Time" type="check" eventName="typeTime"/>
<menuitem label="Latitude" type="check" eventName="typeLat"/>
<menuitem label="Longitude" type="check" eventName="typeLng"/>
</menuitem>
<menuitem label="Define similarity..." eventName="similarity"/>
<menuitem type="separator"/>
<menuitem label="Filter objects..." eventName="similarity"/>
<menuitem label="Order" eventName="similarity">
<menuitem label="Ascending" eventName="typeOther"/>
<menuitem label="Descending" eventName="typeOther"/>
</menuitem>
<menuitem type="separator"/>
<menuitem label="Remove" eventName="paste"/>
</root>
</fx:XML>
</fx:Declarations>
<mx:Label id="myLabel" click="showMenu();"/>
<mx:Image height="20" id = "typeIcon"/>
</mx:HBox>
Here is how I instantiate the renderer:
var newColumn:DataGridColumn = new DataGridColumn();
newColumn.dataField = attr;
newColumn.headerText = attr;
newColumn.sortable = false;
newColumn.editable = false;
newColumn.draggable = false;
newColumn.headerRenderer = new ClassFactory(newviews.RendererDataHeader);
cols.push(newColumn);
any help will be highly appreciated
Add event listener to control (DataGrid) and make event bubble, it will be caught.

Programmatically change Flex MenuBar item toggled property

I have this MenuBar control in Flex 3. How can I programmatically change the toggled property to false?
<mx:MenuBar labelField="#label" itemClick="itemClickHandler(event);" left="0" right="0" top="0" id="menuBar">
<mx:XMLList>
<menuitem label="File" data="top">
<menuitem label="New" data="file-new"/>
</menuitem>
<menuitem label="View" >
<menuitem label="Grid" type="check" toggled="true" data="view-grid"/>
</menuitem>
</mx:XMLList>
</mx:MenuBar>
Easy enough, just need to bind the toggle property to a property within the class like so:
<fx:Script>
<![CDATA[
[Bindable] private var _toggled:Boolean = true;
]]>
</fx:Script>
<mx:MenuBar labelField="#label" itemClick="itemClickHandler(event);" left="0" right="0" top="0" id="menuBar">
<mx:XMLList>
<menuitem label="File" data="top">
<menuitem label="New" data="file-new"/>
</menuitem>
<menuitem label="View" >
<menuitem label="Grid" type="check" toggled="{this._toggled}" data="view-grid"/>
</menuitem>
</mx:XMLList>
</mx:MenuBar>
Now when you change the _toggled property, it will reflect in the menubar.

menu bar control in flex ,needed to handle separate method for individual menu item

i need to fire separate method for individual menu item clicked ,so that individual item can handle separate method.
and i need know what all the properties are available in menu item like type="radio".
<mx:MenuBar id="jj" labelField="#label" itemClick="MenuItemClick(event)" x="23" y="228">
<mx:XMLList>
<menuitem label="File">
<menuitem label="New" type="radio"/>
<menuitem label="Open" data="Openfile" type="Check" />
<menuitem label="Save" />
<menuitem label="Exist"/>
</menuitem>
</mx:XMLList>
</mx:MenuBar>
Can you give any link or example for menubar control?
Thanks
Example from Adobe Flex docs MenuBar
Only three types allowed: check, radio, or separator.
<?xml version="1.0"?>
<!-- Simple example to demonstrate the MenuBar control. -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initCollections();" >
<mx:Script>
<![CDATA[
import mx.events.MenuEvent;
import mx.controls.Alert;
import mx.collections.*;
[Bindable]
public var menuBarCollection:XMLListCollection;
private var menubarXML:XMLList =
<>
<menuitem label="Menu1" data="top">
<menuitem label="MenuItem 1-A" data="1A"/>
<menuitem label="MenuItem 1-B" data="1B"/>
</menuitem>
<menuitem label="Menu2" data="top">
<menuitem label="MenuItem 2-A" type="check" data="2A"/>
<menuitem type="separator"/>
<menuitem label="MenuItem 2-B" >
<menuitem label="SubMenuItem 3-A" type="radio"
groupName="one" data="3A"/>
<menuitem label="SubMenuItem 3-B" type="radio"
groupName="one" data="3B"/>
</menuitem>
</menuitem>
</>;
// Event handler to initialize the MenuBar control.
private function initCollections():void {
menuBarCollection = new XMLListCollection(menubarXML);
}
// Event handler for the MenuBar control's itemClick event.
private function menuHandler(event:MenuEvent):void {
// Don't open the Alert for a menu bar item that
// opens a popup submenu.
if (event.item.#data != "top") {
Alert.show("Label: " + event.item.#label + "\n" +
"Data: " + event.item.#data, "Clicked menu item");
}
}
]]>
</mx:Script>
<mx:Panel title="MenuBar Control Example" height="75%" width="75%"
paddingTop="10" paddingLeft="10">
<mx:Label width="100%" color="blue"
text="Select a menu item."/>
<mx:MenuBar labelField="#label" itemClick="menuHandler(event);"
dataProvider="{menuBarCollection}" />
</mx:Panel>
</mx:Application>
Also bookmark this page Language Reference.
Vineth,
You are unable to add individual event handlers for menu items unless you dynamically create the menu bar and the sub items. This is more pain than it's worth, so I would recommend using the itemCLick handler as stated above and use a switch to determine what methods to fire. For example:
switch( event.item.#data ){
case "3A":
doSomething();
break;
case "3A":
doSomethingElse();
break;
defualt:
doDefault();
break;
}
Note: this is building off of zdmytriv answer

Resources