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?
Related
I have a primefaces datatable with a <p:commandLink> in each row. The user clicks it to see a different page with details about the record he selected. It was working fine until I add a filteredValue in my datatable. I need this attribute (filteredValue) in order to correctly filter and sort my datatable, as shown in this question.
But after adding this attribute, my commandLink stops working. How can I make it work with the attribute?
Here's my datatable:
<p:dataTable var="prot" value="#{myBean.listaProtocolos}" rows="15" filteredValue="#{myBean.listaProtocolosFiltrados}" sortBy="#{prot.dataEntradaArea}" sortFunction="#{myBean.sortXMLDatas}" sortOrder="descending" paginator="true" style="font-size: 0.9em;" paginatorPosition="bottom">
<p:column filterBy="${prot.nrProtocolo}" filterMatchMode="contains" width="8%" style="text-align:center">
<f:facet name="header">ID</f:facet>
<p:commandLink action="#{myBean.verDetalhesProtocolo}" process="#this messages" update="#this messages">
<h:outputText value="#{prot.nrProtocolo}" style="text-decoration: underline;"/>
<f:setPropertyActionListener target="#{myBean.nrProtocolo}" value="#{prot.nrProtocolo}" />
</p:commandLink>
</p:column>
(etc)
and the relevant pieces of myBean:
public void verDetalhesProtocolo() {
for(ProtocoloMY pro : this.listaProtocolos){
if(pro.getNrProtocolo().trim().equalsIgnoreCase(this.nrProtocolo.trim())) {
this.protocolo = new ProtocoloMY(pro);
break;
}
}
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.getExternalContext().redirect("detalhes_protocolo_processo.xhtml");
//(This method isn't even called when I add the attribute filteredValue to my datatable)
public String getNrProtocolo() {
return nrProtocolo;
}
public void setNrProtocolo(String nrProtocolo) {
this.nrProtocolo = nrProtocolo;
}
public List<ProtocoloMY> getListaProtocolos() {
return listaProtocolos;
}
public List<ProtocoloMY> getListaProtocolosFiltrados() {
return listaProtocolosFiltrados;
}
public void setListaProtocolosFiltrados(List<ProtocoloMY> listaProtocolosFiltrados) {
this.listaProtocolosFiltrados = listaProtocolosFiltrados;
}
public void setListaProtocolos(List<ProtocoloMY> listaProtocolos) {
this.listaProtocolos = listaProtocolos;
}
And I almost forgot to say: There's some network traffic happening when I click the link, but nothing is shown in my backend console and the method in my bean isn't called.
I'm running primefaces v6.0.
For PrimeFaces to be able to track which row by its unique id you need to add the attribute rowKey="#{row.id}" to your p:datatable using whatever value in your row POJO that makes it unique.
JSF 2.0, Mojarra 2.0.1, PrimeFaces 3.4.1
Here is a p:inputText component which is expected to call a backing bean method when the enter key is pressed.
<p:inputText id="commentInput" rendered="#{status.haveComment}"
value="#{statusBean.newComment}"
onkeypress="if (event.keyCode == 13) { onchange(); return false; }">
<f:ajax event="change" listener="#{statusBean.test}" />
</p:inputText>
While backing bean has the method of:
public void test(AjaxBehaviorEvent event) {
System.out.println("Pressed enter!");
}
It's calling method when enter key is pressed but it has more than this; unexpected behaviour case:
--Click input text
----Type some letters
------Click somewhere else in the page
--------CONSOLE: Pressed enter!
I think ajax event=change detects a change somehow and calls the method. How to convert this p:inputText component into a proper comment taker component like Facebook or others has?
This is the way how onchange event works in HTML. It is happening when text in input element is changed, but is fired when component loses focus (in your case that is the moment when you click somewhere else in the page).
You can define p:remoteCommand for test method and just write:
<p:remoteCommand name="test" actionListener="#{statusBean.test}"/>
<p:inputText id="commentInput" rendered="#{status.haveComment}"
value="#{statusBean.newComment}"
onkeypress="if (event.keyCode == 13) { test(); return false; }"/>
and in backing bean:
public void test() {
System.out.println("Pressed enter!");
}
With newer PrimeFaces versions (5+ at least) you can use p:defaultCommand instead of scripting. Though you can't use p:remoteCommand then, because p:defaultCommand needs something clickable.
<p:inputText id="input" />
<p:defaultCommand target="submit" />
<!--you can show the button to allow the user to click too, or hide it with display: none-->
<p:commandButton id="submit" style="display: none;" process="input" />
By default p:defaultCommand applies to the whole form. You could limit it with the scope attribute.
I want to disable the button in case there is no value in the input text something like this:
<p:autoComplete id="ac" value="#{bean.selectedNet}"
completeMethod="#{bean.complete}"
minQueryLength="0" size="3">
<p:ajax event="itemSelect" update="genButton" listener="#{bean.handleNetChange}"/>
<p:ajax process="#this" update="genButton" />
</p:autoComplete>
<p:selectManyCheckbox id="en" layout="pageDirection" value="#{bean.selectedEntity}">
<f:selectItems value="#{bean.entityList}"/>
<p:ajax update="genButton" listener="#{bean.handleNetChange}"/>
</p:selectManyCheckbox>
<p:commandButton id="genButton" value="Generate Files"
widgetVar="startButton1"
disabled="#{bean.disableButton}"
actionListener="#{bean.generate}"
onclick="PrimeFaces.monitorDownload(showStatus, hideStatus)"
ajax="false">
<p:fileDownload value="#{bean.streamedContent}"/>
</p:commandButton>
Methods:
public void handleNetChange() {
if (!StringUtils.isBlank(selectedNet) && !selectedEntity.isEmpty()) {
disableButton = false;
} else {
disableButton = true;
}
}
public List<String> complete(String query) {
List<String> results = new ArrayList<String>();
if (StringUtils.isBlank(query)) {
selectedNet = query;
disableButton = true;
} else {
....
}
return results;
}
While the itemSelect event is working perfectly the second one is not. I can see the call to the complete method in the bean but the button is not updated
Any advise?
Seems like you can't force update just with <p:ajax process="#this" update="genButton" />.
I would try to update the button directly from the bean.
Since you are using primefaces you can use RequestContext; try to add this line to your complete method :
RequestContext.getCurrentInstance().addPartialUpdateTarget("genButton");
If you don't use prependId="false" on your wrapping form, you might need to specify the full path to the button e.g.:
RequestContext.getCurrentInstance().addPartialUpdateTarget("fooForm:genButton");
If you want to use disabled, do not use rendered property on command button.
<p:commandButton id="buttonId"
actionListener="#{controller.function}"
value="#{controller.label}"
disabled="#{controller.disableButton}" rendered="#{controller.renderButton}" />
After removing rendered, button gets disabled without any issues.
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!" />
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