How to load dynamic events in Flex - apache-flex

I have a small flex application.
<mx:Script>
<![CDATA[
import flash.events.Event;
// Event handler function to print a message
// describing the selected Button control.
private function printMessage(event:Event):void {
message.text += event.target.label + " pressed" + "\n";
}
]]>
</mx:Script>
<mx:Panel title="Button Control Example"
height="75%" width="75%" layout="horizontal"
paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10">
<mx:VBox>
<mx:Label width="100%" color="blue"
text="Select a Button control."/>
<!-- The button can contain an image, as in the "Button with Icon" button -->
<mx:Button id="iconButton" icon="#Embed('assets/mm-icon.png')" label="Button with Icon"
labelPlacement="right" color="#993300" click="printMessage(event);"/>
<!-- The size of the button and the label attributes can be customized -->
<mx:Button label="Customized Button" color="#993300" toggle="true" selected="true"
textAlign="left" fontStyle="italic" fontSize="13" width="{iconButton.width}"
click="printMessage(event);"/>
<!-- By default, the look and feel of the customized button is
similar to the Default Button. -->
<mx:Button label="Default Button" click="printMessage(event);"/>
</mx:VBox>
<mx:TextArea id="message" text="" editable="false" height="100%" width="100%"
color="#0000FF"/>
</mx:Panel>
What I want to achieve is, I want my user to pass the script as a parameter. so he has the flexibility to do anything with the buttons->like add event, hide the other buttons.
Something like this(below)
<param name="script" value="import flash.events.Event;\n private function printMessage(event:Event):void {\nmessage.text += event.target.label + " pressed" + "\n";\n}">
Thanks.

If I understood, what you want is simply create dynamic event and load it to some component, right? If so in did its very easy to implement.
Just create your own custom event (inherit from Event) or use the Event itself:
var event:Event = new Event("[Your event type here"],[bubbles?],[cancelable?]);
and then add listener to your wanted component to the same "event type".
If you need you can also dispatch this event from wanted component programmatically like this:
[you component].dispatchEvent(event);
but then you have to make sure this component extends EventDispatcher class.
Hope I helped.
Royee

Related

Add button to the flex accordion header which can clickable

I want to add a button with a cross to the header of the accordion which can be clickable. that means i want to display a message when the some one click on that button. i go through many of the samples in the web but couldn't get it done. if any one who knows do this in flex4 it will very helpful.
I tried with also a CanvasButtonAccordionHeader, it shows the button but when i click it, it didn't give the message although i created the click event handler.
if somebody know how to resolve this please describe it with a simple source code.
thanx.
You can easily do that by customizing the header in CSS.
Add the header Style to you accordion.
<mx:Accordion id="accordion"
headerStyleName="accHeader"
width="100%" />
In your CSS
.accHeader {
fillColors: haloSilver, haloBlue;
fillAlphas: 1.0, 0.5;
selectedFillColors: black, black;
}
Or embed your image in here.
You can place that message in your ViewStack.
I use the CanvasButtonAccordionHeader in Flex 3, so not sure if this will work in Flex 4.
But.... in case it's of any use, I create my CanvasButtonAccordianHeader as a custom componant which dispatches an event when the button is clicked:
<CanvasButtonAccordionHeader xmlns="flexlib.containers.accordionClasses.*"
xmlns:mx="http://www.adobe.com/2006/mxml" mouseChildren="true"
<mx:Script>
<![CDATA[
[Bindable]
private var itemName:String;
public function init():void{
itemName=data.name;
}
]]>
</mx:Script>
<mx:Metadata>
[Event(name="homeButtonClicked")]
</mx:Metadata>
<mx:HBox width="100%" horizontalAlign="right" height="100%"
paddingRight="5"
verticalAlign="middle">
<mx:LinkButton label="<>"
click="dispatchEvent(new Event('homeButtonClicked'));"
/>
</mx:HBox>
</CanvasButtonAccordionHeader>
Then I instantiate the custom componant at the bottom of the Accordian as a Header Renderer:
............................................
<mx:headerRenderer>
<mx:Component>
<applicationLayout:AccordionNavHeaderRenderer
homeButtonClicked="outerDocument.dispatchEvent(new Event('homeClick'))"/>
</mx:Component>
</mx:headerRenderer>
</mx:Accordion>
Hope this is of use.

Need to identify the component's selectedItem

