How to set Tab Index Programatically?

Hi,

I have requirement where Grid is provided for the users to edit multiple rows of an Entity. For each Row a column is created dynamically.

Here the challenge is focus changing between the controls in the grid. Currently the focus changes from column 1 to column 2 in the same row. But I want to change from Row 1 to Row 2 from in the same Column. Once the end of the column is reached then move to first row of next column.

I’m using CUBA 7.0.9

My idea is to customize the tabIndex for each control created in the grid. So the focus would change between the controls the way which I want. But I couldn’t figure out how to do it. The documentation says it is XML attribute, but I couldn’t see a method which will set it programatically.

Below is my grid, which is initiated in the XML and then most part of it were created in the program.

image

Below is the UI Descriptor XML for the Grid.

<grid id="equityGrid" responsive="true" stylename="myGrid" align="TOP_LEFT">
    	<columns>
    		<column flex=""/>
    	</columns>
	<rows>
		<row>
			<label align="MIDDLE_LEFT" stylename="scoring" value="msg://balanceSheetDescription"
				   width="100%"/>
		</row>
		<row  flex="2.0">
			<label align="MIDDLE_RIGHT" stylename="bold"
				   value="msg://financialDescription"/>
		</row>
		<row/>
		<row >
			<label align="MIDDLE_RIGHT" stylename="bold"
				   value="msg://financialYear:"/>
		</row>
		<row>
		</row>
		<row>
			<label align="MIDDLE_LEFT" value="msg://shareHolder"/>
		</row>
		<row>
			<label align="MIDDLE_LEFT" value="msg://common"/>
		</row>

		<row>
			<label align="MIDDLE_LEFT" value="msg://retained"/>
		</row>
		<row>
			<label align="MIDDLE_LEFT" value="msg://treasury"/>
		</row>
		<row>
			<label align="MIDDLE_LEFT" value="msg://totalcommon"/>
		</row>
		<row>
			<label align="MIDDLE_LEFT" value="msg://minority"/>
		</row>
		<row>
			<label align="MIDDLE_LEFT" value="msg://totalPrefered"/>
		</row>
		<row>
			<label align="MIDDLE_LEFT" value="msg://analystTotalEquity"/>
		</row>
		<row>
			<label align="MIDDLE_LEFT" value="msg://totalEquity"/>
		</row>
		<row>
			<label align="MIDDLE_LEFT" value="msg://totalAssetsLiabilitiesEquity"/>
		</row>
	</rows>
</grid>

