Flex 4.6 - Event Handling Conflict - actionscript-3

I have a datagrid with many columns and one of the columns contains a set of buttons using ItemRenderer. The datagrid itself has a clicked event which displays a panel. However, when any of the buttons is clicked, the clicked event of the datagrid should not be executed. How can I achieve this? Currently both the button click and datagrid events are being dispatched when the buttons are clicked.
Below is the current implementation:
Monitoring.mxml which has a datagrid and one of the column uses ItemRenderer to store a set a buttons.
<s:GridColumn width="300" dataField="" headerText="Control Buttons"
itemRenderer="com.example.ItemRenderer.ButtonControlsItemRenderer">
</s:GridColumn>
Inside the ButtonControlsItemRenderer.mxml, I have 2 buttons - Log and Advisory
<s:Button id="btn_log" width="49" height="35" label="Log"
click="btn_log_clickHandler(event)"/>
<s:Button id="btn_Advisory" width="81" height="35" label="Advisory"
click="btn_Advisory_clickHandler(event)"/>
and these 2 buttons are dispatching custom events to the datagrid with these functions.
protected function btn_log_clickHandler(event:MouseEvent):void {
var myEventObject:Event = new Event("logButtonEventRenderer",true);
dispatchEvent(myEventObject);
}
protected function btn_Advisory_clickHandler(event:MouseEvent):void{
var myEventObject1:Event = new Event("AdvisoryButtonEventRenderer",true);
dispatchEvent(myEventObject1);
}
Event metadata have been declared and event listeners have been added in Monitoring.mxml:
[Event(name="logButtonEvent", type="com.example.GetSelectedSystemEvent")]
[Event(name="AdvisoryButtonEvent", type="flash.events.Event")]
dg_Events.addEventListener("logButtonEventRenderer",btn_logButtonHandler);
dg_Events.addEventListener("AdvisoryButtonEventRenderer",btn_AdvisoryButtonHandler);
protected function btn_logButtonHandler(event:Event):void{
// Do something;
}
protected function btn_AdvisoryButtonHandler(event:Event):void{
// Do something
}
//Datagrid Click Event
protected function dg_Events_gridClickHandler(event:GridEvent):void {
// Display Panel
}
Thank you and really appreciate your help!

Try to call stopImmediatePropagation function in the button click hanler.Mouse event will bubble.
protected function btn_log_clickHandler(event:MouseEvent):void {
event.stopImmediatePropagation();
var myEventObject:Event = new Event("logButtonEventRenderer",true);
dispatchEvent(myEventObject);
}

Related

Remove focus from input on click outside

I'm using Flex 4.6 with spark components. I have form with DropDownList, and I want to achieve next behaviour:
user clicks on text input in DropDownList -> DropDownList get focus
user clicks outside (on background Rect, for example) -> DropDownList lose focus
Suddenly, second part doesn't work from box. DropDownList still in focus when user clicks outside the text input. How to implement required behaviour?
Example:
<?xml version="1.0"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script><![CDATA[
]]></fx:Script>
<s:TextInput />
</s:Application>
If you click on TextInput it gets focus. And you cannot remove this focus by clicking outside TextInput.
I found solution at the official forum. There is a post with same problem.
And working solution in the end:
textInput.addEventListener(FocusEvent.MOUSE_FOCUS_CHANGE, textInputMouseFocusChange, false, 0, true);
// basically the above Event will dispatch when ever the user clicked outside of textinput when the current focus in in textInput.
private function textInputMouseFocusChange(event:FocusEvent):void {
// basically u dont need this first line if u are not calling any function on textInput focusout.
textInput.dispatchEvent(new FocusEvent(FocusEvent.FOCUS_OUT));
// the remaing peice of code will remove the current focus from textInput to the area where the user had clicked.
// this piece of code i have taken from one of the comments in the blog : http://blog.flexexamples.com/2008/09/23/setting-focus-in-flex-using-the-focus-manager/
var focusPoint:Point = new Point();
focusPoint.x = stage.mouseX;
focusPoint.y = stage.mouseY;
var i:int = (stage.getObjectsUnderPoint(focusPoint).length);
stage.focus=InteractiveObject(stage.getObjectsUnderPoint(focusPoint)[i-1].parent);
}
First of all, I think that you are speaking about the ComboBox spark component and not the DropDownList because you have mentioned the TextInput of the component which is a Label control in the case of a DropDownList.
Then, to remove the focus from the ComboBox component, you can set the stage.focus to null when the change event of your component is fired :
<s:ComboBox change="on_Change(event)" />
And
protected function on_Change(event:Event):void
{
stage.focus = null;
}
Hope that can help.

accessing current rowData of dataprovider in flex view

I have a view
<view:SampleDataGridView
rowCount="{Math.min(MAX_ROW_COUNT, hostComponent.dataList.length)}"
dataprovider="{hostComponent.dataList}"
buttonMode="true"
click="clickRow(event)"
/>
I want to get which row was clicked. I tried using currentTarget and target from event object however it wasn't of much use.
Is there a way I can pass some parameter in clickEvent function like clickEvent(rowData) or clickEvent(currentRowIndex)?
Is there any property when we use dataProvider to show currentIndex?
Data Grid
<mx:DataGrid id="employeeDataGrid" doubleClickEnabled="true" itemDoubleClick="selectEmployee(event);" dataProvider={employeeList} >
Handler
protected function selectEmployee(event:ListEvent):void
{
var selectedEmployee:Employee = event.currentTarget.selectedItem as Employee;
}

Change a variable on click actionscript

