1

I have a <t:dataTable> with two <h:selectOneMenu> dropdowns in two columns. The second dropdown is populated depending on the value of the first dropdown.

<t:dataTable value="#{tablaConfigBean.tablaConfigList}" var="item">
    <t:column>
        <h:selectOneMenu value="#{item.tabla}">
            <f:selectItem itemLabel="SIN CORRESPONDENCIA" itemValue="SIN CORRESPONDENCIA"/> 
            <f:selectItems value="#{tablaConfigBean.tablasList}" var="tabla" itemLabel="#{tabla}"  itemValue="#{tabla}"/>
            <f:ajax listener="#{tablaConfigBean.rellenaCampos}" render="seleccionCampoCorrespondido"/>
        </h:selectOneMenu>
    </t:column>
    <t:column>
        <h:selectOneMenu id="seleccionCampoCorrespondido" value="#{item.columnaCorr}">
            <f:selectItems id="listaCampoCorrespondido" value="#{tablaConfigBean.camposList}" var="campo" itemValue="#{campo}"/>
        </h:selectOneMenu>
    </t:column>
</t:dataTable>

Bean:

public void rellenaCampos (AjaxBehaviorEvent event) throws Exception {
    dataTable = (HtmlDataTable) event.getComponent().getParent().getParent();
    fila = (cCNtablaConfig) dataTable.getRowData();
    tablaParaCampos = fila.getTabla();      
    camposList = cDAOtablaConfig.rellenaCamposTabla(idSistema, sistema.desEsquema, tablaParaCampos, 3);
}

Although the first dropdown dosen't have any value, its <f:selectItems> is always loaded by default. If I choose one of those values, then the <f:selectItems> of the second dropdown populates. The problem appears when the both <h:selectOneMenu>s have to show a value preinitialized from the database. As I have written it, the second dropdown is not loaded with the corresponding value unless I choose manually the value on the first dropdown. Then, the expected value appears.

I have tried something like this: Execute managebean method from javascript onload event, but I'm not able to make it work. How can I do this?

Cœur
  • 37,241
  • 25
  • 195
  • 267
AdSsa
  • 268
  • 1
  • 6
  • 21

1 Answers1

1

Your concrete problem is caused because the list of the 2nd dropdown in the last column is been bound to one and same bean property and in no way dependent of the current row.

In this construct, your best bet would be passing the currently selected value of the 1st dropdown to the <f:selectItems> of the 2nd dropdown.

<t:dataTable value="#{tablaConfigBean.tablaConfigList}" var="item">
    <t:column>
        <h:selectOneMenu value="#{item.tabla}">
            <f:selectItem itemLabel="SIN CORRESPONDENCIA" itemValue="SIN CORRESPONDENCIA"/> 
            <f:selectItems value="#{tablaConfigBean.tablasList}" var="tabla" itemLabel="#{tabla}"  itemValue="#{tabla}"/>
            <f:ajax render="seleccionCampoCorrespondido"/>
        </h:selectOneMenu>
    </t:column>
    <t:column>
        <h:selectOneMenu id="seleccionCampoCorrespondido" value="#{item.columnaCorr}">
            <f:selectItems id="listaCampoCorrespondido" value="#{tablaConfigBean.getCamposList(item.tabla)}" var="campo" itemValue="#{campo}"/>
        </h:selectOneMenu>
    </t:column>
</t:dataTable>

(I removed the <f:ajax listener> from the 1st dropdown and I changed the <f:selectItems value> of the 2nd dropdown)

And move the original ajax listener method's job to the getter behind <f:selectItems>.

private Map<Tabla, List<Campo>> tablaCampos = new HashMap<Tabla, List<Campo>>();

public List<Campo> getCamposList(Tabla tablaParaCampos) {
    List<Campo> campos = tableCampos.get(tablaParaCampos);

    if (campos == null) {
        campos = cDAOtablaConfig.rellenaCamposTabla(idSistema, sistema.desEsquema, tablaParaCampos, 3);
        tableCampos.put(table, campos);
    }

    return campos;
}

Note that lazy loading + cache is implemented here. Also note that you should make sure that the equals() and hashCode() of Tabla class are properly implemented.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Many thanks @Balus. I needed this [JSF 2.0 method invocation](http://stackoverflow.com/questions/3284236/jsf-2-0-method-invocation/3284328#3284328) but only if I specify the get function ` – AdSsa Nov 02 '12 at 12:17
  • Which servlet container are you running? – BalusC Nov 02 '12 at 12:21
  • I now see that you edited your comment and switched it the other way round. Using `#{tablaConfigBean.getCamposList(item.tabla)}` is definitely right, using `#{tablaConfigBean.camposList(item.tabla)}` not. But I now see that you actually got this from my answer. Sorry, this was wrong. I've fixed the answer. – BalusC Nov 02 '12 at 12:30
  • Ah, don't worry. And I'm sorry too, indeed, my first comment was wrong. Many thanks again! – AdSsa Nov 02 '12 at 12:35