JSF - Unhide jsf component when clicking another component - jsf

I'm trying to have a button that brings up an upload dialog.
The way i'm trying to achieve this is similar to this:
<h:outputText value="Click Me" id="testit">
<a4j:support reRender="hideme" event="onclick" action="#{actions.switchTestRendered}"/>
</h:outputText>
<h:outputText id="hideme" value="back" rendered="#{actions.testRendered}"/>
With code in the backing bean:
private boolean testRendered = false;
public String switchTestRendered(){
setTestRendered(!isTestRendered());
System.out.println("Current Status:"+isTestRendered());
return "success";
}
public void setTestRendered(boolean testRendered) {
this.testRendered = testRendered;
}
public boolean isTestRendered() {
return testRendered;
}
When I press the 'click me' label I can see that the switchTestRendered is run but the 'hideme' component does not reveal.
Any suggestions?
Thanks!

Got it.
I should have reRendered the parent of the element which I'm trying to hide/show.
In other words:
<a4j:support reRender="hideme" event="onclick" action="#{actions.switchTestRendered}"/>
should be:
<a4j:support reRender="father_of_hideme" event="onclick" action="#{actions.switchTestRendered}"/>
Thanks!
Ben.

From the code it can only be seen that after 'Click me' the 'hide' component renderer is not updating. You have to find out why

Related

JSF inputSwitch with confirmDialog

I have a inputSwitch that need to show a dialog to confirm or not the operation. The dialog should show a variable message if i put it on or off.
I do the next thing but the problem is when i push no and i toggle the switch to let in then original state it call the ajax event again and open the dialog again. How can i lauch the event only when i click and not when i call the .toggle function?
<p:outputLabel for="activa"
value="#{bundleBean.getValue('activa')}" />
<p:inputSwitch id="activa"
value="#{gestionBean.domainEntity.activa}" onLabel="Si"
offLabel="No"
widgetVar="switch#{gestionBean.domainEntity.id}">
<p:ajax event="change" update="test" oncomplete="PF('dialog#{gestionBean.domainEntity.id}').show()"></p:ajax>
</p:inputSwitch>
<div>
<p:confirmDialog id="test"
widgetVar="dialog#{gestionBean.domainEntity.id}"
styleClass="content-confirmation-dialog"
message="#{gestionBean.mensajeDialogoActiva(gestionBean.domainEntity.activa)}"
header="#{bundleBean.getValue('confirmacion')}" closable="false">
<p:commandButton value="Si"
styleClass="boton rounded-button ui-button-danger float-right ui-confirmdialog-yes" immediate="true"
onclick="PF('dialog#{gestionBean.domainEntity.id}').hide()" />
<!-- action="#{gestionBean.cambiarEstado(gestionBean.domainEntity)}" -->
<p:commandButton value="No" styleClass="boton rounded-button ui-button ui-confirmdialog-no"
immediate="true"
update="activa"
onclick="PF('switch#{gestionBean.domainEntity.id}').toggle(); PF('dialog#{gestionBean.domainEntity.id}').hide()" />
</p:confirmDialog>
You can update the form, instead of the switch, when you click the No button and the dialog will not be shown.
<p:commandButton update="#from">
An alternative approach to solve this problem is to do away with the p:confirmDialog and instead have the change event on the p:inputSwitch / p:toggleSwitch trigger a click event on a hidden commandButton. For example:
<p:inputSwitch id="toggle" value="#{toggleSwitchController.toggleOn}" >
<p:ajax oncomplete="PF('hidnBtn').getJQ().click();"/>
</p:inputSwitch>
<p:commandButton id="hiddenBtn" widgetVar="hidnBtn"
action="#{toggleSwitchController.toggleChanged}"
style="visibility: hidden;">
<p:ajax event="dialogReturn" update=":frm1:growl toggle"
listener="#{toggleSwitchController.handleReturn}" />
</p:commandButton>
The action that the hidden p:commandButton calls can test the value of the toggle and if set to true/yes use PrimeFace's dialog framework to show a confirmation dialog. The dialog can return a boolean, which can be tested in the handleReturn function.
public void toggleChanged() {
if (toggleOn) {
Map<String, Object> options = new HashMap<>();
options.put("resizable", false);
options.put("draggable", false);
options.put("closable", false);
options.put("modal", true);
PrimeFaces.current().dialog().openDynamic("/pages/pleaseConfirm", options, null);
}
}
public void handleReturn(SelectEvent<Boolean> event) {
boolean confirmed = event.getObject();
if (confirmed) {
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "confirmed", null));
} else {
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "not confirmed", null));
toggleOn = false;
}
}
You could make the "pleaseConfirm" dialog more reusable by providing parameters for the text strings through the openDynamic() call.
The problem can be solved by adding a listener to the ajax change event, making the listener return the current value of the toggle and testing the returned value in the onComplete clause before showing the dialog.
<p:inputSwitch id="activa"
value="#{toggleSwitchController.toggleOn}"
onLabel="Si" offLabel="No"
widgetVar="toggleWidget" >
<p:ajax event="change"
listener="#{toggleSwitchController.testToggle}"
update="test"
oncomplete="if ( args.toggleValue == 1 ) { PF('dlgWidget').show();}" />
</p:inputSwitch>
The listener can be very simple:
public void testToggle() {
PrimeFaces.current().ajax().addCallbackParam("toggleValue", (toggleOn ? 1 : 0));
}

