2015-01-02 10 views
0

내 프로젝트는 JasperReport와 비슷한 동적 보고서 앱이며 JSF 2.2.7 (Mojara) 및 primefaces 5.0을 사용하고 있습니다. 사용자가 로그인하면 데이터베이스에서 동적으로로드 된 사용자에게 할당 된 보고서 만 볼 수 있습니다. 보고서를 선택하면 페이지가 두 번째 클릭까지 전체 보고서를로드하지 않는다는 점을 제외하고는 다른 모든 기능이 제대로 작동합니다.동적 JSF/Primefaces 가난한로드

내 문제는 두 번째 클릭까지 보고서가 올바르게로드되지 않는다는 것입니다. 여기에 내 코드가있다.

@Named(value = "userController") 
@SessionScoped 
public class ReportUserController implements Serializable { 

private HtmlPanelGroup panelGroup; // with getter and setter 

@PostConstruct 
public void init() { 
    values = new ArrayList<>(); 
    // Retrieve user's details and reports here 

    MenuModel model = new DefaultMenuModel(); 
    Application application = FacesContext.getCurrentInstance().getApplication(); 
    panelGroup = (HtmlPanelGroup) application.createComponent(HtmlPanelGroup.COMPONENT_TYPE); 
    PanelGrid panelGrid = (PanelGrid) application.createComponent(PanelGrid.COMPONENT_TYPE); 
    panelGrid.setColumns(2); 

    // Retrieve reports for d group the logged-in user belong 
    List<Report> repts = setupController.getExistingReports(); 

    DefaultSubMenu reports = new DefaultSubMenu("Reports"); 
    for (Report rep : repts) { 
     DefaultMenuItem menuItem = new DefaultMenuItem(rep.getReportName()); 
     menuItem.setId(rep.getReportName().replaceAll("\\s+", "")); 
     menuItem.setAjax(true); 
     menuItem.setUpdate(":reportForm"); 
     menuItem.setProcess("@form"); 
     menuItem.setCommand("#{userController.loadReport(" + rep.getId() + ")}"); 
     reports.addElement(menuItem); 
     reports.addElement(new DefaultSeparator()); 

    } 
    model.addElement(reports); 
    Menubar menubar = (Menubar) application.createComponent(Menubar.COMPONENT_TYPE); 
    menubar.setModel(model); 

    panelGroup.getChildren().add(menubar); 

} 

public void loadReport(Long id) { 

    selectedReport = reportFacade.find(id); 
    if (parameters != null) { 
     parameters.clear(); 
    } 

    if (values != null) { 
     values.clear(); 
    } 

    queryColumns = selectedReport.getColumns(); 

    queryParams = selectedReport.getReportParameters(); 
    query = selectedReport.getReportQuery(); 

    // This method is called to build the components of the page to be rendered dynamically. 
    // And it's every time a new report is selected 
    buildPage(); 

} 

} 

그리고 동일한 클래스의 buildPage() 방법입니다. 여기

