Problem with p:dashboard model dynamically update

Problem with p:dashboard model dynamically update :

I found this solution :

this is an example for anyone who will find the same difficulty that I met in the creation of a Dynamic Dashboard (everything is dynamic).

My problem question

The project is : Display an empty dashboard, the user will visualize a menu in the right side of the FORM with a list of Meeting Room avaiable. After the click of one Meeting Room, the model will be update and the panel visualized in the right column (pre – assigned with its ID). I assign dynamically every ID, numer of column, number of panel and number of element visualized inside each panel.


First of all, popolate a Java DashboardModel with empty column :

    private DashboardModel model;
    private List<DashboardColumn> dashboardColumn;

    DashboardColumn columnTmp = new DefaultDashboardColumn();
    model.addColumn(columnTmp);
    columnDashboard.add(columnTmp);

Logically you have to create getter and setter for the model. I create a List of DashboardColumn for an easy management of each column.

Popolate a list of meetingRoom object called meetingRoomByOffice. This list will be necessary to the actionMenu to create dynamic element inside the menu.

for(x = 0;x<tempMeetingRoom.size();x++)
                {
                meetingRoomByOffice.add(tempMeetingRoom.get(x));
                }

I popolate a bidimensional Array to save the ID of each column ( column1 = 1 office ID) with the real position inside the list (ID : 450 – position inside the list 0 etc)

for(i = 0;i<officesList.size();i++) {
            officePositionAndColumn[i][0] = (int) (long) officesList.get(i).getId();
            officePositionAndColumn[i][1] = i;

            }

After this, create the element inside the XHTML The first one is the actionMenu

NOTE I’VE GOT A PERSONALIZED ONE, NO PARTICULAR MODIFICATION

<smifn:actionsMenu id="tableAddMeetingRoom" styleClass="col-xs-8 col-md-12 text-right"
                    onclick="@this.update()"
                    title="#{msg['booking.add_meeting_room']}">
                    <c:forEach items="#{homeReceptionDashboardBck.meetingRoomByOffice}" var="meetingRoomElement">
                        <p:menuitem id="#{homeReceptionDashboardBck.getMenuItemId(meetingRoomElement)}" 
                            action="#{homeReceptionDashboardBck.onAddPanel(meetingRoomElement)}" 
                            process="@this"
                            value="#{meetingRoomElement.name}" 
                            icon="icon-add-3" 
                            iconPos="left"
                            update ="widgetBookingReception">
                        </p:menuitem>       <!--  oncomplete="PF('bookingSelect').show()"-->
                    </c:forEach>
                </smifn:actionsMenu>
  1. First foreach —> get a List of element and browse them one by one with the “name” of meetingRoomElement
  2. To get the ID, I have done a particular method call getMenuItemId that generate an ID with the name of the meeting room, splitted. Something like this : Name : Sala Demo –> ID : Sala__Demo
  3. action call the main method to modify the model, I’ll explain it after this list.
  4. update ="widgetBookingReception"> is important to update the entire FORM

Method onAddPanel

I have a special class with two main object :

  • idWidget that it is a string
  • meetingRoom that it is an object MeetingRoom

First of all, I create the ID with one underscore

    String [] nameMeetingRoom = panelSelected.getName().split(" ");
    String idWidget = nameMeetingRoom[0]+"_"+nameMeetingRoom[1];

Create, and add it into a TMP object, after that insert the “widget” inside a list of widget insert in the model by the user. This is important to avoid lost widgets.

    DashboardWidget tmp = new DashboardWidget();

    tmp.setIdWidget(idWidget);
    tmp.setName(panelSelected.getName());
    tmp.setOffice(panelSelected.getOffice());

    widgets.add(tmp);

Now i’ll find the position inside the list, update the model and the listOfMeetingRoom avaible inside the menu.

for(i = 0;i<officePositionAndColumn.length;i++)
    {
        //se l'id che era stato impostato è uguale a quello passato 
        if(officePositionAndColumn[i] [0] == panelSelected.getOffice().getId())
            //posizione della colonna che va da 0 a n.
            columnPosition = officePositionAndColumn[i][1];
    }
    //se è stato trovata la posizione della colonna
    if(columnPosition>=0) {
        //mi ricavo la colonna 
        DashboardColumn columnSelected = new DefaultDashboardColumn();
        columnSelected = columnDashboard.get(columnPosition);
        //imposto l'id al widget
        columnSelected.addWidget(idWidget);
        //sovrascrivo la colonna con quella modificata
        columnDashboard.set(columnPosition, columnSelected);
        //reimposto il modello e ricarico le colonne
        setModel(new DefaultDashboardModel());
        for(i = 0;i<columnDashboard.size();i++)
        {
            this.model.addColumn(columnDashboard.get(i));
        }

        for(i = 0;i<meetingRoomByOffice.size();i++)
        {
            if(meetingRoomByOffice.get(i).equals(panelSelected))
            {
                meetingRoomByOffice.remove(i);
            }
        }

This is how I update the entire model. But now we have to update it into the XHTML.

I create a full dynamic dashboard, this is the code :

<p:dashboard widgetVar="dash" model ="#{homeReceptionDashboardBck.model}">
<c:when test="not empty #{homeReceptionDashboardBck.widgets}">
            <c:forEach items="#{homeReceptionDashboardBck.widgets}" var="Element">

                <p:panel id="#{Element.idWidget}" header="#{Element.name}">
                <c:when test="not empty #{homeReceptionDashboardBck.uploadBooking(Element)}">
                    <c:forEach items="#{homeReceptionDashboardBck.uploadBooking(Element)}" var="row">
                                <h:outputText value="#{homeReceptionDashboardBck.getEventGeneralInfo(row)}"> </h:outputText>
                                <h:outputText> <br/></h:outputText>
                    </c:forEach>
                </c:when>
                <c:otherwise>
                    <c:when test="#{homeReceptionDashboardBck.uploadBooking(Element)}">
                            <h:outputText value="Nessun evento prenotato"> </h:outputText>
                            <h:outputText> <br/></h:outputText>
                        </c:when>
                </c:otherwise>
                </p:panel>
            </c:forEach>

</c:when>
    </p:dashboard>

Be careful, inside the foreach you can’t pass null List or empty List. I use WHEN to prevent that.

If you have any question, I’m happy to answer and share part of my code. See you soon 😀


Leave a Comment