Below is the code which is creating the grid.

    private void createEquityColumn(InstanceContainer<FinancialYear> dc, boolean editable, int yearDiff){
        FinancialYear year = dc.getItem();

        //Create new Column in the Grid
        int colIdx = equityGrid.getColumns() + 1;
        equityGrid.setColumns(colIdx + 1);

        int rowIdx = 0;

        //1st Row
        equityGrid.add(usedInScoring(), colIdx, rowIdx++);

        createFinancialDescription(equityGrid, colIdx, rowIdx++, editable, yearDiff);

        rowIdx++;

        //Year Row
        equityGrid.add(createYearLabel(year), colIdx, rowIdx++);

        rowIdx++;
        rowIdx++;

        createGridCurrencyField(equityGrid, dc,"commonStockAndAPIC", colIdx, rowIdx++, editable);
        createGridCurrencyField(equityGrid, dc,"retainedEarnings", colIdx, rowIdx++, editable);
        createGridCurrencyField(equityGrid, dc,"treasuryStockAndOther", colIdx, rowIdx++, editable);
        CurrencyField<Double> totalCommonEquity = createGridFormulaField(equityGrid, colIdx, rowIdx++);
        totalCommonEquity.setValue(year.totalCommonEquity());

        createGridCurrencyField(equityGrid, dc,"minorityInterests", colIdx, rowIdx++, editable);
        createGridCurrencyField(equityGrid, dc,"totalPreferredEquity", colIdx, rowIdx++, editable);
        createGridCurrencyField(equityGrid, dc,"adjustmentToTotalEquity", colIdx, rowIdx++, editable);

        CurrencyField<Double> totalEquity = createGridFormulaField(equityGrid, colIdx, rowIdx++);
        totalEquity.setValue(year.totalEquity());

        Label<String> totalAssetsLiabilityEquity = uiComponents.create(Label.TYPE_STRING);
        totalAssetsLiabilityEquity.setAlignment(Component.Alignment.MIDDLE_CENTER);
        totalAssetsLiabilityEquity.setValue(year.totalAssetsLiabilitiesEquity());
        equityGrid.add(totalAssetsLiabilityEquity, colIdx, rowIdx);
    }

	private void createGridCurrencyField(GridLayout grid, InstanceContainer<FinancialYear> dc, String property, int colIdx, int rowIdx, boolean editable){
        CurrencyField<Double> field = uiComponents.create(CurrencyField.TYPE_DOUBLE);
        field.setValueSource(new ContainerValueSource<>(dc, property));
        field.setAlignment(Component.Alignment.MIDDLE_CENTER);
        field.setWidth(this.columnWidth);
        field.addStyleName("currency-field");
        field.setEditable(editable);
        grid.add(field, colIdx, rowIdx);
    }

    private CurrencyField<Double> createGridFormulaField(GridLayout grid, int colIdx, int rowIdx){
        CurrencyField<Double> field = uiComponents.create(CurrencyField.TYPE_DOUBLE);
        field.setAlignment(Component.Alignment.MIDDLE_CENTER);
        field.setWidth(this.columnWidth);
        field.setEditable(false);
        field.addStyleName("formula-field");

        grid.add(field, colIdx, rowIdx);
        return field;
    }

    private Label<String> usedInScoring(){
        Label<String> usedInScoringLbl = uiComponents.create(Label.TYPE_STRING);
        usedInScoringLbl.setValue("USED IN SCORING");
        usedInScoringLbl.setAlignment(Component.Alignment.MIDDLE_CENTER);
        usedInScoringLbl.setWidth(columnWidth);
        usedInScoringLbl.addStyleName("scoring");
        return  usedInScoringLbl;
    }

    private Label<String> createYearLabel(FinancialYear year){
        Label<String> yearLbl = uiComponents.create(Label.TYPE_STRING);
        yearLbl.setValue(year.getFinancialYear().toString());
        yearLbl.setAlignment(Component.Alignment.MIDDLE_CENTER);

        return yearLbl;
    }

    private void createFinancialDescription(GridLayout grid, int colIdx, int rowIdx, boolean editable, int yearDiff){
        if(editable)
        {
            Label<String> financialDescription = uiComponents.create(Label.TYPE_STRING);
            String labelVal = "Latest Year";
            if(yearDiff > 0) labelVal += " - " + yearDiff;

            financialDescription.setValue(labelVal);
            financialDescription.setAlignment(Component.Alignment.MIDDLE_CENTER);

            grid.add(financialDescription, colIdx, rowIdx);
        }

    }

The grid is injected into the editor as below.

	@Inject
    private GridLayout cashFlowGrid;

How to set the tab index of a control programatically?

Thanks & Regards,
Hari

Hi some one from Cuba support help?

Hello Cuba Support Team,

Your response to this query would be greatly appreciated.

Thanks,
Hari

Hi @gorelov ,

I need a experts suggestion on this post. It has been nearly a week I have created this post.

Request your attention.

Thanks,
Hari

Hi,

Any component that implements the com.haulmont.cuba.gui.components.Component.Focusable interface has the setTabIndex method. All fields (e.g. CurrencyField, TextField, etc.) implement this interface.

Regards,
Gleb

Hi,

I couldn’t find this method for at least CurrencyField. Please my below code which creates the Currency Field Dynamically and adds it to a Grid.

image

Am I doing something wrong?

Thanks,
Hari

And when I had a look at the Code of Currency Field I found, it doesn’t extends Component.Focusable.

image

However TextField extends TextInputField which extends Component.Focusable. Please see below.

image

Thanks,
Hari

.

You’re right, it appeared that CurrencyField doesn’t implement Focusable. I created a GitHub issue.

Do you have a workaround till you fix?

You can unwrap the Vaadin component and set tabIndex to it, e.g.:

field.unwrap(CubaCurrencyField.class).setTabIndex(...);

Thanks!! I will use this code.

Update; It worked the way I expected!! Thanks for the help. I do have one more doubt (How to do). Will create a another post will enough information in it.