So I have a problem of integrating plain JavaScript and a primefaces dialog component. The user should get an overlay dialog (single) as a response to a click on a number of dynamically JavaScript-generated Div elements (multiple). The contents of the dialog should depend on which div element the user clicked on.
A simplified structure that mimics the issue is as follows:
javascript (google closure):
// this code is in a loop that creates multiple div elements
// in the page dom structure.
var iconDiv = goog.dom.createDom('div', {
'id': nodeId, // **
'class': 'icondiv',
'style': iconDivStyle // **
}, goog.dom.createDom('img', {
'src': 'layer_icons/unused.png',
'class': 'iconDivImg',
'style': 'width:100% ;position:absolute; height: auto; '
}));
goog.events.listen(iconDiv,goog.events.EventType.CLICK,function (e){
// in an ideal situation, the stringField is set to 'this.id' here ...
dlg1.show();
});
//** these are the code lines that mark the difference between the
// divs created in the loop.
primefaces dialog:
this is the dialog component that is shown when the user clicks on any of the icons created in the above javascript.
<p:dialog id="DialogId" dynamic="true" widgetVar="dlg1">
<h:form id="formId">
<p:outputLabel id="clickedOnDiv_Id" value=" #{managedBean.stringField}"/>
<p:outputLabel id="somePropertyOfThisDiv_Id" value="#{managedBean.stringFieldSetByMethod}"/>
</h:form>
</p:dialog>
Managed Bean:
class managedBean {
private String stringField ; // getter and setter
private String stringFieldSetByMethod ; // getter and setter
public void method(){
// uses the stringField in some way to set 'stringFieldSetByMethod' ...
}
}
the above is what I would like to achieve,if you already figured out the way to achieve it, please advise.
next is what I tried so far:
I added the following javascript function:
populateDialog = function(divId){
document.getElementById('formId:hiddenInput').value = divId;
document.getElementById('formId:hdnBtn').click();
}
so the onClick events handler is changed to the following:
goog.events.listen(iconDiv,goog.events.EventType.CLICK,function (e){
divId = this.id; // where divId is a variable accessible to populateDialog()
dlg1.show();
}); // this is inside a loop, so it is set for each created div
then I added populateDialog() as an OnShow callback to the dialog and changed it to look like:
<p:dialog id="DialogId" dynamic="true" widgetVar="dlg1" onShow="populateDialog();">
<h:form id="formId">
<h:inputHidden id="hiddenInput" value="#{nodesBean.stringField}" />
<p:commandButton id="hdnBtn" ajax="true" actionListener="#{managedBean.method()}" style="display: none;" update=":formId"/>
<p:outputLabel id="clickedOnDiv_Id" value="#{managedBean.stringField}"/>
<p:outputLabel id="somePropertyOfThisDiv_Id" value="#{managedBean.stringFieldSetByMethod}"/>
</h:form>
</p:dialog>
the result is that the managedBean.method is never called, and all the fields are empty when the dialog is loaded, I can follow the progress of JavaScript until the call of populateDialog(), the divId is correct, and I get no JavaScript errors. The server however is completely clueless about all the client side humps and jumps I'm doing, an explanation of what is really happening would be much appreciated.
Thanks in advance!
So the solution is using :
in the dialog:
`<h:inputHidden id="hiddenInput" value="#{nodesBean.stringField}" />
<p:remoteCommand name="remoteCommandFunction" process="hiddenInput" update=":formId"/>`
in the onclick handler (of each dynamically created div)
goog.events.listen(iconDiv,goog.events.EventType.CLICK,function (e){
divId = this.id; // where divId is a variable accessible to populateDialog()
dlg1.show();
}); // this is inside a loop, so it is set for each created div
the javascript function called as dialog onshow callback:
populateDialog = function(divId){
document.getElementById('formId:hiddenInput').value = divId;
remoteCommandFunction(); // this is cool cause it solves my problem, not cool cause you really have to know what you're looking for in the documentation to find it >:-/
}
finally, in the managed bean:
class managedBean {
private String stringField ; // getter and setter
private String stringFieldSetByMethod ; // getter and setter
public void setStringField(String sf){
this.stringField = sf;
method();
}
public void method(){
// uses the stringField in some way to set 'stringFieldSetByMethod' ...
}
}