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).
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>
- First foreach —> get a List of element and browse them one by one with the “name” of meetingRoomElement
- 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
- action call the main method to modify the model, I’ll explain it after this list.
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 😀