I have jsf page with TabView... Together 3 tabs. Tabs calls dialogs with some forms for creating elements. Dialogs are placed in external .xhtml page.
First tab is on "main" page (code placed below) and growl message called from validation bean shows well on the page. Second tab is calling growl message but from button placed on form from external file with dialogs... No errors occurs but the growl message didn't show at all.
My "main" view:
<ui:composition>
<p:growl id="growl" showDetail="true" life="4000" />
<h:form id="systemSettingsForm">
<p:tabView id="ticketSettingsTab" rendered="true" widgetVar="tabViewVar">
<p:tab id="tab0">
...
</p:tab>
<p:tab id="tab1">
<ui:include src="/WEB-INF/tags/dialogs.xhtml" />
<p:commandButton value="Add" oncomplete="PF('addDialog').show()" update=":systemSettingsForm:ticketSettingsTab:addingDlg" />
...
</p:tab>
</p:tabView>
</h:form>
</ui:composition>
</h:body>
Dialogs view looks like (nothing special as I think...):
<p:dialog id="addPositionDlg" header="Add position" widgetVar="addDialog">
<h:panelGrid id="addingDlg" columns="3" >
<p:outputLabel value="Position name :"/>
<p:selectOneMenu id="selectType" value="#{positionsTableView.positionType}" >
<f:selectItem itemLabel="Select one option" itemValue="" />
<f:selectItems value="#{positionsTableView.types}" />
</p:selectOneMenu>
<p:outputLabel style="width:1px;"/>
<p:outputLabel value="Prefix :" />
<p:inputText id="addPrefix" value="#{positionsTableView.newPosition.prefix}" />
<pe:tooltip for="addPrefix" showEvent="focus" hideEvent="blur">...</pe:tooltip>
//few simillar inputs, not even validated
<center>
<p:commandButton value="Add" actionListener="#{positionsTableView.addByPrefix}" ajax="true"
update=":systemSettingsForm:ticketSettingsTab:mappingTable" oncomplete="PF('addDialog').hide();"/>
</center>
</h:panelGrid>
</p:dialog>
Growl message is added in actionListener invoked by command button in dialog form (#{positionsTableView.addByPrefix}) and this bean is in the same package as previous one (this working) and message is added in the same manner, which is:
public static void addMessage(String title, String message) {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(title, message));
}
Both beans calling messages are session-scoped.
I have searched here and tried to google solutions but none was successful...
Please help.
MY SOLUTION:
At command button which invokes the message to be displayed on growl element I have updated whole tabView menu and it works.Maybe it's not the best solution, but updating growl id causes an error (it was not visible from dialog file).
Related
I work on a xhtml page which uses two tabs which contain command buttons.
After one command button clicked in Tab1, which contains "Person Information", then the other tab, which has "Address Information" is opened.
My second tab has selectOneMenu with using p:ajax listener. After clicking first button, second tab is not visible, and besides the command button in the Tab1 is not fired.
After using different components such as outputText, components of Tab2 became visible. Could you have any solution for this problem?My code is as shown in below:
Code:
<h:form>
<p:accordionPanel>
<p:tab title="Person Information">
<h:panelGrid>
<p:selectOneMenu filterEnable="true"
disabled="#{bean1.disableChoosePerson}" required="true"
value="#{bean1.person}">
<f:selectItems value="#{bean1.personList}" />
</p:selectOneMenu>
</h:panelGrid>
<p:commandButton value="save" rendered="#{bean1.renderSave}"
action="#{bean1.actionSavePerson}" />
</p:tab>
<p:tab title="Address Information"
disabled="#{bean1.adressDisabled}">
<h:panelGrid>
<p:selectOneMenu value="#{bean1.selectedProvince}"
required="true">
<p:ajax listener="#{bean1.actionHandleChangeProvince}" />
<f:selectItems value="#{bean1.provinceList}" />
</hm:selectOneMenu>
</h:panelGrid>
<h:panelGrid>
<hm:commandButton value="save" rendered="#{bean1.renderSave}"
action="#{bean1.actionSaveAddress}" />
</h:panelGrid>
</p:tab>
</p:accordionPanel>
</h:form>
I've got a problem as described in the title.
Small description of the problem is as following:
I have button which is used to open dialog. Then, inside that dialog, there is button which opens another dialog on top of the first one. After clicking second button I want method from controller to be called but nothing happens. Value in h:outputText is read properly, so I guess it is not a problem with connection controller->view.
I'm using:
Spring web 3.1.2.RELEASE
JSF 2.2.10
Primefaces 5.1
Code:
beans.xml
<bean id="testController" class="test.TestController" />
TestController.java
public class TestController implements Serializable
{
private static final long serialVersionUID = 7028608421091861830L;
private String test;
public TestController()
{
test = "abc";
}
public void testMethod()
{
test = "cba";
}
public String getTest()
{
return test;
}
}
test.xhtml
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg1').show();" />
</h:panelGrid>
<p:dialog widgetVar="dlg1">
<h:outputText value="Resistance to PrimeFaces is futile!" />
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg2').show();" />
</h:panelGrid>
<p:dialog widgetVar="dlg2">
<h:outputText value="#{testController.test}" />
<p:commandButton value="Call method" type="button" actionListener="#{testController.testMethod}" />
</p:dialog>
</p:dialog>
What I tried:
adding appendToBody="true" to each p:dialog
changing from p:commandButton to p:button
changing from actionListener to action
but nothing helps.
I would be grateful for any help or advice of what can be the reason of not calling given method.
There are 3 problems.
You're nesting <p:dialog> components. This doesn't make sense. Separate them.
A <p:dialog> must have its own <h:form>, particularly when you explicitly use appendToBody="true" or appendTo="#(body)", otherwise nothing can be submitted because JavaScript would relocate the dialog out of its position in the HTML DOM tree to the end of body, causing it to not be sitting in a form anymore.
A <p:commandButton type="button"> acts as a "click" button, not as a submit button. Remove that attribute from submit buttons.
All in all, this is how it should look like:
<h:form>
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg1').show();" />
</h:panelGrid>
</h:form>
<p:dialog widgetVar="dlg1">
<h:form>
<h:outputText value="Resistance to PrimeFaces is futile!" />
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg2').show();" />
</h:panelGrid>
</h:form>
</p:dialog>
<p:dialog widgetVar="dlg2">
<h:form>
<h:outputText value="#{testController.test}" />
<p:commandButton value="Call method" actionListener="#{testController.testMethod}" />
</h:form>
</p:dialog>
OK. I guess I found a way to fix this problem.
It seems that the problem was:
type="button"
I deleted it from the list of attributes of each button and now it works even without h:form. Thanks for help.
Hello I am trying to implement some primefaces commandbuttons in a p:datatable. My need is almost identical to this post:
f:setPropertyActionListener not invoked
Basically I need to have a column of buttons in a , click on one button will pass the object of the current row to the bean, and a dialog will pop out, showing some information of the chosen object.
The following is the relevant code:
<f:view>
<body>
<h:form id="theForm">
<p:dataTable id="testFailures" value="#{testDetails.report.failures}" var="failure"
styleClass="baseTable">
<p:column id="requestColumn">
<f:facet name="header">
<h:outputText value="Request" id="requestHeaderText" />
</f:facet>
<p:commandButton value="Detail" update="requestDialog"
oncomplete="PF('dlg1').show();" type="button">
<f:setPropertyActionListener
target="#{testDetails.selectedFailure}" value="#{failure}" />
</p:commandButton>
<h:message for="requestDialog" />
<p:dialog id="requestDialog" header="Request Dialog"
widgetVar="dlg1" dynamic="true">
<h:outputText value="#{selectedFailure.request}" />
</p:dialog>
</p:column>
</p:dataTable>
</h:form>
<h:message for="theForm" />
<h:message for="responseDialog" />
<p:dialog id="responseDialog" header="Request Dialog"
widgetVar="dlg2" dynamic="true">
<h:form>
<h:outputText value="#{selectedFailure.request}" />
</h:form>
</p:dialog>
</body>
</f:view>
I tried to put the dialog in different positions (see my "dlg1" and "dlg2"). But neither works. No dialog showing. does not show anything either. And I don't see any error message in the browser's console window. (I think there is a exclamation warning).
I have tried debug mode, and set method for the property "selectedFailure" is not called.
Try to remove type="button" from your commandButton and it should work. Also dialogs should not be placed inside dataTables so the position of "dlg2" is more correct.
I want to change my ActionListener of commandButton depending on the icon selected in advance:
<p:dialog id="dialog" header="Add Memo" widgetVar="dialogMemo" resizable="false" >
<h:form>
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="commentInput" value="Comment:" />
<p:inputTextarea id="commentInput" value="#{dashboardBean.getCurrentComment()}" rows="6" cols="25" label="commentInput"/>
<p:watermark for="commentInput" value="Enter your memo..."/>
<h:outputLabel for="selectShare" value="Share Memo: " />
<p:selectBooleanCheckbox id="selectShare" />
<h:outputLabel for="choosePriority" value="Priority:" />
<p:selectOneMenu id="choosePriority" value="#{dashboardBean.currentPriority}" label="choosePriority">
<f:selectItem itemLabel="Low Priority" itemValue="1" />
<f:selectItem itemLabel="Medium Priority" itemValue="2" />
<f:selectItem itemLabel="High Priority" itemValue="3" />
</p:selectOneMenu>
<p:commandButton id="submitDialog" icon="ui-icon-check" value="Confirm" ajax='false' type="submit" action="#{dashboardBean.getLastMemo()}"/>
<p:commandButton icon="ui-icon-close" onclick="dialogMemo.hide();" value="Cancel"/>
</h:panelGrid>
</h:form>
</p:dialog>
<p:layout fullPage="true">
<p:layoutUnit id="leftPanel" position="west" size="250" header="My Memos" resizable="false" closable="false" collapsible="false">
<h:form id="form">
<p:commandButton id="addMemo" icon="ui-icon-plus" onclick="dialogMemo.show();" type="submit" action="#{dashboardBean.getEditControl}"/>
<p:dashboard id="dashboardId" model="#{dashboardBean.model}" binding="#{dashboardBean.dashboard}">
</p:dashboard>
</h:form>
</p:layoutUnit>
</h:body>
When i click to command button (id="addMemo"), i want to change actionListener to commandButton(id="submitDialog").
I try that with:
public void getEditControl()
{
UIViewRoot view = _context.getViewRoot();
CommandButton button = (CommandButton) view.findComponent("submitDialog");
System.out.println("I am ID ==== [ " + button.getId() +" ]");
}
But 'button.getId()' does't work.
But 'button.getId()' does't work.
I gather that this is because the button is actually null and therefore the attempt to invoke the getId() method threw a NullPointerException? It's surprising that you stated the problem like that, "button.getId() doesn't work" instead of like "view.findComponent() returned null" (which has in turn the pretty obvious consequence that any attempt to access it would throw NullPointerException). If you had indeed no clue why it threw NullPointerException, then I strongly recommend to take a JSF pause and learn basic Java first.
Coming back to the concrete problem, the findComponent will return null when the client ID submitDialog doesn't exist in the component tree. Indeed, you have it inside a <h:form> which is a NamingContainer component. The button's client ID is more likely formId:submitDialog where formId is the ID of the button's parent form which you have to assign yet. An easy way to find out it is checking the ID of the generated HTML representation of the button.
See also this related question: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar" Just substitute "ajax" in the answer with findComponent.
I am not sure that the way you do this is the right way.
If you want to get component instance better way to do this will be not get it by id but add
<p:commandButton id="submitDialog" icon="ui-icon-check"
value="Confirm" ajax='false' type="submit"
action="#{dashboardBean.getLastMemo()}" binding="#{dashboardBean.component}" />
and that way the property in the bean will always have the component instance that you need.
Note that the scope of bean where you put component binding should be view to avoid side affects.
I have a field that has a required attribute. When I press the Accept button to save some data without entering any value in the field, an error message is displayed. So far so good.
But, if right after that I decide to click on the Cancel button, that error message overrides the confirmation message that is supposed to be displayed inside a <p:dialog/> element.
NOTE: If instead I use the <p:confirmDialog/> component, there seems to be no problem because, I guess, it uses a message="" attribute, no the <p:messages/> tag.
XHTML
<p:dialog>
<p:outputPanel>
<h:form>
<h:outputText value="Field:"/>
<p:inputText id="field" value="" type="text" required="true" requiredMessage="You must complete the field" />
<p:growl id="messages" showDetail="true"/>
<p:commandButton id="dialogCancel" value="Cancel" oncomplete="confirmCancelDialog.show();" actionListener="#{controller.addCloseWarn}" />
</h:form>
</p:outputPanel>
</p:dialog>
<h:form>
<p:dialog id="confirmCancelDialog" header="Warning!" widgetVar="confirmCancelDialog" modal="true" >
<p:messages id="closeMessage" showDetail="true" autoUpdate="true" />
<p:commandButton id="confirm" value="Accept" onclick="..." />
<p:commandButton id="decline" value="Cancel" onclick="..." />
</p:dialog>
</h:form>
Bean controller
public void addCloseWarn(ActionEvent actionEvent) {
FacesContext.getCurrentInstance().addMessage("closeMessage", new FacesMessage(FacesMessage.SEVERITY_WARN, null,
"Are you sure you want to leave the page?"));
}
Problem with Cancel button is that your form is submitted and validation is executed. You can add process="#this" attribute to commandButton, so other parts of form will not be processed and your addCloseWarn method will be executed.
I would also add that this is probably not standard use of message tag. It is used to show errors, warning and successful messages, not confirmation questions. So use confirmDialog or use standard dialog with just ordinary text and OK - Cancel buttons.