I am creating a lot of dynamic flex components like RadioButton, Combo Box, CheckBox.
if(type=="mx.controls.CheckBox"){
//if(rep.currentIndex<5){
for each(j in x){
k=createNewInstanceOfClass(rep.currentItem.type);
k.id="radioGroup"+rep.currentItem;
k.label=j.linkname;
k.data=j.linkname;
linkPanel[rep.currentIndex].addChild(DisplayObject(k));
}
MXML
<mx:Panel layout="horizontal" id="linkPanel" title="Evaluation" fontWeight="bold" height="100%" backgroundColor="0xFFF7E6"
borderThicknessLeft="0" borderThicknessRight="0" cornerRadius="10" headerHeight="20" dropShadowEnabled="false" roundedBottomCorners="true" verticalScrollPolicy
="off" horizontalScrollPolicy="off" headerColors="[#ffffff,#ffffff]" width="100%">
<mx:Form>
<mx:FormItem paddingLeft="2" paddingTop="2" paddingBottom="2">
<mx:Repeater id="rep2" dataProvider="{sendToActionScript(rep.currentItem.link)}" />
</mx:FormItem>
</mx:Form>
</mx:Panel>
When i click on Submit finally i need to get all the selected Values in each question. All the components are dynamically created at runtime.
You can list the children of linkPanel with getChildren()
when looping through them, read the "selected" property
public function test():void {
for each ( var obj:Object in linkPanel.getChildren()) {
if( obj is RadioButton) {
Alert.show( (obj as RadioButton).selected.toString());
}
}
}
If you are creating a list of radio buttons belonging to a group, look into "selectedValue" for this group
<mx:RadioButtonGroup id="rbg" />
<mx:RadioButton id="answer1" group="{rbg}" label="Answer 1" />
public function test():void {
Alert.show( rbg.selectedValue.toString())
}

flex regain lost focus

I have a custom component with textbox & a poup button
as
<mx:HBox>
<mx:Text id="source" height="100%" width="40%" data="my text" />
<mx:VBox backgroundAlpha="0" height="100%" borderThickness="0">
<mx:PopUpButton enabled="true" id="editButton" width="40" icon="#Embed('assets/images/Legends/editIcon.png')"
initialize="popUpButton_initialize()"
popUp="{actionMenuEdit}"
height="19" toolTip="Edit at segment"/>
</mx:VBox>
</mx:HBox>
I am using this custom component as the itemEditor for the datagrid
I have a problem with focus. I need to set focus to the text after popup buttton itemclick
The scenario is that I am typing text in the source text. If I go to popup button and click any item, the focus moves to the popup button, and I am unable to type in the text as the focus is lost.
I need to set the focus back to the source code after pop-up-button item-selection so that I can continue typing.
At the moment I need to click gain in the text and then I am able to type.
source.setFocus()
You will need to add a handler for the change event of the pop up button that sets the focus to your text box.
This will be something like this:
this.focusManager.setFocus(source);
or in your example:
<mx:HBox>
<mx:Text id="source" height="100%" width="40%" data="my text" />
<mx:VBox backgroundAlpha="0" height="100%" borderThickness="0">
<mx:PopUpButton enabled="true" id="editButton" width="40" icon="#Embed('assets/images/Legends/editIcon.png')"
initialize="popUpButton_initialize()"
popUp="{actionMenuEdit}"
change="{this.focusManager.setFocus(source)}"
height="19" toolTip="Edit at segment"/>
</mx:VBox>
</mx:HBox>
may b this help u
if (flexApplication != "undefined") flexApplication.focus();

Flex - Avoid click event on container when enclosed component is clicked

I have a Flex application where I'm using a Canvas to contain several other components. On that Canvas there is a Button which is used to invoke a particular flow through the system. Clicking anywhere else on the Canvas should cause cause a details pane to appear showing more information about the record represented by this control.
The problem I'm having is that because the button sits inside the Canvas any time the user clicks the Button the click event is fired on both the Button and the Canvas. Is there any way to avoid having the click event fired on the Canvas object if the user clicks on an area covered up by another component?
I've created a simple little test application to demonstrate the problem:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
private function onCanvasClick(event:Event):void {
text.text = text.text + "\n" + "Canvas Clicked";
}
private function onButtonClick(event:Event):void {
text.text = text.text + "\n" + "Button Clicked";
}
]]>
</mx:Script>
<mx:Canvas x="97" y="91" width="200" height="200" backgroundColor="red" click="onCanvasClick(event)">
<mx:Button x="67" y="88" label="Button" click="onButtonClick(event)"/>
</mx:Canvas>
<mx:Text id="text" x="97" y="330" text="Text" width="200" height="129"/>
</mx:Application>
As it stands when you click the button you will see two entries made in the text box, "Button Clicked" followed by "Canvas Clicked" even though the mouse was clicked only once.
I'd like to find a way that I could avoid having the second entry made such that when I click the Button only the "Button Clicked" entry is made, but if I were to click anywhere else in the Canvas the "Canvas Clicked" entry would still appear.
The event continues on because event.bubbles is set to true. This means everything in the display heirarchy gets the event. To stop the event from continuing, you call
event.stopImmediatePropagation()
Laplie's answer worked like a charm. For those interested the updated code looks like this:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
private function onCanvasClick(event:Event):void {
text.text = text.text + "\n" + "Canvas Clicked";
}
private function onButtonClick(event:Event):void {
text.text = text.text + "\n" + "Button Clicked";
event.stopImmediatePropagation();
}
]]>
</mx:Script>
<mx:Canvas x="97" y="91" width="200" height="200" backgroundColor="red" click="onCanvasClick(event)">
<mx:Button x="67" y="88" label="Button" click="onButtonClick(event)"/>
</mx:Canvas>
<mx:Text id="text" x="97" y="330" text="Text" width="200" height="129"/>
</mx:Application>
The only difference is the one additional line in the onButtonClick method.
I have 2 ideas, first try this:
btn.addEventListener(MouseEvent.Click,function(event:MouseEvent):void{
event.stopImmediatePropagation();
...
});
if that doesn't work, see if you can add the click listener to the canvas and not the button and check the target property on the event object. something like:
btn.addEventListener(MouseEvent.Click,function(event:MouseEvent):void{
if(event.target == btn){
...
}
else{
...
}
});
Again, these are some ideas of the top of my head...I'll create a small test app and see if these work...

