I have a grid, when i click on the edit button it goes to edit page... but i need the value in the grid also to be passed to the page.
this.dispatchEvent(new DepManagementEvent(DepManagementEvent.EDIT_NAVI));
The above code lands in EDIT page... how can i move the values too.
My Parent Page code.
private function editForm():void {
var event:DepManagementEvent = new DepManagementEvent("Edit Page",true);
dispatchEvent(event);
}
The Edit Page below....
public function init(event:DepManagementEvent):void {
this.addEventListener(DepManagementEvent.EDIT_NAVI, onEditNavi);
}
public function onEditNavi(event:DepManagementEvent):void {
Alert.show("as");
}
I am not getting the alert, when the page is navigated from the parent one.... on click. Also edit this code on how i can pass the variables too.
Add a public var (called "navi" in the code below) to the DepManagementEvent that's of the same type as the item in the grid, then dispatch the event like this instead:
var event:DepManagementEvent = new DepManagementEvent( DepManagementEvent.EDIT_NAVI );
event.navi = grid.selectedItem;
dispatchEvent( event );
To listen to the event on the other side, you add an event listener for a function...
addEventListener( DepManagementEvent.EDIT_NAVI, onEditNavi);
private function onEditNavi( event:DepManagementEvent ):void
{
// add logic here
}
Since you're in an itemRenderer, you can dispatch a bubbling event that will move up to the parent List/DataGrid and continue to bubble up to other parent views in the display hierarchy. When you create the event, pass the second argument ("bubbles") as true:
new DepManagementEvent( DepManagementEvent.EDIT_NAVI, true );
Related
I have made a hierarchy in which there is a main page, using add element i have attached a component mxml of type group. There is a single button on main page when clicked it should add children of type group in that group type mxml component along with two buttons. Now using one of buttons i am attaching another component mxml type group. the problem is even they overlap i can still excess the children groups of first group component mxml. how can i stop this mouse events to happen.
I think those kind of events usually bubble up to parent components.
You can try using the following code in your mouse click event listener to stop further propagation:
private function onMouseClicked(event: MouseEvent): void {
event.stopPropagation();
... do whatever you wanted when smth was clicked ...
}
By setting enabled, mouseChildren, mouseEnabled to false, you will disable the entire component and it's children. example below
private var myPreviousGroupComponent:Group = null;
function addNewGroup():void
{
if(myPreviousGroupComponent != null)
{
myPreviousGroupComponent.enabled = false;
myPreviousGroupComponent.mouseChildren = false;
myPreviousGroupComponent.mouseEnabled = false;
}
var newGroup:Group = new Group();
addElement(newGroup);
myPreviousGroupComponent = newGroup;
}
I'm using code based on this post.
It uses a focus_out event to detect if there is a change that needs to be committed. However I notice that a FOCUS_OUT event is only called if you click away from the textfield but inside the component. Is there any way I can listen for clicks outside the component from within the component?
addEventListener(FocusEvent.FOCUS_OUT, onFocusOut);
protected function onFocusOut(event:FocusEvent):void
{
_updatedText = text;
if(_updatedText != _originalText){
dispatchEvent(new Event(Event.CHANGE));
}
setEditable(false);
}
In the component itself, you can do this:
systemManager.addEventListener( FocusEvent.KEY_FOCUS_CHANGE, focusChangeHandler );
systemManager.addEventListener( FocusEvent.MOUSE_FOCUS_CHANGE, focusChangeHandler );
Just be sure you clean up and remove the event listener before your component is removed from the stage (assuming it is added dynamically). That will prevent you from stacking up a bunch of event listeners.
Alternatively, if you just want to find out whenever someone clicks outside of a specific component, you can do something like this:
systemManager.addEventListener( MouseEvent.MOUSE_DOWN, system_mouseDownHandler );
private function system_mouseDownHandler( event:MouseEvent ):void {
if( !event.target != this && !this.contains(event.target as DisplayObject) ){
// Do Something Here
}
}
Again, make sure you cleanup any event listeners if this component is added/removed dynamically.
Hope this helps!
EDIT:
If you want to cleanup the eventListeners, do something like this (called when the remove event is triggered in your component):
<mx:Component remove="myRemoveHandler();" />
private function myRemoveHandler():void {
if( systemManager.hasEventListener( MouseEvent.MOUSE_DOWN ) systemManager.removeEventListener( MouseEvent.MOUSE_DOWN, system_mouseDownHandler );
}
Obviously substitute the event listeners that you ended up using (Focus or Mouse).
In LabelEditor class dispatches a Event.CHANGE event on focus out you can just listen for that event
I'm trying to use a flexlib schedule viewer in my application.
I want to have it so that when I click on a scheduled event, it calls a function in my main app (that will allow me to edit the event). But there doesn't seem to be any specific function for anything like this built into the class ie no event dispatched when I click on an event.
I can use the 'click' function to detect that the item has been clicked on.. and have tried something like this:
private function exerciseClickHandler(event:MouseEvent):void{
if (exerciseSeries.selectedItem != null){
//code
}
}
<code:ScheduleViewer id="exerciseSeries" click="exerciseClickHandler(event)" />
This method isn't very reliable because if it only works the first time.. once an item is selected, it stays selected so all following clicks on the item fulfills the condition.
Is there any way to determine whether an event was being clicked on?
Or do I have to extend the component and add some sort of clickEvent when an event is clicked on.
Since exerciseClickHandler is firing up when you click on the component, wouldn't this work?
Instead of
private function exerciseClickHandler(event:MouseEvent):void{
if (exerciseSeries.selectedItem != null){
//code
}
}
write
private function exerciseClickHandler(event:MouseEvent):void{
switch (exerciseSeries.selectedItem)
{
//code
case xy:
break;
}
}
or
private function exerciseClickHandler(event:MouseEvent):void{
//do something with exerciseSeries.selectedItem
}
What I mean is that you wrote that everything stops after the first element is clicked. And according to the code you provided it has to stop, beacuse after the first click exerciseSeries.selectedItem won't be null anymore, since it's selected. So remove the conditional you wrote and use the instance.
I'd suggest you set up a ChangeWatcher to keep an eye on the selectedItem (or selectedItems if you are going to allow multiple selection at some point). Example:
protected exerciseSeriesCreationCompleteHandler(event:FlexEvent):void{
ChangeWatcher.watch(this,['exerciseSeries','selectedItem'], handleChange_SelectedItem);
}
protected function handleChange_SelectedItem(event:PropertyChangeEvent):void{
// Either
dispatchedEvent(//some custom event);
// Or
someDirectMethodCall();
}
An alternative would be to search for an instance of the the event class in the view hierarchy under the mouse coordinates whenever a user clicks.
//Attach this click handler to the component
private function handleClick(event : MouseEvent) : void {
var obj : *EventClass*= null;
var applicationStage : Stage = FlexGlobals.topLevelApplication.stage as Stage;
var mousePoint : Point = new Point(applicationStage.mouseX, applicationStage.mouseY);
var objects : Array = applicationStage.getObjectsUnderPoint(mousePoint);
for (var i : int = objects.length - 1; i >= 0; i--) {
if (objects[i] is *EventClass*) {
obj = objects[i] as *EventClass*;
break;
}
}
if(obj is *EventClass*){
//Dispatch some custom event with obj being the item that was clicked on.
}
}
Where EventClass is the class of the objects that represent events
I have had similar problems and sometimes you can get by with wrapping the object with a Box and putting the click event on the Box. If you have not already tried that, it's a cheap, easy fix (if it works for you).
<mx:Box click="exerciseClickHandler(event)">
<code:ScheduleViewer id="exerciseSeries" />
</mx:Box>
I've a parent (Canvas) with many children (LinkButtons)
The linkButtons trigger an event to communicate between them:
dispatchEvent(new SameBookmarkEvent("SameBookmarkEvent", bookmark.name));
and all linkButtons have a listener
this.addEventListener("SameBookmarkEvent", highlightMe);
...
private function highlightMe(e:SameBookmarkEvent):void {
//do something
}
Now, the issue is that the event is only listened by the dispatcher child. In other words, only the child triggering the event, is receiving it. I was wondering what's wrong with it, and if I should add a listener to the parent (Canvas)...
I basically need the children (LinkButton) communicate between them
Yes, when you add the button's listener to a function within that object, of course only that object will receive the event. When you call addEventListener with the highlightMe function, you pass a reference to the highlightMe function within the current scope. That means that the private function within that class is referenced. But that function is different for each new instance of the class.
In OOP each object works for itself and doesn't know anything about the parents, so one link button should not be able to know that there are other link buttons beside itself and what those buttons do. Instead the parent knows that there are X different link buttons, each working alone, but managed by the parent to work together. In that sense, when working with events, one should always leave the event handling in the parent object – except your custom class has default handlers that keep a standard procedure working (like changing appearance on mouse over etc), or when you have custom events that encapsulate other events.
As such the correct way to deal with it, is to have a single event handler in the parent class (where you instantiate the buttons) which then also is able to identify which button the event is related to.
Example
public class SomeParent extends Sprite
{
public function SomeParent ()
{
var btn:Button;
for ( var i:uint = 0; i < 100; i++ )
{
btn = new Button();
btn.label = 'Button ' + i;
btn.addEventListener( MouseEvent.CLICK, clickHandler );
this.addChild( btn );
}
}
private function clickHandler ( event:MouseEvent ):void
{
var btn:Button = event.eventTarget as Button;
trace( 'Button with id ' + this.getChildIndex( btn ) + ' and label "' + btn.label + '" was pressed.' );
}
}
I have a method to add an XML node structure to the currently selected tree node.
This appends the xml, and opens the parent node to display the newly added node.
I then select the node by setting the selectedItem of the tree.
I have an editing form that updates its values on the tree change event. When I set the selectedItem in this method, The node is selected correctly but the change event never fires (thus the editor doesnt update). I have tried to call it in a call later block to no avail.
Is there a way I can force the tree to dispatch a change event at this point?
public function addSelected(node:XML):void{
tree_expandItem(false);
var selectedItem:XML = tree.selectedItem as XML;
selectedItem.appendChild(node);
tree_expandItem(true);
callLater(function():void { tree.selectedItem = node; } );
}
To extend this question in a general sort of way - I would have thought that changing the selectedItem of the tree would result in a change event anyway? Or is a change only considered a change if the user makes it?
You could move the logic that is currently in your change event handler to a separate function, and then call that function directly:
private function changeHandler(event:ListEvent):void
{
doChangeLogic();
}
private function doChangeLogic():void
{
//statements
}
public function addSelected(node:XML):void
{
tree_expandItem(false);
var selectedItem:XML = tree.selectedItem as XML;
selectedItem.appendChild(node);
tree_expandItem(true);
callLater(function():void { tree.selectedItem = node; } );
doChangeLogic();
}
Is there a way I can force the tree to dispatch a change event at this point?
Use the dispatchEvent() method. Thanks James!