Displaying Primefaces confirmDialog from Backing Bean

I have a Primefaces datatable and when the user clicks on a row, I display the data to edit in a form.
If the user changes the data in the form and clicks on any other row i.e if there is dirty data, I need to popup a confirmDialog to show if the user wants to save the data / discard it.
The confirmDialog does not display when I try to execute it from backing bean.
Any help is appreciated!
I have implemented it as follows:
.xhtml:
<p:dataTable id="tsTableId" value="#{transactionSetBean.studentList}" var="tsRow"
selectionMode="single" selection="#{transactionSetBean.selectedEditRec}" rowKey="#{tsRow.id}" scrollRows="10">
<p:ajax event="rowSelect" listener="#{transactionSetBean.onRowSelect}" update=":transactionSetsForm:tsEntryFrmId">
</p:ajax>
..
</p:dataTable>
ConfirmDialog:
<p:confirmDialog widgetVar="dataChangeDlg" message="Save changes Or Cancel">
<p:commandButton value="Save Changes" oncomplete="PF('dataChangeDlg').hide();"
update=":transactionSetsForm:messages :transactionSetsForm:tsEntryFrmId"
action="#{transactionSetBean.updateRecord}" />
<p:commandButton value="Cancel" onclick="PF('dataChangeDlg').hide();"
</p:confirmDialog>
Backing Bean:
public void onRowSelect(SelectEvent event)
{
String actionName = ON_ROW_SELECT;
try
{
Student selectedObj = (Student)event.getObject();
if (selectedObj != null)
{
selectedEditRec = selectedObj;
}
// if data is changed then show the dataChange dialog
if (isDataChanged())
{
setShowDataChangedDialog(true);
RequestContext context = RequestContext.getCurrentInstance();
// execute javascript and show dialog
context.execute("PF('dataChangeDlg').show();");
}
}
catch (Exception e)
{
handleException(e);
}
}
RequestContext.getCurrentInstance().execute("PF('dataChangeDlg').show();");
<p:ajax event="rowSelect" listener="#{transactionSetBean.onRowSelect}" update=":transactionSetsForm:tsEntryFrmId">
works for me.
There must be another error. maybe isDataChanged is false, wrong component ids in update or something.
With PrimeFaces >= 6.2
PrimeFaces.current().executeScript("PF('dataChangeDlg').show()");

How to call popup based on a condition in richfaces?

