apache-flexflex3usabilityitemrenderer

Flex ItemRenderer prevents use of tabbing between text inputs


I have a custom ItemRenderer that displays 5 text inputs in each of 3 panels:

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox 
    xmlns:mx="http://www.adobe.com/2006/mxml"
    height="300"
    width="800"
    creationComplete="onCreationComplete()"
>
    <!-- code-behind -->
    <mx:Script source="ChainListRenderer.mxml.as" />

    <mx:Label text="{data.title}" fontSize="25" fontWeight="bold" width="100%" textAlign="center" />
    <mx:HBox>
        <mx:Panel id="triggerPanel" title="Trigger" width="260">
            <mx:VBox id="tpBoxes" width="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
                <mx:TextInput id="trigger1" width="100%" textAlign="left" tabIndex="0" tabEnabled="true" />
                <mx:TextInput id="trigger2" width="100%" textAlign="left" tabIndex="1" tabEnabled="true" />
                <mx:TextInput id="trigger3" width="100%" textAlign="left" tabIndex="2" tabEnabled="true" />
                <mx:TextInput id="trigger4" width="100%" textAlign="left" tabIndex="3" tabEnabled="true" />
                <mx:TextInput id="trigger5" width="100%" textAlign="left" tabIndex="4" tabEnabled="true" />
            </mx:VBox>
        </mx:Panel>
        <mx:Panel id="linkPanel" title="Link" width="260">
            <mx:VBox id="lpBoxes" width="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
                <mx:TextInput id="link1" width="100%" textAlign="left" tabIndex="5" tabEnabled="true" />
                <mx:TextInput id="link2" width="100%" textAlign="left" tabIndex="6" tabEnabled="true" />
                <mx:TextInput id="link3" width="100%" textAlign="left" tabIndex="7" tabEnabled="true" />
                <mx:TextInput id="link4" width="100%" textAlign="left" tabIndex="8" tabEnabled="true" />
                <mx:TextInput id="link5" width="100%" textAlign="left" tabIndex="9" tabEnabled="true" />
            </mx:VBox>
        </mx:Panel>
        <mx:Panel id="answerPanel" title="Answer" width="260">
            <mx:VBox id="apBoxes" width="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
                <mx:TextInput id="answer1" width="100%" textAlign="left" tabIndex="10" tabEnabled="true" />
                <mx:TextInput id="answer2" width="100%" textAlign="left" tabIndex="11" tabEnabled="true" />
                <mx:TextInput id="answer3" width="100%" textAlign="left" tabIndex="12" tabEnabled="true" />
                <mx:TextInput id="answer4" width="100%" textAlign="left" tabIndex="13" tabEnabled="true" />
                <mx:TextInput id="answer5" width="100%" textAlign="left" tabIndex="14" tabEnabled="true" />
            </mx:VBox>
        </mx:Panel>
    </mx:HBox>
</mx:VBox>

Unfortunately, when used as an ItemRenderer, tabbing between the text inputs doesn't work, even with the tabIndex values above. If I copy this code to an MXML application of its own, tabbing between text inputs works as expected.

Does anyone know how to restore tabbing in this scenario? It will be a shame if I have to release this app without such a simple usability element.

I suppose I may need to implement mx.managers.IFocusManagerComponent, but I can't find any examples on how to do that, and the FocusManager docs aren't helping either.


Solution

  • I was using an mx:VBox as a custom itemRenderer with rendererIsEditor="true" for my datagrid, and I was running into the tab order issue as well.

    What I figured out is that the itemRenderer needs to implement IFocusManagerComponent in order for the main application's FocusManager() to be able to tab correctly to it. I tried implementing that interface:

    <?xml version="1.0"?>
    <mx:VBox implements="mx.managers.IFocusManagerComponent" ...>
     [the rest of my itemRenderer code]
    </mx:VBox>
    

    ...and it turns out to be rather complex to do...lots of interface functions to implement.

    However in my case I was lucky; I only had one TextInput element in my itemRenderer (the rest was all just custom code, validators & formatters) so I converted my itemRenderer from mx:VBox to mx:TextInput (which already implements the IFocusManagerComponent):

    <?xml version="1.0"?>
    <mx:TextInput ...>
     [the rest of my itemRenderer code]
    </mx:TextInput>
    

    Voila! My tab order issue was fixed.

    I suppose the conclusion for those of you with more complex itemRenderers is you'll need to either fully implement the IFocusManagerComponent interface in your class...which is probably good because it looks like it would tell flex how to custom-tab through your itemRenderer fields. Or perhaps you could change your top level tag to something which already implements the interface, eg: could you nest the mx:VBox inside something like:

    <mx:Container focusIn="FocusManager.setFocus(trigger1)">
    

    ...and have it work perhaps? Someone with more complex code than I should give it a try and see what happens.