public void buildPage() { 

    Application application = FacesContext.getCurrentInstance().getApplication(); 
    reportPanelGroup = (HtmlPanelGroup) application.createComponent(HtmlPanelGroup.COMPONENT_TYPE); 
    PanelGrid panelGrid = (PanelGrid) application.createComponent(PanelGrid.COMPONENT_TYPE); 
    panelGrid.setColumns(2); 

    for (ReportParameter param : queryParams) { 

     String parameterLabel = param.getLabel(); 
     String componentType = param.getComponentType(); 
     String calendarPattern = param.getCalendarPattern(); 
     boolean required = param.isRequired(); 
     boolean userProperty = param.isUserProperty(); 
     String queryPosition = param.getQueryPosition(); 
     String sqlDatePattern = param.getSqlDatePattern(); 
     String dataType = param.getDataType(); 
     String userPropertyName = param.getUserPropertyName(); 
     List<DropDown> dropDowns = param.getDropDowns(); 

     if ((userProperty)) { 
      // Retrieve some info from the logged-in user    
     } else { 

      OutputLabel label = (OutputLabel) application.createComponent(OutputLabel.COMPONENT_TYPE); 

      label.setId(parameterLabel.replaceAll("\\s+", "") + "label"); 
      label.setValue(parameterLabel + ":"); 

      if (componentType.equalsIgnoreCase("Calendar")) { 
       Calendar cal = (Calendar) application.createComponent(Calendar.COMPONENT_TYPE); 

       cal.setId(parameterLabel.replaceAll("\\s+", "")); 
       cal.setShowButtonPanel(true); 
       cal.setPattern(calendarPattern); 
       cal.setRequired(required); 

       cal.setValueExpression("value", 
         getExpressionFactory() 
         .createValueExpression(getELContext(), "#{userController.parameters['" 
           + queryPosition.trim() + "']}", Date.class)); 

       label.setFor(parameterLabel.replaceAll("\\s+", "")); 
       panelGrid.getChildren().add(label); 

       panelGrid.getChildren().add(cal); 

      } else if (componentType.equalsIgnoreCase("TextField")) { 
       InputText input = (InputText) application.createComponent(InputText.COMPONENT_TYPE); 
       input.setRequired(required); 
       input.setId(parameterLabel.replaceAll("\\s+", "")); 

       input.setValueExpression("value", 
         getExpressionFactory() 
         .createValueExpression(getELContext(), "#{userController.parameters['" 
           + queryPosition.trim() + "']}", String.class)); 

       label.setFor(parameterLabel.replaceAll("\\s+", "")); 
       panelGrid.getChildren().add(label); 

       panelGrid.getChildren().add(input); 
      } else if (componentType.equalsIgnoreCase("DropDown")) { 

       SelectOneMenu selectOneMenu = (SelectOneMenu) application.createComponent(SelectOneMenu.COMPONENT_TYPE); 
       UISelectItems selectItems = (UISelectItems) application.createComponent(UISelectItems.COMPONENT_TYPE); 
       selectOneMenu.setRequired(required); 
       selectOneMenu.setId(parameterLabel.replaceAll("\\s+", "")); 

       selectItems.setId(parameterLabel.replaceAll("\\s+", "") + "selectItems"); 

       List<SelectItem> items = new ArrayList<>(); 

       items.add(new SelectItem("", "Select...")); 
       if (dropDowns != null && !dropDowns.isEmpty()) { 
        for (DropDown d : dropDowns) { 
         items.add(new SelectItem(d.getValue(), d.getLabel())); 
        } 
       } 

       selectItems.setValue(items); 
       selectOneMenu.getChildren().add(selectItems); 

       selectOneMenu.setValueExpression("value", 
         getExpressionFactory() 
         .createValueExpression(getELContext(), "#{userController.parameters['" 
           + queryPosition.trim() + "']}", String.class)); 

       label.setFor(parameterLabel.replaceAll("\\s+", "")); 
       panelGrid.getChildren().add(label); 

       panelGrid.getChildren().add(selectOneMenu); 

      } 
     } 
    } 
    reportPanelGroup.getChildren().add(panelGrid); 

    HtmlCommandButton searchBtn = (HtmlCommandButton) application.createComponent(HtmlCommandButton.COMPONENT_TYPE); 
    searchBtn.setId("searchBtnID"); 
    searchBtn.setValue("Search"); 
    //searchBtn.setIcon("icon ui-icon-search"); 
    //searchBtn.setAjax(false); 

    ExpressionFactory ef = getApplication().getExpressionFactory(); 
    MethodExpression performSearch = ef.createMethodExpression(getELContext(), 
      "#{userController.performSearch}", null, new Class[]{ActionEvent.class}); 
    MethodExpressionActionListener meal = new MethodExpressionActionListener(performSearch); 
    searchBtn.addActionListener(meal); 
    searchBtn.setType("submit"); 

    //searchForm.getChildren().add(searchBtn); 
    reportPanelGroup.getChildren().add(searchBtn); 

    Spacer spacer = (Spacer) application.createComponent(Spacer.COMPONENT_TYPE); 
    spacer.setHeight("30"); 
    reportPanelGroup.getChildren().add(spacer); 

    HtmlForm downloadForm = (HtmlForm) application.createComponent(HtmlForm.COMPONENT_TYPE); 
    downloadForm.setId("downloadForm"); 

    CommandLink downloadBtn = (CommandLink) application.createComponent(CommandLink.COMPONENT_TYPE); 
    downloadBtn.setId("downloadBtnID"); 
    downloadBtn.setValue("Test Download"); 
    //downloadBtn.setIcon("icon ui-icon-search"); 
    downloadBtn.setAjax(false); 

    String reportName = this.selectedReport.getReportName().trim().replaceAll("\\s+", "").trim(); 

    MethodExpression downloadAnyReport = ef.createMethodExpression(getELContext(), 
      "#{userController.downloadAnyReport(userController.values, " 
      + "userController.headings, '" + reportName + "')}", null, // Replace report name 
      new Class[]{List.class, Collection.class, String.class}); 
    downloadBtn.setType("submit"); 
    downloadBtn.setActionExpression(downloadAnyReport); 

    downloadForm.getChildren().add(downloadBtn); 
    reportPanelGroup.getChildren().add(downloadForm); 

    DataTable dynamicTable = (DataTable) application.createComponent(DataTable.COMPONENT_TYPE); 
    dynamicTable.setValueExpression("value", getExpressionFactory() 
      .createValueExpression(getELContext(), "#{userController.values}", List.class)); 
    dynamicTable.setVar("val"); 
    dynamicTable.setRows(20); 

    List cols = new ArrayList<>(); 

    for (int i = 0; i < queryColumns.size(); i++) { 
     Column col = (Column) application.createComponent(Column.COMPONENT_TYPE); 
     col.setHeaderText(queryColumns.get(i).getPrefferedName()); 
     if (queryColumns.get(i).isLink()) { 
      HtmlForm linkForm = (HtmlForm) application.createComponent(HtmlForm.COMPONENT_TYPE); 
      linkForm.setId("linkForm"); 
      CommandLink link = (CommandLink)  application.createComponent(CommandLink.COMPONENT_TYPE); 

      if (queryColumns.get(i).isDataMasked()) { 
       link.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(), 
         "#{userController.maskStringValue(val[" + i + "]," + queryColumns.get(i).getLeftDigit() + "," + queryColumns.get(i).getRightDigit() + ")}", String.class)); 
      } else { 
       link.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(), 
         "#{val[" + i + "]}", String.class)); 
      } 

      link.setStyle("text-decoration: underline; color: blue;"); 
      MethodExpression action = ef.createMethodExpression(getELContext(), 
        "customizeColumns?faces-redirect=true", null, new Class[]{String.class}); 
      link.setAjax(false); 
      link.setActionExpression(action); 
      linkForm.getChildren().add(link); 
      col.getChildren().add(linkForm); 
     } else { 
      HtmlOutputText out = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE); 
      if (queryColumns.get(i).getFormatAs() != null && queryColumns.get(i).getFormatAs().equals("Amount")) { 
       out.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(), 
         "#{userController.formatAsAmount(val[" + i + "])}", String.class)); 
      } else if (queryColumns.get(i).getFormatAs() != null && queryColumns.get(i).getFormatAs().equals("Number")) { 
       out.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(), 
         "#{userController.formatAsNumber(val[" + i + "])}", String.class)); 
      } else if (queryColumns.get(i).isDataMasked()) { 
       out.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(), 
         "#{userController.maskStringValue(val[" + i + "]," + queryColumns.get(i).getLeftDigit() + "," + queryColumns.get(i).getRightDigit() + ")}", String.class)); 
      } else { 
       out.setValueExpression("value", getExpressionFactory().createValueExpression(getELContext(), 
         "#{val[" + i + "]}", String.class)); 
      } 

      col.getChildren().add(out); 
     } 
     cols.add(col); 
    } 

    dynamicTable.setColumns(cols); //renderReport 
    dynamicTable.setValueExpression("rendered", getExpressionFactory() 
      .createValueExpression(getELContext(), "#{userController.values.size() > 0}",  Boolean.class)); 

    dynamicTable.setPaginator(true); 
    dynamicTable.setRowsPerPageTemplate("20,50,100"); 

    reportPanelGroup.getChildren().add(dynamicTable); 

} 

