Reputation: 33
i need to access the data object of an org.primefaces.model.diagram.Element in a managedBean on click of this very element. I am using primefaces 5.2. I tried multiple ways to establish this, but none did work so far. Here is one approach:
xhtml:
the idea is, to pass the element through a commandLink action attribute (which works fine for e.g. data tables):
<fl:composition template="/WEB-INF/template.xhtml" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:fl="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui">
<fl:define name="content">
<h:form id="form">
<p:diagram style="height:600px" value="#{flowDiagramBean.model}" var="el">
<f:facet name="element">
<p:commandLink actionListener="#{flowDiagramBean.onElementClicked}" update="@form" value="#{el.actionElementLabelText}">
<f:attribute name="element" value="#{el}"/>
</p:commandLink>
</f:facet>
</p:diagram>
</h:form>
</fl:define>
</fl:composition>
The inital build up of the prototypes diagram:
@PostConstruct
public void init() {
setModel(new DefaultDiagramModel());
getModel().setMaxConnections(-1);
getModel().getDefaultConnectionOverlays().add(new ArrowOverlay(20, 20, 1, 1));
FlowChartConnector connector = new FlowChartConnector();
connector.setPaintStyle("{strokeStyle:'#C7B097',lineWidth:3}");
getModel().setDefaultConnector(connector);
ScreenFlowItemObj screenFlowItemObj = new ScreenFlowItemObj();
screenFlowItemObj.setActionElementLabelText("test");
Element start = new Element(screenFlowItemObj, "20em", "6em");
start.addEndPoint(new BlankEndPoint(EndPointAnchor.BOTTOM));
start.addEndPoint(new BlankEndPoint(EndPointAnchor.LEFT));
Element trouble = new Element(screenFlowItemObj, "20em", "18em");
trouble.addEndPoint(new BlankEndPoint(EndPointAnchor.TOP));
trouble.addEndPoint(new BlankEndPoint(EndPointAnchor.BOTTOM));
trouble.addEndPoint(new BlankEndPoint(EndPointAnchor.RIGHT));
model.addElement(start);
model.addElement(trouble);
}
As you can see, the type ScreenFlowItemObj is the passed data object of each element.
The actionListener looks like this:
public void onElementClicked(ActionEvent event) {
ScreenFlowItemObj screenFlowItemObj = (ScreenFlowItemObj) event.getComponent().getAttributes().get("element");
}
Unfortunately on click of the commandLink the attribute "element" does not get put to the attribute map, so in the listener screenFlowItemObj resolves to null. Am i doing something wrong? Might there be another way to make this happen?
I am using primefaces 5.2 on a 1.7 tomee with JSF 2.2.
Thank you,
Gunnar
Upvotes: 2
Views: 4537
Reputation: 33
Thanks to Kukeltje approach, i was able to implement the functional reqiurement successfully:
xhtml:
<fl:composition template="/WEB-INF/template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:fl="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<fl:define name="content">
<h:form id="screenFlowForm">
<p:diagram value="#{flowDiagramBean.model}" var="el"
style="height:600px">
<f:facet name="element">
<h:outputText value="#{el.actionElementLabelText}" />
</f:facet>
</p:diagram>
<p:remoteCommand name="elementClicked"
actionListener="#{flowDiagramBean.onElementClicked}"/>
<script type="text/javascript">
$(document).on('click',
'.ui-diagram > .ui-diagram-element',
function(info) {
elementClicked([ {
name : 'elementId',
value : info.target.id
} ]);
});
</script>
</h:form>
</fl:define>
</fl:composition>
ActionListener:
public void onElementClicked() {
logger.info(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("elementId"));
}
Works for me. I do not understand, why i have to pass the parameter in an one-element array, but ok - it is working.
Thank you for leading me to the right direction.
Gunnar
Upvotes: 1
Reputation: 12337
There is no click event on 'elements' in the jsPlumb framework that PrimeFaces uses, so an 'ajax' select event is not possible, not directly anyway.
What you could do is:
adding the eventhandler:
$(document).on('click', '.ui-diagram > .ui-diagram-element', function(info){
console.log(info.target.id); // change this to call the remote command
});
How the info.target.id
can be passed to a remote command can be read in this stackoverflow Q/A
I checked step 1 and 2 and used 3 before. It all works, I just did not combine them yet, but that should be not to difficult
Upvotes: 3