Action of command button not invoked if I use ajax - ajax

I have the following problem:
I have a button that should invoke a method, but the page should't get refreshed (I display a dialog based on bootstrap modal after clicking on the button and it vanishes otherwise). Therefore I use ajax to say that nothing should get rendered after clicking on the button.
I already used applied it before and it worked. But in the recent version of my code the method isn't invoked anymore as long as I use ajax. If I remove the ajax part the method is invoked as it should be, but the page gets refreshed and I don't want that.
My code:
<h:form>
<ui:fragment rendered="#{bean.condition1}">
<ui:include src="facelet1.xhtml" />
</ui:fragment>
<ui:fragment rendered="#{bean.condition2}">
<ui:include src="facelet2.xhtml" />
</ui:fragment>
<h:commandButton value="Save" action="bean.method">
<f:ajax execute="#form" render="#none"/>
</h:commandButton>
<h:form>
Before I had it like this and it worked:
<h:form>
<ui:include src="bean.faceletPath" />
<h:commandButton value="Save" action="bean.method">
<f:ajax execute="#form" render="#none"/>
</h:commandButton>
<h:form>
Thanks all,
/metalhamster
Edit:
facelet1.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<ui:composition>
<h:panelGrid columns="2">
<h:outputText value="Name:">
<h:inputText value="bean.name">
<h:outputText value="Value:">
<h:inputText value="bean.value">
</h:panelGrid>
</ui:composition>
</h:body>
</html>
facelet2.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<ui:composition>
<h:panelGrid columns="2">
<h:outputText value="Name:">
<h:inputText value="bean.name">
<h:outputText value="Text:">
<h:inputText value="bean.text">
</h:panelGrid>
</ui:composition>
</h:body>
</html>

Related

Dynamically populate options in a selectOneMenu by <ui:repeat>

I'm trying to populate some dropdown menus in primefaces with content depending on some choices from other selections in the GUI. This is a simplified example of what I'm trying to do:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core" >
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:form>
<c:set var="options" value="#{['1','2','3']}" />
<c:set var="currentValue" value="#{3}" />
<h:outputText value="${options}" />
<ui:repeat var="r" value="#{options}">
<h:outputText value="#{r}" />
</ui:repeat>
<c:set var="currentValue" value="#{currentValue}" />
<p:selectOneMenu id="selectValue"
value="${currentValue}"
class="pFieldSet_Template_Input200 r10">
<p:ajax event="change" />
<ui:repeat var="r" value="#{options}">
<f:selectItem itemLabel="Choice #{r} (20180101)" itemValue="#{r}" />
</ui:repeat>
</p:selectOneMenu>
</h:form>
</h:body>
</html>
When I visit the page it shows [1, 2, 3]123 and an empty selectOneMenu. I would have expected the selectOneMenu to contain the choices as well. The iteration obivously works in the above case so I don't know why it doesn't show the options in the menu. What am I doing wrong?
The <ui:repeat> is an UI component while <f:selectItem> is a taghandler (like JSTL). Taghandlers runs during view build time before UI components which runs during view render time. So at the moment the <ui:repeat> runs, there is no means of a <f:selectItem>.
A <c:forEach>, which is also a tag handler, would work:
<p:selectOneMenu id="selectValue"
value="${currentValue}"
class="pFieldSet_Template_Input200 r10">
<p:ajax event="change" />
<c:forEach items="#{options}" var="r">
<f:selectItem itemLabel="Choice #{r} (20180101)" itemValue="#{r}" />
</c:forEach>
</p:selectOneMenu>

JSF client behavior set on composite component is triggered twice in some conditions

