Alex Belke
Alex Belke

Reputation: 2233

p:dashboard keep sort order after close

I want to use this primefaces dashboard https://www.primefaces.org/showcase/ui/panel/dashboard.xhtml

dashboard.xhtml

<div style="height:500px">
    <h:form>
        <p:growl id="msgs" showDetail="true" />

        <p:dashboard id="board" model="#{dashboardView.model}">
            <p:ajax event="reorder" listener="#{dashboardView.handleReorder}" update="msgs" />

            <p:panel id="sports" header="Sports">
                <h:outputText value="Sports Content" />
            </p:panel>

            <p:panel id="finance" header="Finance">
                <h:outputText value="Finance Content" />
            </p:panel>

            <p:panel id="lifestyle" header="Lifestyle">
                <h:outputText value="Lifestyle Content"  />
            </p:panel>

            <p:panel id="weather" header="Weather">
                <h:outputText value="Weather Content" />
            </p:panel>

            <p:panel id="politics" header="Politics">
                <h:outputText value="Politics Content" />
            </p:panel>
        </p:dashboard>

        <div style="clear:both" />
    </h:form>
</div>

DashBoardView.java

package org.primefaces.showcase.view.panel;

import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.primefaces.event.CloseEvent;
import org.primefaces.event.DashboardReorderEvent;
import org.primefaces.event.ToggleEvent;
import org.primefaces.model.DashboardColumn;
import org.primefaces.model.DashboardModel;
import org.primefaces.model.DefaultDashboardColumn;
import org.primefaces.model.DefaultDashboardModel;

@ManagedBean
@ViewScoped
public class DashboardView implements Serializable {

    private DashboardModel model;

    @PostConstruct
    public void init() {
        model = new DefaultDashboardModel();
        DashboardColumn column1 = new DefaultDashboardColumn();
        DashboardColumn column2 = new DefaultDashboardColumn();
        DashboardColumn column3 = new DefaultDashboardColumn();

        column1.addWidget("sports");
        column1.addWidget("finance");

        column2.addWidget("lifestyle");
        column2.addWidget("weather");

        column3.addWidget("politics");

        model.addColumn(column1);
        model.addColumn(column2);
        model.addColumn(column3);
    }

    public void handleReorder(DashboardReorderEvent event) {
        FacesMessage message = new FacesMessage();
        message.setSeverity(FacesMessage.SEVERITY_INFO);
        message.setSummary("Reordered: " + event.getWidgetId());
        message.setDetail("Item index: " + event.getItemIndex() + ", Column index: " + event.getColumnIndex() + ", Sender index: " + event.getSenderColumnIndex());

        addMessage(message);
    }

    public void handleClose(CloseEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Panel Closed", "Closed panel id:'" + event.getComponent().getId() + "'");

        addMessage(message);
    }

    public void handleToggle(ToggleEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, event.getComponent().getId() + " toggled", "Status:" + event.getVisibility().name());

        addMessage(message);
    }

    private void addMessage(FacesMessage message) {
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    public DashboardModel getModel() {
        return model;
    }
}

enter image description here

It is very cool feature.

I make some drag&drop

enter image description here

and close tab of browser and open it again then all come to default.

enter image description here

I need somehow to keep this order.

Probably use cookies somehow or any other way. Is it possible and if yes how to do it?

Important is that the widget's order should be saved for every user. By this I mean one of two options:

  1. every logged user can see this order in every devices
  2. Without logging in browser but when open new browser the order should be by default. Or some other user open that order should be by default.

Upvotes: 0

Views: 483

Answers (1)

pwain
pwain

Reputation: 279

For sure not the best solution but a solution:

I guess I would save the events from handleReorder(DashboardReorderEvent event) in a database or in a file. And load the order in the postconstruct init. What do you think?

Edit like wrote in the comment it is not possible to serialize the event for me.

My second try is like this:

public void handleReorder(DashboardReorderEvent event) {
        FacesMessage message = new FacesMessage();
        message.setSeverity(FacesMessage.SEVERITY_INFO);
        message.setSummary("Reordered: " + event.getWidgetId());
        message.setDetail("Item index: " + event.getItemIndex() + ", Column index: " + event.getColumnIndex() + ", Sender index: " + event.getSenderColumnIndex());

        addMessage(message);

        serializeEvent(event);
    }

The serializeEvent method does not serialize the event because this failed to me, but it serialize an Object with necessary informations.

private void serializeEvent(DashboardReorderEvent event) {
        String userName = userBean.getUserName();
        StackoverflowObject e = new StackoverflowObject(event);
        try {
            FileOutputStream fileOut =
            new FileOutputStream("c:/tmp/events"+userName+".txt");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(e);
            //out.writeObject(event.getWidgetId()+";"+  event.getItemIndex()+";"+ event.getColumnIndex());
            out.close();
            fileOut.close();

         } catch (Exception i) {
            i.printStackTrace();
         }
    }

in the postconstruct init you read the serialized object and decide where to put the widget. This will show you the idea (it is nearly 1 a.m. so I show you just the beginning)

@PostConstruct
    public void init() {
        model = new DefaultDashboardModel();
        DashboardColumn column1 = new DefaultDashboardColumn();
        DashboardColumn column2 = new DefaultDashboardColumn();
        DashboardColumn column3 = new DefaultDashboardColumn();
        StackoverflowObject e =   deserializeEvent("politics");

        if (e != null &&"politics".equalsIgnoreCase(e.getWidgetId()) && e.getColumnId() == 0){
            column1.addWidget("politics");
        } else   if (e != null &&"politics".equalsIgnoreCase(e.getWidgetId()) && e.getColumnId() == 1){
            column2.addWidget("politics");
        }
        else{
            column3.addWidget("politics");
        }

.. do the same for all other widget

Now you have also the question to do it per user. The method deserializeEvent determinate the user and read the correct file for this user.

If you ask yourself how to get the user. In most cases like this

FacesContext.getCurrentInstance().getExternalContext().getRemoteUser()

If you have a loginbean like in my example you can get it from your userBean.

Edit the stackoverflowObject looks like this

public class StackoverflowObject implements Serializable{


/**
 * 
 */
private static final long serialVersionUID = -4921468076398836905L;
private String widgetId;
private int columnId;
private int itenId;
public StackoverflowObject(DashboardReorderEvent event) {
    this.setWidgetId(event.getWidgetId());
    this.setColumnId(event.getColumnIndex());
    this.setItenId(event.getItemIndex());
}

// +getter and setter

Upvotes: 2

Related Questions