how do I get a handle to a custom component in Flex?

I have a custom login component in Flex that is a simple form that dispatches a custom LoginEvent when a user click the login button:
<?xml version="1.0" encoding="utf-8"?>
<mx:Form xmlns:mx="http://www.adobe.com/2006/mxml" defaultButton="{btnLogin}">
<mx:Metadata>
[Event(name="login",tpye="events.LoginEvent")]
</mx:Metadata>
<mx:Script>
import events.LoginEvent;
private function _loginEventTrigger():void {
var t:LoginEvent = new LoginEvent(
LoginEvent.LOGIN,
txtUsername.text,
txtPassword.text);
dispatchEvent(t);
}
</mx:Script>
<mx:FormItem label="username:">
<mx:TextInput id="txtUsername" color="black" />
</mx:FormItem>
<mx:FormItem label="password:">
<mx:TextInput id="txtPassword" displayAsPassword="true" />
</mx:FormItem>
<mx:FormItem>
<mx:Button id="btnLogin"
label="login"
cornerRadius="0"
click="_loginEventTrigger()" />
</mx:FormItem>
</mx:Form>
I then have a main.mxml file that contains the flex application, I add my component to the application without any problem:
<custom:login_form id="cLogin" />
I then try to wire up my event in actionscript:
import events.LoginEvent;
cLogin.addEventListener(LoginEvent.LOGIN,_handler);
private function _handler(event:LoginEvent):void {
mx.controls.Alert.show("logging in...");
}
Everything looks good to me, but when I compile I get an "error of undefined property cLogin...clearly I have my control with the id "cLogin" but I can't seem to get a"handle to it"...what am I doing wrong?
Thanks.
ah! I figured it out...it was a big oversight on mine...it's just one of those days...
I couldn't get the handle on my component because it was not yet created...I fixed this by simply waiting for the component's creationComplete event to fire and then add the event listener.
You can also do something like this I believe:
<custom:login_form id='cLogin' login='_handler' />
You can also do something like this I
believe:
<custom:login_form id='cLogin' login='_handler' />
Minor clarification as there seem to be some confusion in the original code.
Indeed and the reason for this is that a metadata tag has been used to declare the event that is to be made available that way.
<mx:Metadata>
[Event(name="login", type="events.LoginEvent")]
</mx:Metadata>
However, there was no need to add the event metadata when instead of a component "event" property (login='_handler') an event listener was used:
cLogin.addEventListener(LoginEvent.LOGIN,_handler);
addEventListener -> no metadata tag needed
event property in the component tag -> metadata tag required

Resources