Let's take the following example:
The composite component is as follows:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<!-- INTERFACE -->
<cc:interface>
<cc:clientBehavior name="click" targets="button" event="click"/>
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<span id="#{cc.clientId}">
<h:commandButton id="button" value="Press me">
<f:ajax event="click" listener="#{bean.helloFromComposite()}"/>
</h:commandButton>
</span>
</cc:implementation>
</html>
And the using page is as follows:
<h:form id="form">
<my:button id="my-button">
<f:ajax event="click" listener="#{bean.HelloFromPage()}"/>
</my:button>
</h:form>
Then, when I click on the button the bean logs:
Hello from composite
Hello from page
Hello from composite
Hello from page
Reproduced on Glassfish 4.1.1 with Omnifaces 2.5.1 and Primefaces 6.0.
If I change my using page as follows, then the problem disappears:
<h:form id="form">
<my:button id="my-button">
<f:ajax event="click" listener="#{bean.HelloFromPage()}" execute="#none"/>
</my:button>
</h:form>
When I click on the button the bean now logs:
Hello from composite
Hello from page
I have two questions:
Is it a known behavior?
Is the sequence "Hello from composite", "Hello from page" by design? It's fine by me, as in my opinion the ajax behavior inside the composite is more specific (and should be executed first) than the ajax behavior specified in the using page.
Edit:
I can reproduce the problem in a very simple way, as follows:
<h:form>
<h:commandButton>
<f:ajax event="click" listener="#{bean.helloOne()}"/>
<f:ajax event="click" listener="#{bean.helloTwo()}"/>
</h:commandButton>
</h:form>
Solved by adding an execute #none attribute in the second AJAX call:
<h:form>
<h:commandButton>
<f:ajax event="click" listener="#{bean.helloOne()}"/>
<f:ajax event="click" listener="#{bean.helloTwo()}" execute="#none"/>
</h:commandButton>
</h:form>
Could there be a confusion between the button is 'clicked' and the button is 'executed'?

Primefaces 4.0: p:ajax partialSubmit inside compositeComponent

I'm trying to create a simple composite component based on JSF h:panelGroup:
filter.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:p="http://primefaces.org/ui">
<composite:interface>
</composite:interface>
<composite:implementation>
<span>Расширенный фильтр</span>
<h:panelGroup id="#{cc.clientId}" class="filter"
style="background:white">
<composite:insertChildren></composite:insertChildren>
</h:panelGroup>
</composite:implementation>
and place a component that has to be partially submitted inside it.
<h:form id="issueFilterForm" prependId="false">
<c3:filter>
<h:panelGrid columns="2">
<h:outputText value="Продукт:" />
<p:selectOneMenu value="#{issueFilterBean.selectedProd}"
filter="true" filterMatchMode="contains">
<f:selectItem itemLabel="Выберите продукт" itemValue="-1" />
<f:selectItems value="#{issueFilterBean.products}" var="proj"
itemLabel="#{proj.name}" itemValue="#{proj.id}" />
<p:ajax event="change" process="#this" update="#form"
partialSubmit="true" />
</p:selectOneMenu>
</h:panelGrid>
</c3:filter>
</h:form>
The p:ajax call is fired, but no partial submission takes place. If i remove enclosing c3:filter, the submission works well.
How can I make this not skipping partial submission?

what mean this strange httpError?