과 (나와 함께 자사의 바보 긴 코드를하시기 바랍니다 곰은) 내 페이지입니다 :

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<ui:composition xmlns:ui="http://xmlns.jcp.org/jsf/facelets" 
      template="./usersTemplate.xhtml" 
      xmlns:h="http://xmlns.jcp.org/jsf/html" 
      xmlns:p="http://primefaces.org/ui" 
      xmlns="http://www.w3.org/1999/xhtml"> 

<ui:define name="usersTitle"> 
    usersTitle 
</ui:define> 

<ui:define name="usersContent"> 
    <div class="container-fluid"> 
     <p:growl id="growl" life="3000" sticky="true"/> 
     <h:form id="menuForm"> 
      <!-- This panelGroup is for the menubar of reports --> 
      <h:panelGroup binding="#{userController.panelGroup}"/> 
     </h:form> 
     <h:form id="reportForm"> 
      <!-- This panelGroup is to show the components and datatable of the selected report -->    
      <h:panelGroup id="reportPanel" binding="#{userController.reportPanelGroup}"/> 
     </h:form> 
    </div> 
</ui:define> 

다른 모든는 경우를 제외하고는 잘 작동, 내가 다시 말하겠습니다 메뉴 모음의 보고서 목록에서 보고서를 선택하면 두 번째 클릭까지 페이지가 업데이트되지 않고 전체 페이지 제출과 Ajax를 모두 시도했습니다. 제발 수있는 모든 도움을 주셔서 감사합니다. 미리 감사드립니다.

답변

0

나중에 비슷한 문제가있을 수있는 다른 사람들에게, 제가 해결할 솔루션을 게시합니다. 결국 완벽하게 작동하고 있습니다. 선택한 보고서의 구성 요소를 토글 한 rendered 속성이있는 페이지에 <p:commandButton/>을 추가했습니다. 그런 다음 menubar에있는 menuItemsoncomplete 속성을 통해 ajax 호출 후 commandButton 클릭을 발생시키는 자바 스크립트 메서드를 추가했습니다. 여기에 코드 snipets은 다음과 같습니다

// JavaScript:

function clickAgain(){ 
     document.getElementById('reportForm:refreshBtn').click(); 
    } 

// I added the button to my page:

...

<h:form id="reportForm"> 
      <p:commandButton value=" Load #{userController.selectedReport.reportName}" 
          icon="ui-icon-refresh" rendered="#{!userController.renderReport}" 
          id="refreshBtn"> 
       <p:ajax update="@form" listener="#{userController.changeRender()}"/> 
      </p:commandButton> 
      <h:panelGroup id="reportPanel" binding="#{userController.reportPanelGroup}" 
          rendered="#{userController.renderReport}"/> 
</h:form> 

마법은 자바 스크립트 함수는 모든 선택 후라고하며, 사용자가 버튼을 볼 수 없습니다 결코 menuitem과 이것은 버튼을 사라지게 만드는 페이지를 다시로드하고 보고서는 올바르게로드됩니다. 감사합니다.