Как получить порядок и ширину столбцов данных простых чисел из ManagedBean

Я использую Primefaces 4.0, JSF Mojarra 2.2.2 и вот мой код данных:

<p:dataTable id="tabexam"
             paginatorPosition="bottom"
             var="exam"
             value="#{dyna.examViewDataModel}"
             widgetVar="examTable"
             emptyMessage="aucun résultat trouvé pour votre recherche"
             paginator="true"
             rows="40" 
             selection="#{dyna.selectedExamen}"
             filteredValue="#{dyna.filteredexams}"
             selectionMode="single"
             resizableColumns="true"  
             draggableColumns="true"
             paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"  
             rowsPerPageTemplate="40,80,120">

<p:columns value="#{datatableBean.table}"
           var="column"
           headerText="#{column.userListname}"
           rendered="#{column.visible}"
           resizable="#{column.resizable}"
           width="#{column.width}"
           columnIndexVar="colIndex">

   <h:panelGroup>
             <p:outputLabel value="#{column.dbname}" styleClass="fonty"/>
   </h:panelGroup>

 </p:columns>

</p:dataTable>

Вот что я пробовал до сих пор, но я получаю пустые строки для getHeaderText в консоли и пустую ширину, интересно, чего мне не хватает

UIViewRoot view = FacesContext.getCurrentInstance().getViewRoot();
    DataTable tabler = (DataTable) view.findComponent(":form1:tabexam");
    List<UIColumn> coler = tabler.getColumns();

    for (int i = 0; i < coler.size(); i++) {

        System.out.println("/////////////////");
        System.out.println(coler.get(i).getValueExpression("headerText").getValue(FacesContext.getCurrentInstance().getELContext()));
        System.out.println(coler.get(i).getHeaderText());
        System.out.println(coler.get(i).isRendered());
        System.out.println(coler.get(i).isResizable());
        System.out.println(coler.get(i).getWidth());
        System.out.println("/////////////////");

    }
 System.out.println(coler.size());

Обратите внимание, что coler.size() дает количество столбцов, показанных в таблице данных. но coler.get(i).getHeaderText() всегда дает пустую строку.

1 ответ

Решение

Вы что-то ошибаетесь

  1. не гнездиться p:column внутри p:columns
  2. DataTable.getColumns не возвращает то, что вы ожидаете:

    public List<UIColumn> getColumns() {
        if(columns == null) {
            columns = new ArrayList<UIColumn>();
            FacesContext context = getFacesContext();
            char separator = UINamingContainer.getSeparatorChar(context);
    
            for(UIComponent child : this.getChildren()) {
                if(child instanceof Column) {
                    columns.add((UIColumn) child);
                }
                else if(child instanceof Columns) {
                    Columns uiColumns = (Columns) child;
                    String uiColumnsClientId = uiColumns.getClientId(context);
    
                    for(int i=0; i < uiColumns.getRowCount(); i++) {
                        DynamicColumn dynaColumn = new DynamicColumn(i, uiColumns);
                        dynaColumn.setColumnKey(uiColumnsClientId + separator + i);
                        columns.add(dynaColumn);
                    }
                }
            }
        }
    
        return columns;
    }
    

это возвращает синтетическую эмуляцию: только columnKey для каждого столбца и, как вы указали, правильное количество столбцов.

вообще говоря, p:columns это ОДИН компонент, и когда вы обращаетесь к нему с уровня контроллера, вы должны ссылаться на его DECLARATION (один компонент) вместо его REPRESENTATION (несколько столбцов)

  1. так как вы поддерживаете p:columns с вашим #{datatableBean.table} у вас уже должна быть вся информация, которую вы пытаетесь получить из компонента DataTable, в обратной разработке.

Обновить

о, теперь я понимаю, что ты хочешь делать. Вы должны использовать слушатели событий для этого.

из витрины ПФ:

