0

In my project, I have intertwined 2 datatables. I want to update second datatable when first datatable's rows expanded.

<h:form id="form2">
     <p:dataTable var="modules" value="#{EVMView.allModules}" id="mydatatable"> 
        <f:facet name="header">
            Modules
        </f:facet>
        <p:column style="width:2rem">
            <p:rowToggler/>
        </p:column>
        <p:column headerText="Module">
            <h:outputText value="#{modules}"/>
        </p:column>
        
         <p:rowExpansion>
            <div class="product">
                 <p:dataTable var="questions" value="#{EVMView.allQuestions}" id="mydatatable2"> 
                    <p:column style="width:2rem">
                        <p:rowToggler/>
                    </p:column>
                    <p:column headerText="Question">
                        <h:outputText value="#{questions}"/>
                    </p:column>
                    
                    <p:rowExpansion>
                    
                    </p:rowExpansion>
                 </p:dataTable>
            </div>
         </p:rowExpansion>
     </p:dataTable>
</h:form>

When I expand mydatatable's row, I don't see the values in mydatatable2.

So I know I have to update mydatatable2 too, but I couldn't find how to do it.

EDİT

According to @Jasper's answer, I added ViewScoped in my bean and I added this ajax in my first datatable.

<p:ajax event="rowToggle" listener="#{EVMView.updateTable2()}"/>

My bean is like this

package com.utc.pw.ui;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import org.primefaces.PrimeFaces;

import com.utc.pw.domain.EVMOptions;
import com.utc.pw.domain.EVMQuestions;
import com.utc.pw.domain.SalesOrder;
import com.utc.pw.service.EVMService;
import com.utc.pw.service.PublicService;

@ManagedBean(name="EVMView")
@ViewScoped
public class EVMView {
    @EJB
    private PublicService publicService;
    @EJB
    private EVMService evmService;
    
    private EVMQuestions evmQuestions=new EVMQuestions();
    
    private String strSO;
    private List<SalesOrder> salesOrders;
    private List<String> allModules;
    private List<EVMQuestions> allQuestions;
    private String selectedOption;
    private List<EVMOptions> optionList;
    private String answer;
    
    public String getAnswer() {
        return answer;
    }
    public void setAnswer(String answer) {
        this.answer = answer;
    }
    public List<EVMOptions> getOptionList() {
        return optionList;
    }
    public void setOptionList(List<EVMOptions> optionList) {
        this.optionList = optionList;
    }
    public String getSelectedOption() {
        return selectedOption;
    }
    public void setSelectedOption(String selectedOption) {
        this.selectedOption = selectedOption;
    }
    public List<EVMQuestions> getAllQuestions() {
        return allQuestions;
    }
    public void setAllQuestions(List<EVMQuestions> allQuestions) {
        this.allQuestions = allQuestions;
    }
    public PublicService getPublicService() {
        return publicService;
    }
    public void setPublicService(PublicService publicService) {
        this.publicService = publicService;
    }
    public EVMService getEvmService() {
        return evmService;
    }
    public void setEvmService(EVMService evmService) {
        this.evmService = evmService;
    }
    public EVMQuestions getEvmQuestions() {
        return evmQuestions;
    }
    public void setEvmQuestions(EVMQuestions evmQuestions) {
        this.evmQuestions = evmQuestions;
    }
    public String getStrSO() {
        return strSO;
    }
    public void setStrSO(String strSO) {
        this.strSO = strSO;
    }
    public List<SalesOrder> getSalesOrders() {
        return salesOrders;
    }
    public void setSalesOrders(List<SalesOrder> salesOrders) {
        this.salesOrders = salesOrders;
    }
    public List<String> getAllModules() {
        return allModules;
    }
    public void setAllModules(List<String> allModules) {
        this.allModules = allModules;
    }
    @PostConstruct
    public void init()  {
        this.salesOrders = publicService.getAllSalesOrders();
        
    }
    public void loadModules()
    {
        this.allModules=evmService.getAllModules(strSO);
        this.allQuestions=evmService.getAllQuestions(strSO);
        PrimeFaces.current().ajax().update("form2:mydatatable");
        //PrimeFaces.current().ajax().update("form3:mydatatable2");
    }
    public void updateTable2()
    {
        PrimeFaces.current().ajax().update(":mydatatable2");
    }
    public List<EVMOptions> options(String module,int questionID)
    {
        this.optionList=evmService.getOptions(strSO, module, questionID);
        
        return optionList;
    }
}
demir5334
  • 145
  • 12
  • It's better to use `javax.faces.view.ViewScoped` and `@Named("EVMView")` instead of the deprecated `@ManagedBean`. https://stackoverflow.com/questions/4347374/backing-beans-managedbean-or-cdi-beans-named – Jasper de Vries Feb 08 '21 at 07:40

1 Answers1

1

You don't need to update the table in the p:rowExpansion when it is expanded as it is lazy loaded by default. What you do need to do is make sure that you child p:dataTable value="#{...}" is set correctly. To do so, add a listener on the outer p:dataTable and set the model based on the expanded row. You will need to use the rowToggle event, which takes a ToggleEvent as the parameter.

As your table has multiple rows of modules, you should have model in your bean which can contain multiple modules, like a Map with the module ID as the key and the questions as the value. Add module entries in your rowToggle handler.

Also make sure your bean is at least ViewScoped.

See also:

Jasper de Vries
  • 13,693
  • 6
  • 54
  • 86