Search code examples
primefacesdrag-and-dropelementdiagram

Primefaces: Cloning of Diagram Element does not work properly


i want to add multiple elements on an existing diagram in primefaces but it overwrites the created one all the time. It creates the first one and after that it keeps overwriting whenever i drop a new element on the diagram. I'm using the panel via drag'n drop to add new element to the diagram.

See below my code (diagram.xhtml):

<h:form id="elementForm">

    <p:panel id="epnl" header="Draggable Panel">
        <h:outputText value="New Workflow Task" />
    </p:panel>
    <p:draggable for="epnl" helper="clone" />

    <p:outputPanel id="selectedElements" style="height:600px">
        <p:diagram id="diagramV" value="#{diagramFlowChartView.model}"
            style="height:600px" styleClass="ui-widget-content" />
    </p:outputPanel>


    <p:droppable for="diagramV" widgetVar="dropWV">
        <p:ajax listener="#{diagramFlowChartView.onElementDrop}"
            update="elementForm, selectedElements, diagramV" />
    </p:droppable>
</h:form>
<script type="text/javascript">
    //<![CDATA[
    PrimeFaces.widget.Droppable.prototype.bindDropListener = function() {
        var _self = this;
        this.cfg.drop = function(event, ui) {
            if (_self.cfg.onDrop) {
                _self.cfg.onDrop.call(_self, event, ui);
            }
            if (_self.cfg.behaviors) {
                var dropBehavior = _self.cfg.behaviors['drop'];
                if (dropBehavior) {
                    var ext = {
                        params : [ {
                            name : _self.id + '_dragId',
                            value : ui.draggable.attr('id')
                        }, {
                            name : _self.id + '_dropId',
                            value : _self.cfg.target
                        }, {
                            name : ui.draggable.attr('id') + '_left',
                            value : ui.position.left
                        }, {
                            name : ui.draggable.attr('id') + '_top',
                            value : ui.position.top
                        } ]
                    };
                    console.log(ui);
                    dropBehavior.call(_self, ext);
                }
            }
        };
    }
    // ]]>
</script>   

The related Bean (FormChartView.java):

@ManagedBean(name = "diagramFlowChartView")
@RequestScoped
public class FlowChartView {

private DefaultDiagramModel model;

private Element elm = new Element("", "25em", "10em");

private List<Element> elements = new ArrayList<Element>();

public void onElementDrop(DragDropEvent ddEvent) {
    String dargId = ddEvent.getDropId();
    System.out.println("dargId = " + dargId);
    Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
    String left = params.get(dargId + "_left");
    String top = params.get(dargId + "_top");
    elment = new Element("Test", left, top);
    elment.setId(UUID.randomUUID().toString());
    System.out.println("elm.id = " + elm.getId());
    model.addElement(elm);

}


@PostConstruct
public void init() {
    model = new DefaultDiagramModel();
    elm = new Element("", "25em", "10em");
    model.setMaxConnections(-1);

    FlowChartConnector connector = new FlowChartConnector();
    connector.setPaintStyle("{strokeStyle:'#C7B097',lineWidth:3}");
    model.setDefaultConnector(connector);

    Element start = new Element("Fight for your dream", "20em", "6em");
    start.addEndPoint(new BlankEndPoint(EndPointAnchor.BOTTOM));
    start.addEndPoint(new BlankEndPoint(EndPointAnchor.LEFT));
    start.setDraggable(true);
    start.setStyleClass("background-color: #98AFC7");

    Element trouble = new Element("Do you meet some trouble?", "20em", "18em");
    trouble.addEndPoint(new BlankEndPoint(EndPointAnchor.TOP));
    trouble.addEndPoint(new BlankEndPoint(EndPointAnchor.BOTTOM));
    trouble.addEndPoint(new BlankEndPoint(EndPointAnchor.RIGHT));
    trouble.setDraggable(true);

    Element giveup = new Element("Do you give up?", "20em", "30em");
    giveup.addEndPoint(new BlankEndPoint(EndPointAnchor.TOP));
    giveup.addEndPoint(new BlankEndPoint(EndPointAnchor.LEFT));
    giveup.addEndPoint(new BlankEndPoint(EndPointAnchor.RIGHT));

    Element succeed = new Element("Succeed", "50em", "18em");
    succeed.addEndPoint(new BlankEndPoint(EndPointAnchor.LEFT));
    succeed.setStyleClass("ui-diagram-success");

    Element fail = new Element("Fail", "50em", "30em");
    fail.addEndPoint(new BlankEndPoint(EndPointAnchor.LEFT));
    fail.setStyleClass("ui-diagram-fail");

    model.addElement(start);
    model.addElement(trouble);
    model.addElement(giveup);
    model.addElement(succeed);
    model.addElement(fail);

    elements.add(start);
    elements.add(trouble);
    elements.add(giveup);
    elements.add(succeed);
    elements.add(fail);


    model.connect(createConnection(start.getEndPoints().get(0), trouble.getEndPoints().get(0), null));
    model.connect(createConnection(trouble.getEndPoints().get(1), giveup.getEndPoints().get(0), "Yes"));
    model.connect(createConnection(giveup.getEndPoints().get(1), start.getEndPoints().get(1), "No"));
    model.connect(createConnection(trouble.getEndPoints().get(2), succeed.getEndPoints().get(0), "No"));
    model.connect(createConnection(giveup.getEndPoints().get(2), fail.getEndPoints().get(0), "Yes"));
}

public DefaultDiagramModel getModel() {
    return model;
}

public void setModel(DefaultDiagramModel model) {
    this.model = model;
}

public Element getElment() {
    return elment;
}


public void setElment(Element elment) {
    this.elment = elment;
}


public List<Element> getElements() {
    return elements;
}


public void setElements(List<Element> elements) {
    this.elements = elements;
}


private Connection createConnection(EndPoint from, EndPoint to, String label) {
    Connection conn = new Connection(from, to);
    conn.getOverlays().add(new ArrowOverlay(20, 20, 1, 1));

    if(label != null) {
        conn.getOverlays().add(new LabelOverlay(label, "flow-label", 0.5));
    }

    return conn;
}

}


Solution

  • My fault. This is caused by the element list to be reinitialized each time an (ajax)request was made. Which in turn was caused by the bean scope being @RequestScoped

    Changing @RequestScoped to @ViewScoped solved the issue.