msukow
asked on
Flex 3.0 simple navigation question
I had the following code originally which worked:
<mx:Button id="loginButtonID" click="currentState='state 1'"
x="175" y="5" styleName="loginButton" buttonMode="true" cornerRadius="0" />
I now have changed the button to be a component. The click state doesn't work any more because the path is not valid anymore (I think). I tried the following, but it was no good as well:
<mx:Button id="loginButtonID" click="currentState='/stat e1'"
x="175" y="5" styleName="loginButton" buttonMode="true" cornerRadius="0" />
The application mxml is in the same folder as the component folder, which holds the login.mxml component.
What should the click code be?
<mx:Button id="loginButtonID" click="currentState='state
x="175" y="5" styleName="loginButton" buttonMode="true" cornerRadius="0" />
I now have changed the button to be a component. The click state doesn't work any more because the path is not valid anymore (I think). I tried the following, but it was no good as well:
<mx:Button id="loginButtonID" click="currentState='/stat
x="175" y="5" styleName="loginButton" buttonMode="true" cornerRadius="0" />
The application mxml is in the same folder as the component folder, which holds the login.mxml component.
What should the click code be?
Where is 'state1' defined? As you've made the button a (presumably MXML) component by itself, you probably want to move the state definition inside the component as well.
I assume state1 is part of the main application ,not the login component.
<mx:Button id="loginButtonID" click="parent.currentState ='state1'"
x="175" y="5" styleName="loginButton" buttonMode="true" cornerRadius="0" />
or
<mx:Button id="loginButtonID" click="Application.applica tion.curre ntState='s tate1'"
x="175" y="5" styleName="loginButton" buttonMode="true" cornerRadius="0" />
The proper way to do this would be to use events:
in your button component code:
<mx:Button id="loginButtonID" click="dispatchEvent( new Event('loginClicked'))"
x="175" y="5" styleName="loginButton" buttonMode="true" cornerRadius="0" />
and in init function of the module that has the state 1 defined, assuming the login component instance was name 'button1':
button1.addEventListener(" loginClick ed", doClick);
private function doClick( e:Event):void
{
currentState = 'state1';
}
<mx:Button id="loginButtonID" click="parent.currentState
x="175" y="5" styleName="loginButton" buttonMode="true" cornerRadius="0" />
or
<mx:Button id="loginButtonID" click="Application.applica
x="175" y="5" styleName="loginButton" buttonMode="true" cornerRadius="0" />
The proper way to do this would be to use events:
in your button component code:
<mx:Button id="loginButtonID" click="dispatchEvent( new Event('loginClicked'))"
x="175" y="5" styleName="loginButton" buttonMode="true" cornerRadius="0" />
and in init function of the module that has the state 1 defined, assuming the login component instance was name 'button1':
button1.addEventListener("
private function doClick( e:Event):void
{
currentState = 'state1';
}
ASKER
I updated the code below in the main app, as well as the login component. I know I am close, but I can't quite wrap my head around the process. I now get the following error on line 22 of the main app (loginButtonID.addEventLis tener("log inClicked" , loginClick);)
1120: Access of undefined property loginButtonID.
1120: Access of undefined property loginButtonID.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:login="components.*"
layout="absolute" height="612" width="792"
backgroundColor="#FFFFFF" backgroundAlpha="0" currentState="initialState">
<mx:Script>
<![CDATA[
public function captureLoginEvent (event:Event):void
{
trace("logged in");
//click="currentState='productGroupingState'"
}
private function loginClick( e:Event):void
{
currentState = 'state1';
}
//
private function initMSS():void
{
loginButtonID.addEventListener("loginClicked", loginClick);
}
]]>
</mx:Script><mx:states>
<mx:State name="initialState">
<mx:AddChild position="lastChild">
<login:initialScreen x="0" y="245" width="792"/>
</mx:AddChild>
<mx:AddChild position="lastChild">
<login:LoginComp x="541" y="10" />
</mx:AddChild>
<mx:AddChild position="lastChild">
<mx:Image x="150" y="155" source="images/mdiCreativeLogo.swf"/>
</mx:AddChild>
<mx:RemoveChild target="{mdiCreativeLogoMainID}"/>
<mx:RemoveChild target="{monthNavID}"/>
<mx:RemoveChild target="{cartButtonID}"/>
</mx:State>
<mx:State name="productGroupingState"/>
</mx:states>
<mx:Style source="supportFiles/Button.css" />
<mx:Style>
@font-face {
src:url("components/supportFiles/fonts.swf");
fontFamily: "Helvetica";
}
@font-face {
src:url("components/supportFiles/fonts.swf");
fontFamily: "Helvetica";
fontStyle: bold;
}
</mx:Style>
<mx:Image id="mdiCreativeLogoMainID" source="images/mdiCreativeLogo.swf"
x="28" y="71" height="42.559" width="318.338"/>
<login:monthNavComp id="monthNavID" y="144" width="792"/>
<mx:Button x="641" y="67.7" styleName="cartButton" id="cartButtonID" width="65.8" height="55.3" click="currentState='cart'" buttonMode="true"/>
</mx:Application>
---------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" borderThickness="0" borderColor="0x000000">
<mx:Style source="supportFiles/Button.css" />
<mx:Style>
@font-face {
src:url("supportFiles/fonts.swf");
fontFamily: "Helvetica";
}
@font-face {
src:url("supportFiles/fonts.swf");
fontFamily: "Helvetica";
fontStyle: bold;
}
</mx:Style>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
private function checkLogin():void {
if(usernameText.text == "user" && passwordText.text == "pass"){
Alert.show("Success!");
}else{
Alert.show("Fail!");
}
}
]]>
</mx:Script>
<mx:Form id="loginForm" x="0" y="0" verticalGap="3" paddingTop="0" paddingBottom="0" paddingLeft="0" paddingRight="0">
<mx:FormItem id="usernameFormItem" label="Username:">
<mx:TextInput id="usernameText"/>
</mx:FormItem>
<mx:FormItem id="passwordFormItem" label="Password:">
<mx:TextInput id="passwordText"/>
</mx:FormItem>
<mx:Button id="loginButtonID" click="dispatchEvent( new Event('loginClicked'))"
styleName="loginButton" buttonMode="true" cornerRadius="0"/>
<!--<mx:Button id="loginButtonID" label="Login" click="checkLogin()" styleName="loginButton" buttonMode="true" cornerRadius="0"/>-->
</mx:Form>
</mx:Canvas>
Seems hobbit72 guessed correctly what you were trying to do with states.
OK assuming your loginButtonID control is within your monthNavComp control:
monthNavComp.loginButtonID .addEventL istener("l oginClicke d", loginClick);
OR
monthNavComp.addEventListe ner("login Clicked", loginClick);
but the click action in your subcontrol needs to be: click="dispatchEvent( new Event('loginClicked', true))" to allow event bubbling from loginButtonID up to monthNavComp.
OK assuming your loginButtonID control is within your monthNavComp control:
monthNavComp.loginButtonID
OR
monthNavComp.addEventListe
but the click action in your subcontrol needs to be: click="dispatchEvent( new Event('loginClicked', true))" to allow event bubbling from loginButtonID up to monthNavComp.
ASKER
It is actually located in the LoginComp component. I updated the script on the main app to be:
private function initProgram():void
{
LoginComp.loginButtonID.ad dEventList ener("logi nClicked", loginClick);
}
But I don't know how to trigger "initProgram" and I get the following error now:
1119: Access of possibly undefined property loginButtonID through a reference with static type Class. mdiCreative/src mdiCreative.mxml line 22
private function initProgram():void
{
LoginComp.loginButtonID.ad
}
But I don't know how to trigger "initProgram" and I get the following error now:
1119: Access of possibly undefined property loginButtonID through a reference with static type Class. mdiCreative/src mdiCreative.mxml line 22
ASKER
Where should "click="dispatchEvent( new Event('loginClicked', true))" go? On the LoginComp.mxml component?
Difficult to make step by step suggestions when the landscape is changing...
Can you post the code as you now have it?
I'm online for the next 30 mins if you want a quick answer.
Can you post the code as you now have it?
I'm online for the next 30 mins if you want a quick answer.
ASKER
Main app:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:login="components.*"
layout="absolute" height="612" width="792"
backgroundColor="#FFFFFF" backgroundAlpha="0" currentState="initialState ">
<mx:Script>
<![CDATA[
public function captureLoginEvent (event:Event):void
{
trace("logged in");
//click="currentState='pro ductGroupi ngState'"
}
private function loginClick( e:Event):void
{
currentState = 'state1';
}
//
private function initProgram():void
{
LoginComp.loginButtonID.ad dEventList ener("logi nClicked", loginClick);
}
]]>
</mx:Script><mx:states>
<mx:State name="initialState">
<mx:AddChild position="lastChild">
<login:initialScreen x="0" y="245" width="792"/>
</mx:AddChild>
<mx:AddChild position="lastChild">
<login:LoginComp x="541" y="10" />
</mx:AddChild>
<mx:AddChild position="lastChild">
<mx:Image x="150" y="155" source="images/mdiCreative Logo.swf"/ >
</mx:AddChild>
<mx:RemoveChild target="{mdiCreativeLogoMa inID}"/>
<mx:RemoveChild target="{monthNavID}"/>
<mx:RemoveChild target="{cartButtonID}"/>
</mx:State>
<mx:State name="productGroupingState "/>
</mx:states>
<mx:Style source="supportFiles/Butto n.css" />
<mx:Style>
@font-face {
src:url("components/suppor tFiles/fon ts.swf");
fontFamily: "Helvetica";
}
@font-face {
src:url("components/suppor tFiles/fon ts.swf");
fontFamily: "Helvetica";
fontStyle: bold;
}
</mx:Style>
<mx:Image id="mdiCreativeLogoMainID" source="images/mdiCreative Logo.swf"
x="28" y="71" height="42.559" width="318.338"/>
<login:monthNavComp id="monthNavID" y="144" width="792"/>
<mx:Button x="641" y="67.7" styleName="cartButton" id="cartButtonID" width="65.8" height="55.3" click="currentState='cart' " buttonMode="true"/>
</mx:Application>
-------------------------- ---------- ---------- ---------
Login component below
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:login="components.*"
layout="absolute" height="612" width="792"
backgroundColor="#FFFFFF" backgroundAlpha="0" currentState="initialState
<mx:Script>
<![CDATA[
public function captureLoginEvent (event:Event):void
{
trace("logged in");
//click="currentState='pro
}
private function loginClick( e:Event):void
{
currentState = 'state1';
}
//
private function initProgram():void
{
LoginComp.loginButtonID.ad
}
]]>
</mx:Script><mx:states>
<mx:State name="initialState">
<mx:AddChild position="lastChild">
<login:initialScreen x="0" y="245" width="792"/>
</mx:AddChild>
<mx:AddChild position="lastChild">
<login:LoginComp x="541" y="10" />
</mx:AddChild>
<mx:AddChild position="lastChild">
<mx:Image x="150" y="155" source="images/mdiCreative
</mx:AddChild>
<mx:RemoveChild target="{mdiCreativeLogoMa
<mx:RemoveChild target="{monthNavID}"/>
<mx:RemoveChild target="{cartButtonID}"/>
</mx:State>
<mx:State name="productGroupingState
</mx:states>
<mx:Style source="supportFiles/Butto
<mx:Style>
@font-face {
src:url("components/suppor
fontFamily: "Helvetica";
}
@font-face {
src:url("components/suppor
fontFamily: "Helvetica";
fontStyle: bold;
}
</mx:Style>
<mx:Image id="mdiCreativeLogoMainID"
x="28" y="71" height="42.559" width="318.338"/>
<login:monthNavComp id="monthNavID" y="144" width="792"/>
<mx:Button x="641" y="67.7" styleName="cartButton" id="cartButtonID" width="65.8" height="55.3" click="currentState='cart'
</mx:Application>
--------------------------
Login component below
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" borderThickness="0" borderColor="0x000000">
<mx:Style source="supportFiles/Button.css" />
<mx:Style>
@font-face {
src:url("supportFiles/fonts.swf");
fontFamily: "Helvetica";
}
@font-face {
src:url("supportFiles/fonts.swf");
fontFamily: "Helvetica";
fontStyle: bold;
}
</mx:Style>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
private function checkLogin():void {
if(usernameText.text == "user" && passwordText.text == "pass"){
Alert.show("Success!");
}else{
Alert.show("Fail!");
}
}
]]>
</mx:Script>
<mx:Form id="loginForm" x="0" y="0" verticalGap="3" paddingTop="0" paddingBottom="0" paddingLeft="0" paddingRight="0">
<mx:FormItem id="usernameFormItem" label="Username:">
<mx:TextInput id="usernameText"/>
</mx:FormItem>
<mx:FormItem id="passwordFormItem" label="Password:">
<mx:TextInput id="passwordText"/>
</mx:FormItem>
<mx:Button id="loginButtonID" click="dispatchEvent( new Event('loginClicked', true))"
styleName="loginButton" buttonMode="true" cornerRadius="0"/>
<!--<mx:Button id="loginButtonID" label="Login" click="checkLogin()" styleName="loginButton" buttonMode="true" cornerRadius="0"/>-->
</mx:Form>
</mx:Canvas>
click="dispatchEvent( new Event('loginClicked', true))"
goes on the loginButtonID button.
You had before:
<mx:Button id="loginButtonID" click="dispatchEvent( new Event('loginClicked'))"
styleName="loginButton" buttonMode="true" cornerRadius="0"/>
You would make that:
<mx:Button id="loginButtonID" click="dispatchEvent( new Event('loginClicked', true))"
styleName="loginButton" buttonMode="true" cornerRadius="0"/>
to make the event 'bubble'.
Then in your containing control (the application root in this case) you could use:
private function initMSS():void
{
monthNavID.addEventListene r("loginCl icked", loginClick); // this will be 'heard' from the monthNavID control because the event bubbled up from loginButtonID control to it's parent, monthNavID.
}
However you've changed all the code on us now so the names of your controls have changed, but hopefully you can decipher where we're up to from this.
You don't have to use event bubbling.
Right from the example you posted you could have used:
private function initMSS():void
{
monthNavID.loginButtonID.a ddEventLis tener("log inClicked" , loginClick); // this will be 'heard' from the monthNavID control because the event bubbled up from loginButtonID control to it's parent, monthNavID.
}
so without bubbling, you would have to listen to the control sending the event directly.
To make initMSS (or now initProgram?) fire, put a 'creationComplete' event on your login control, e.g.
<login:monthNavComp id="monthNavID" y="144" width="792" creationComplete="initProg ram();"/>
goes on the loginButtonID button.
You had before:
<mx:Button id="loginButtonID" click="dispatchEvent( new Event('loginClicked'))"
styleName="loginButton" buttonMode="true" cornerRadius="0"/>
You would make that:
<mx:Button id="loginButtonID" click="dispatchEvent( new Event('loginClicked', true))"
styleName="loginButton" buttonMode="true" cornerRadius="0"/>
to make the event 'bubble'.
Then in your containing control (the application root in this case) you could use:
private function initMSS():void
{
monthNavID.addEventListene
}
However you've changed all the code on us now so the names of your controls have changed, but hopefully you can decipher where we're up to from this.
You don't have to use event bubbling.
Right from the example you posted you could have used:
private function initMSS():void
{
monthNavID.loginButtonID.a
}
so without bubbling, you would have to listen to the control sending the event directly.
To make initMSS (or now initProgram?) fire, put a 'creationComplete' event on your login control, e.g.
<login:monthNavComp id="monthNavID" y="144" width="792" creationComplete="initProg
1.
You main login component seems to be:
<login:monthNavComp id="monthNavID" y="144" width="792"/>
This is type 'monthNavComp' - it's id is 'monthNavID'.
'loginButtonID' is the id of a button control within your 'monthNavComp' control
2.
Your initProgram function should be:
private function initProgram():void
{
monthNavID.addEventListene r("loginCl icked", loginClick); // because you allowed event bubbling [click="dispatchEvent( new Event('loginClicked', true))]
}
3.
For simplicity for now, to get initProgram called, do this:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:login="components.*"
layout="absolute" height="612" width="792"
backgroundColor="#FFFFFF" backgroundAlpha="0" currentState="initialState "
creationComplete="initProg ram();">
You main login component seems to be:
<login:monthNavComp id="monthNavID" y="144" width="792"/>
This is type 'monthNavComp' - it's id is 'monthNavID'.
'loginButtonID' is the id of a button control within your 'monthNavComp' control
2.
Your initProgram function should be:
private function initProgram():void
{
monthNavID.addEventListene
}
3.
For simplicity for now, to get initProgram called, do this:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:login="components.*"
layout="absolute" height="612" width="792"
backgroundColor="#FFFFFF" backgroundAlpha="0" currentState="initialState
creationComplete="initProg
ASKER
Hmmm... LoginComp should handle the login only.
And monthNavComp should just be a component that handles 6 buttons, which display the different months. They should not affect each other. It is obvious I have something wrong with my logic. I tried to send the archived flex files, but it didn't let me. Can I email you the files somehow?
And monthNavComp should just be a component that handles 6 buttons, which display the different months. They should not affect each other. It is obvious I have something wrong with my logic. I tried to send the archived flex files, but it didn't let me. Can I email you the files somehow?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for the hard work - I will look into this tomorrow morning.
Update?