I am trying to understand popup menu in richfaces. I am trying to do the following: I have a textbox and a button. I write some text into the textbox, and if the value of the text written is "popup", i want to call the popup menu. Here is the code:
<h:form>
<h:inputText value="#{popupCall.text}"></h:inputText>
<a4j:commandButton action="#{popupCall.showpopup()}" onclick="if (#{popupCall.showpopup()}) #{rich:component('popup')}.show();">
</a4j:commandButton>
</h:form>
<rich:popupPanel id="popup" modal="false" autosized="true" resizeable="false">
<f:facet name="header">
<h:outputText value="Popup panel" />
</f:facet>
<f:facet name="controls">
<h:outputLink value="#" onclick="#{rich:component('popup')}.hide();
return false;">
X
</h:outputLink>
</f:facet>
</rich:popupPanel>
and the bean:
#ManagedBean (name="popupCall")
#VievScoped
public class PopupCall {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public PopupCall() {
}
public void checkText(){
if(text.equals("popup")){
//CALL POPUP MENU
}
}
public boolean showpopup(){
if(text!=null && text.equals("popup"))
return true;
else
return false;
}
}
If i don't put "if(#{popupCall.showpopup()})" inside the onclick method it always calls when button is pressed but now even though the showpopup()method returns true no popup is shown. Also, inside the showpopup() method, if i just write return true, the if statement inside onclick works but now it does not.
Can anyone help me with this? Thanks
For your case you want to use oncomplete instead of onclick since you want to show <rich:popupPanel> after executing some business logic. When I changed
onclick="if (#{popupCall.showpopup()}) #{rich:component('popup')}.show();"
to
oncomplete="if (#{popupCall.showpopup()}) #{rich:component('popup')}.show();"
The pop up showed up. Also be careful with
action="#{popupCall.showpopup()}"
Remember that action needs String (or null) for navigation but
showpopup() is returning a boolean so you might want to fix that.
I found these links to be helpful check them out (for the first link, I liked the one with the highest vote).
Primefaces onclick and onsuccess differences
EL expression inside p:commandButton onclick does not update/re-render on ajax request?

Several select menus with a4j support, only the last one works

I have several forms like this on the same page:
<h:form>
<h:selectOneMenu value="#{collectionBean.selectedCollection}">
<f:selectItems value="#{collectionBean.collectionItems}" />
<a4j:support event="onchange" />
</h:selectOneMenu>
<a4j:commandButton value="Add" action="#{collectionBean.addToCollection(_resource)}" >
</a4j:commandButton>
</h:form>
Here is my Bean:
#Name("collectionBean")
#Scope(ScopeType.SESSION)
public class CollectionBean {
private String selectedCollection;
public String getSelectedCollection() {
return selectedCollection;
}
public void setSelectedCollection(String collectionName) {
selectedCollection = collectionName;
}
public List<SelectItem> getCollectionItems() {
...
}
public void addToCollection(Resource res) {
...
}
}
A form is associated to a resource _resource, its goal is to let the user add the resource to a collection he choses.
The problem is that only the last form on the page works: when changing the selection in the other forms, the setSelectedCollection method is never called.
Do you have an idea of what could be wrong?
As said here and in the comments, it does not make sense to bind several components to the same bean property. So I used a Map in the backing bean, with the resource id as a key.
<h:selectOneMenu value="#{collectionBean.selections[_resource.id]}">
<f:selectItems value="#{collectionBean.collectionItems}" />
<a4j:support event="onchange" />
</h:selectOneMenu>
Still, it did not fix the main problem: only the last form on the page worked. For all the other forms, the method getSelections was never called.
Then, instead of using several forms (one form for each select menu), I used a single englobing form. I don't know why, but it worked...

Richfaces inputText onBlur and commandButton onClick

I have a page with two text fields and a commandButton, in one of the text field onBlur i'm calling onBlur() method in the bean and in the commandButton i'm calling onClick() method in the bean, every thing works fine except when i click the commandButton if the focus is on the text box with onBlur then only the onBlur method been called not both. I've attached the xhtml file and bean.
XHTML Code
<h:inputText id="service" value="#{onBlurTestBean.service}">
<a4j:support status="test" event="onblur"
action="#{onBlurTestBean.onBlur}" reRender="category" />
</h:inputText>
<a4j:htmlCommandLink id="submit" action="#{onBlurTestBean.onClick}"
ajaxSingle="true" value="Click!" />
Bean
public class OnBlurTestBean {
private String service;
private String category;
public void initialize(){
}
public void onBlur(){
log("onBlur");
try{
Thread.sleep(1000);
}catch(Exception e){
}
}
public void onClick(){
log("OnClick");
}
public void log(String msg){
System.out.println(msg);
}
}
The specified example in question works OK (both methods are invoked onBlur and onClick).
In you case it seems you have a4j:status component which blocks user clicks (for example covers the layout with invisible div).
To verify my assumption, try the following (status attribute removed, a4j:region added):
<a4j:region>
<h:inputText id="service" value="#{onBlurTestBean.service}">
<a4j:support event="onblur"
action="#{onBlurTestBean.onBlur}" reRender="category" />
</h:inputText>
</a4j:region>
<a4j:htmlCommandLink id="submit" action="#{onBlurTestBean.onClick}"
ajaxSingle="true" value="Click!" />

Resources