How can I tab accross a ButtonBar component in Flex? - apache-flex

I have a button bar inf flex along with several other input controls, I have set the tabIndex property for each control and all goes well until I tab to the ButtonBar.
The ButtonBar has 3 buttons but tabbing to it, only the first button gets focus, tab again and the focus goes back to the top control...
How can I make tabbing go through ALL buttons in a Flex Button bar? Is there a way to do this or do I need to create individual buttons for this?
This seems like a possible bug to me...

The component is written so the user must press the left/right arrow keys when focus is within the bar to traverse the buttons--this is a fairly standard GUI behavior (you also see this in other places like radio button groups). If you look into the SDK source for ButtonBar, you can see where they've explicitly disabled tab focus for each child button as it's created:
override protected function createNavItem(
label:String,
icon:Class = null):IFlexDisplayObject
{
var newButton:Button = Button(navItemFactory.newInstance());
// Set tabEnabled to false so individual buttons don't get focus.
newButton.focusEnabled = false;
...
If you really want to change this behavior, you can make a subclass to do it, something like this:
package {
import mx.controls.Button;
import mx.controls.ButtonBar;
import mx.core.IFlexDisplayObject;
public class FocusableButtonBar extends ButtonBar {
public function FocusableButtonBar()
{
super();
this.focusEnabled = false;
}
override protected function createNavItem(
label:String, icon:Class=null):IFlexDisplayObject
{
var btn:Button = Button(super.createNavItem(label, icon));
btn.focusEnabled = true;
return btn;
}
}
}

Related

Removing a blinking cursor in Flex Flash Player

I have a MX TextInput field on my form. As one of our user has seizure problems with blinking cursors, I am trying to disable it but without success. Through Control Panel, I have been able to prevent a blinking cursor in Office Apps and on the Web browsers but not with the Flex Application which uses the Flash Player. Has anyone come across this issue and have a solution?
Here's a simple solution that removes the cursor all together. I'm not sure if you want to remove the cursor (feasible) or stop the cursor from blinking (seems less feasible).
It works by setting the underlying TextField object's selectable property to false. The MX TextInput class has it's own selectable property, however, the code in TextInput also requires the editable property to be false to disable selection. So you need to extend TextInput to work around that.
The underlying TextField doesn't expose any properties to stop the cursor from blinking (that I'm aware of). TextField is one of Flash Player's built in classes, so the chances of modifying this low level behavior seem slim.
This obviously breaks the ability to copy/paste in the TextInput. You might have to devise a way to temporarily enable selection to support copy/paste or selecting text in general.
package
{
import mx.controls.TextInput;
public class CustomTextInput extends TextInput
{
public function CustomTextInput()
{
}
private var _hideCursor:Boolean = true;
private var hideCursorChanged:Boolean = true;
public function get hideCursor():Boolean
{
return _hideCursor;
}
public function set hideCursor(value:Boolean):void
{
if (value == hideCursor)
{
return;
}
hideCursorChanged = true;
_hideCursor = value;
invalidateProperties();
}
override protected function commitProperties():void
{
super.commitProperties();
if (hideCursorChanged)
{
hideCursorChanged = false;
textField.selectable = !_hideCursor;
}
}
}
}

how to stop getting mouse click events in flex

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;
}

Flex checkBox: disable state change when clicked on label

I would like the native Flex checkBox to change state only, when the box is clicked. If user clicks the label the state shouldn't change.
The click event cannot be muted as it is utilized in parenting components.
Any ideas how to obtain such functionality? How to detect, that user has clicked the label?
Thanks,
Rafal
Marty Pitt was very close to the right answer. I've added an event handler to his code, that stops the propagation - and now it works perfectly (as expected)!
The code below is a class that extends mx:CheckBox:
override protected function createChildren():void {
super.createChildren();
this.mouseChildren = true;
textField.mouseEnabled = false;
textField.addEventListener(MouseEvent.CLICK, textFieldClickHandler);
}
protected function textFieldClickHandler(me:MouseEvent):void{
me.stopImmediatePropagation();
}
Thank you.
Workaround - checkbox without label and separate label nearby.
If it's a Halo checkbox, I would create a subclass, and override createChildren(), with something like:
override protected function createChildren():void {
super.createChildren();
// in Button, this is false by default, however we want to restrict
// clicking to the button itself, not the label, so allow the children
// to recieve mouse events, to prevent the button from dispatching them.
this.mouseChildren = true;
textField.mouseEnabled = false;
}
That seems like a pretty kludgy hack, but it may work (I haven't tested it).
If it's a Spark checkbox, then you can just create a seperate skin. Much cleaner!

Select multiple items in Flex Tree control without pressing the Ctrl key?

I'm trying to modifty the Flex Tree control to allow a user to select multiple items by just clicking each of the desired elements (ie I don't want them to have to press Ctrl or Shift). If the user clicks a selected item a 2nd time, it will deselect it. Can anyone help me out?
Thanks!
I just had to do this with a datagrid, since they are both based on list it will work for you too
How can I get a datagrid to behave like the ctrl key is active?
You can create a simple custom component of ur own. Here is the code:
package com
{
import flash.events.MouseEvent;
import mx.controls.Tree;
public class ForceCtrlTree extends Tree
{
override protected function mouseClickHandler(event:MouseEvent):void
{
event.ctrlKey = true;
super.mouseClickHandler(event);
}
override protected function mouseDownHandler(event:MouseEvent):void
{
event.ctrlKey = true;
super.mouseDownHandler(event);
}
}
}
Import this package into your project.
Then declare the tree component as follows:
Now you need not click ctrl to select multiple objects.

How do I change the State in an itemRenderer based on an action in another itemRenderer?

I have a DataGridColumn with an ItemRenderer that extends the Box component. The default display is a Text component. When the user clicks on the text component, I change the State to add a PopUpMenuButton child, and make the Text component invisible. This works fine. However, I only want to allow one PopUpMenuButton to be visible in the DataGrid at a time (similar to how an itemEditor works). I don't want to use an itemEditor, because I've run into too many problems trying to get that to work in this instance.
I am implementing IDropInListItemRenderer in my itemRenderer, in order to access the listData property, which will give me the owner (DataGrid), but I don't know how to "turn off" the "editing" state in other itemRenderers in the DataGrid.
How can I accomplish this?
Thanks.
Here we go. I simply added an Listener for Change Events in the listData.owner - if it is triggered, I update the currentState to null. Works like a charm. Much easier than trying to access the itemRenderers in the column and resetting them all. Better on performance too.
private function label_clickHandler():void
{
showEditor();
}
private function showEditor():void
{
this.currentState = "editingMode";
var ownerListBase:ListBase = ListBase(listData.owner);
ownerListBase.addEventListener(ListEvent.CHANGE, ownerListBase_changeHandler);
}
private function ownerListBase_changeHandler(event:ListEvent):void
{
this.currentState = null;
var ownerListBase:ListBase = ListBase(listData.owner);
ownerListBase.removeEventListener(ListEvent.CHANGE, ownerListBase_changeHandler);
}

Resources