<p:dataTable var="car" value="#{tableBean.carsSmall}" widgetVar="cars" draggableRows="true">  

    <p:ajax event="colReorder" listener="#{tableBean.onColReorder}" update=":some:component" />  

    <p:ajax event="colResize" listener="#{tableBean.onColResize}" update=":some:component"/>    

    <!-- columns here -->  
</p:dataTable> 

прослушивание этих событий при поддержке бина и поддержание этой информации должно решить вашу проблему

обновление 2

уфф, это было не просто.

из-за ошибки Primefaces для динамического изменения размера столбцов (по крайней мере, для моих попыток) и неполной реализации события переупорядочения столбцов, вот что получилось:

<h:form id="form">
    <h:panelGroup id="model">
        <ui:repeat var="column2" value="#{testBean.columnList2}">
            <div>#{column2.title} - #{column2.width}</div>
        </ui:repeat>
    </h:panelGroup>

    <p:dataTable var="elem" value="#{testBean.elementList}" resizableColumns="true" draggableColumns="true">
        <p:ajax event="colReorder" listener="#{testBean.onColumnReorder}" update=":form:model" />  
        <p:ajax event="colResize" listener="#{testBean.onColumnResize}" update=":form:model"/>  

        <c:forEach var="column" items="#{testBean.columnList}">
            <p:column headerText="#{column.title}" rendered="#{column.visible}" width="#{column.width}">
                <f:attribute name="myCol" value="#{column}"/>
                <span>#{elem[column.property]}</span>
            </p:column>
        </c:forEach>
    </p:dataTable>
</h:form>

и этот боб:

@ManagedBean
@ViewScoped
public class TestBean implements Serializable
{
    private static final long serialVersionUID = 1L;

    private List<MyColumn> columnList;
    private List<MyColumn> columnList2;
    private List<MyElement> elementList;

    public class MyColumn
    {
        private String title;
        private String property;
        private boolean visible = true;
        private boolean resizable = true;
        private int width = 100;

        public MyColumn(String title, String property, boolean visible, boolean resizable, int width)
        {
            super();
            this.title = title;
            this.property = property;
            this.visible = visible;
            this.resizable = resizable;
            this.width = width;
        }

        // getters and setters
    }

    public class MyElement
    {
        private String code;
        private String name;
        private String type;

        public MyElement(String code, String name, String type)
        {
            super();
            this.code = code;
            this.name = name;
            this.type = type;
        }

        // getters and setters
    }

    @PostConstruct
    public void init()
    {
        columnList = new ArrayList<>();
        columnList.add(new MyColumn("element code", "code", true, true, 100));
        columnList.add(new MyColumn("element name", "name", true, true, 100));
        columnList.add(new MyColumn("element type", "type", true, true, 100));

        columnList2 = new ArrayList<>(columnList);

        elementList = new ArrayList<>();
        elementList.add(new MyElement("001", "foo", "normal"));
        elementList.add(new MyElement("002", "bar", "strange"));
        elementList.add(new MyElement("003", "xyz", "normal"));
        elementList.add(new MyElement("004", "abc", "nothing"));
    }

    public void onColumnResize(ColumnResizeEvent event)
    {
        UIColumn column = event.getColumn();
        int width = event.getWidth();

        UIComponent colComponent = (UIComponent) column;
        MyColumn myCol = (MyColumn) colComponent.getAttributes().get("myCol");

        myCol.setWidth(width);
    }

    public void onColumnReorder(AjaxBehaviorEvent event)
    {
        DataTable table = (DataTable) event.getSource();

        columnList2.clear();

        for(UIColumn column : table.getColumns())
        {
            UIComponent colComponent = (UIComponent) column;

            MyColumn myCol = (MyColumn) colComponent.getAttributes().get("myCol");
            columnList2.add(myCol);
        }
    }

    // getters and setters

}

обновленный код, вы можете найти упорядоченные столбцы в columnList2, теперь также отображаются в виде. теперь вы можете использовать columnList2 хранить рудер и ширину в дБ.

Другие вопросы по тегам