I use JSF in implementation MyFaces 2.0
I have 2 jsf pages login.xhtml and register.xhtml.
login.xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>System CollDoc</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="3" >
<h:outputLabel for="username" value="Login:"/>
<h:inputText id="username" value="#{userManager.userName}" required="true" requiredMessage="#{msg.requiredLoginMsg}">
<f:ajax event="blur" render="usernameMessage"/>
</h:inputText>
<h:message id="usernameMessage" for="username" />
<h:outputLabel for="password" value="#{msg.password}"/>
<h:inputSecret id="password" value="#{userManager.password}" required="true" requiredMessage="#{msg.requiredPassMsg}">
<f:ajax event="blur" render="passwordMessage" />
</h:inputSecret>
<h:message id="passwordMessage" for="password" />
<h:commandButton value="#{msg.login}" action="#{userManager.login}"/>
</h:panelGrid>
</h:form>
<h:messages id="messages" globalOnly="true"/>
<h:link value="#{msg.register}" outcome="register.xhtml"/>
</h:body>
</html>
register.xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>System CollDoc</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="3" >
<h:outputLabel for="login" value="Login:"/>
<h:inputText id="login" value="#{registerBacking.registerLog}" required="true" requiredMessage="#{msg.requiredLoginMsg}">
<f:ajax event="blur" render="usernameMessage"/>
</h:inputText>
<h:message id="usernameMessage" for="login"/>
<h:outputLabel for="pass" value="#{msg.password}"/>
<h:inputSecret id="pass" value="#{registerBacking.registerPass}" required="true" requiredMessage="#{msg.requiredPassMsg}">
<f:ajax event="blur" render="passwordMessage" />
</h:inputSecret>
<h:message id="passwordMessage" for="pass" />
<h:commandButton value="#{msg.login}" action="#{registerBacking.register}"/>
</h:panelGrid>
</h:form>
<h:link class="link" value="#{msg.returnTxt}" outcome="/pages/login.xhtml"/>
</h:body>
</html>
I run my application and first i see login.xhtml page. I click at first inputText "username" and next at inputSecret "password" (validation for "username" is run by ajax request on blur), next at link to register page (validation for "password" is run by ajax request on blur) and i get dialog with error:
Error Message: Request failed with status 0 and reason
--------------------------------------------------------
Calling function:myfaces._impl.xhrCore._AjaxRequest
Error Name: httpError
--------------------------------------------------------
Note, this message is only sent, because project stage is development and no other error listeners are registered.
I click "ok" button and i get register.xhtml page in my web browser. At register page situation is same: I click at inputText "login", next at inputSecret "pass" (validation for "login" is run by ajax request on blur) next i click link back to login page or button to run business logic (validation for "pass" is run by ajax request on blur) and i get same error
What does error mean? What is wrong?
Edit:
I run my application again now and i don't get any error message. Why do I get this error only sometimes?
It is a result of mixing AJAX and 'regular' requests. When the button is hit two requests run in parallel: one - AJAX request for validation on blur, and second - form submit of commandButton.
JSF detects it when AJAX request is completed and reports it as a potential problem (e.g. if both requests did some actions on server side which were inter-dependent).
Probably simplest way to fix it in your case is to make the button do AJAX request as well (add f:ajax to the h:commandButton), then JSF will put the request to the queue what will guarantee that requests are made serially but not concurrently.

<f:ajax> contains an unknown id when switching from PrimeFaces to jsf/html

this is my 1st question here :)
My code is as follows:
<?xml version="1.0"?>
<f:view xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
>
<h:head />
<h:body>
<h:form id="filterForm">
<h:outputStylesheet library="css" name="main.css" />
<div id="filterPane">
<h:panelGroup rendered="#{not empty filters.categories}">
<div class="filter">
<div class="filterCategories" style="width: 100%;">
<h4>Kategorien</h4>
<p />
<h:selectManyCheckbox layout="pageDirection"
value="#{filters.selectedCategories}"
valueChangeListener="#{filters.categoryValueChanged}">
<f:selectItems value="#{filters.categories}" var="category"
itemLabel="#{category.displayName} (#{category.count})"
itemValue="#{category.name}" />
<f:ajax render="#form" />
</h:selectManyCheckbox>
</div>
</div>
</h:panelGroup>
</div>
</h:form>
</h:body>
</f:view>
I get the same error as some others before me here #stackoverflow - but none of the suggested solutions worked for me.:
<f:ajax> contains an unknown id 'A5539:filterForm:j_idt9' - cannot locate it in the context of the component j_idt9
Before my switch from <p:selectManyCheckbox to <h:selectManyCheckbox the code was working fine.
We need to change to <h:selectedManyCheckbox, because the PrimeFaces variant is not selectable for a non-JavaScript user. I need the form <h:form id="filterForm"> to be re-rendered as a consequence of my AJaX request via the <f:ajax> element.
Beside the initial <f:ajax render="#form" /> I unsuccessfully tried to reference the <h:form id="filterForm"> element with the following variants:
<f:ajax render=":filterForm" />
<f:ajax render=":#{component.parent.parent}" />
I also tried some more stupid ones.
Any hint, anybody!? :)

Resources