I would like to know how I could change a variable on click using actionscript.
I have :
private var test:int = 0;
public function thisIsTest():void{
test = test + 1;
}
<mx:Image left="10" bottom="10" source="#Embed(source='Assets/blabla.png')" click="thisIsTest()" buttonMode="true"/>
I would like to add 1 to the variable test each time I click on the button 'blabla'.
The problem is that it only works once.
Thank you for your help
The simplest method would be to use a MouseEvent listener. You attach the listener to whatever you want to be clicked and tell the listener which function to execute when an event is triggered:
var test:int = 0;
image.addEventListener(MouseEvent.CLICK, thisIsTest);
// Will 'listen' for mouse clicks on image and execute thisIsTest when a click happens
public function thisIsTest(e:MouseEvent):void
{
test = test + 1;
trace(test);
}
// Output on subsequent clicks
// 1
// 2
// 3
// 4
This does mean the image you want to attach the listener to needs to be a display object, like a sprite or movieclip, but this shouldn't be a problem if you're using Flash.
EDIT: Further actions noted in comments.
Import an image into Flash and use it to generate a Sprite or Movieclip and give it an Actionscript link id (like a class name):
// Add the image to the stage
var img:myImage = new myImage();
addChild(img);
// Assign the mouse event listener to the image
img.addEventListener(MouseEvent.CLICK, thisIsTest);

itemclick event in spark tabbar?

Hallo tabbar supports item click event. However spark tabBar doesnot supports itemClick event.
is there way to listen itemclick event in SPARK TABBAR
thanks all
Spark components inheriting from ListBase no longer dispatch ItemClick events. You can use the IndexChangeEvent event instead though. It has a property newIndex that tells you which is the newly selected item (or tab in this particular case).
<s:TabBar dataProvider="{dp}" change="trace('selected: ' + event.newIndex)" />
One big difference with the old ItemClick is that this event is only dispatched when the selected item actually changes (as opposed to whenever it is clicked). If you really want the behaviour of ItemClick back, you can create a custom ItemRenderer that dispatches an
ItemClick event.
If you want to react on every click there are a few approaches. Here are two of them:
1./ Create a custom ItemRenderer that dispatches an ItemClick event.
.
public class TabBarButton extends ButtonBarButton {
override public function initialize():void {
super.initialize();
addEventListener(MouseEvent.CLICK, fireItemClick);
}
private function fireItemClick(event:MouseEvent):void {
owner.dispatchEvent(new ItemClickEvent(
ItemClickEvent.ITEM_CLICK, false, false, null, itemIndex, null, data
))
}
}
You can now use it like this:
<s:TabBar id="tabBar" dataProvider="{dp}"
itemRenderer="net.riastar.TabBarButton" />
tabBar.addEventListener(ItemClickEvent.ITEM_CLICK, onItemClick);
2./ Another approach would be to just listen for any click event on the TabBar and use event.target to find the clicked tab:
<s:TabBar dataProvider="{dp}" click="trace(event.target)" />
//traces tabBar.TabBarSkin1.dataGroup.TabBarButton1
Note that this is a direct answer to your question, but I actually don't think you should do this. In most cases IndexChangeEvent.CHANGE will do just fine.

Strange Behaviour on DataGrid with ArrayCollection as DataProvider

I have a Datagrid with an ArrayCollection as DataProvider, the arrayCollection is partially generated by a remoteObject call, the dataprovider seems to works at least until I try to edit the field...
By the RemoteObject I only receive an ArrayCollection with the field ip, but the datagrid looks for the fields ip, check and save...
If I add/edit this new field it works, but only under particular condition
The DataGrid:
<s:DataGrid id="datagrid" left="10" right="10" top="136"
dataProvider="{listaIPCheck}" bottom="10" requestedRowCount="4">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="ip" headerText="Asset"/>
<s:GridColumn dataField="check" headerText="Inventory"/>
<s:GridColumn dataField="save" headerText="Salvataggio"/>
</s:ArrayList>
</s:columns>
</s:DataGrid>
The Script:
[Bindable]private var listaIPCheck:ArrayCollection;
private function ro_resultHandler(event:Event=null):void
{
listaIPCheck = new ArrayCollection();
listaIPCheck = ro.getListUpdate.lastResult;
heap = 0;
// Read Below {POINT #1}
init3();
}
private function init3():void
{
// Read Below {POINT #2}
if (heap<listaIPCheck.length)
{
// omitted the initialization of the process p
p.addEventListener(NativeProcessExitEvent.EXIT, onExit);
try{
p.start(startupInfo);
}catch(e:Error){}
}
}
private function onExit(e:NativeProcessExitEvent):void {
// Read below {POINT #3}
}
Here is my code, now as you can see there are 3 line where I wrote to read below...
Let's assume to put this simple for instead of the commented line (once at a time)
for (var k:Number=0;k<listaIPCheck.length;k++)
{
listaIPCheck.getItemAt(k).check = "checkVal";
listaIPCheck.getItemAt(k).save = "saveVal";
}
This code always work in the 3 points, so at the end of the call the ArrayCollection is always filled with the new values, but the datagrid refresh the items only in point #1 and #2
Why not in Point #3???
The reason the DataGrid doesn't refresh when you change properties on an item in an ArrayCollection is that because changing the properties does not trigger the collectionChange event. The DataGrid has no way to know that properties within the object changed. It has to do with pointers and memory spaces and what exactly the DataGrid is looking at for binding purposes.
In most cases, the invalidateList() method to force a refresh of the display. You can call the refresh() method or the itemUpdated() method on the collection or replace the dataProvider completely to force a refresh.