问题
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
回答1:
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:
- Give each element an explicit ID in your model (e.g. start.setId('start'))
- in your page after the diagram add some code that adds event handlers to the diagram elements (these are identifiable by their class (`ui-diagram-element)
- in the event handler call a PrimeFaces remote command that calls an actionListener with the id of the clicked element added to it
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
回答2:
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
来源:https://stackoverflow.com/questions/35812682/jsf-primefaces-eventing-in-diagram-elements