The response of my AJAX-request delivers the whole body, so every element/script gets reloaded. I cant figure out why. The only part which needs a reload is content.
I'm using JSF2.3 and Wildfly17.
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
>
<h:head>
</h:head>
<h:body>
<h:form>
<f:ajax render="content">
<h:commandLink value="#{msg['menu.1']}" action="#{page1.getLink()}"/>
<h:commandLink value="#{msg['menu.2']}" action="#{page2.getLink()}"/>
<h:commandLink value="#{msg['menu.3']}" action="#{page3.getLink()}"/>
</f:ajax>
<h:commandLink value="#{msg['menu.logout']}" action="#{homeBean.logOut()}"/>
</h:form>
<ui:insert id="content" name="content" >
<!--<ui:include src="/template/common/commonContent.xhtml" />-->
</ui:insert>
</h:body>
</html>
EDIT:
It looks like this:
EDIT2:
The response after pressing one of the commandLinks
<?xml version='1.0' encoding='UTF-8'?>
<partial-response><changes><update id="javax.faces.ViewRoot"><![CDATA[<html xmlns="http://www.w3.org/1999/xhtml"><head id="j_idt2"><script type="text/javascript" src="/bwa/javax.faces.resource/jsf.js.xhtml;jsessionid=2o_BGXk3sRokUbdd2ta2TO_Sl2u-pPduIiijrwtW.pcwer1819?ln=javax.faces"></script></head><body onload="startTime()">
<form id="j_idt4" name="j_idt4" method="post" action="/bwa/user/textSearch.xhtml;jsessionid=2o_BGXk3sRokUbdd2ta2TO_Sl2u-pPduIiijrwtW.pcwer1819" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_idt4" value="j_idt4" />
<a id="j_idt4:j_idt5" href="#" onclick="mojarra.ab(this,event,'action',0,'content');return false">Home</a><a id="j_idt4:j_idt6" href="#" onclick="mojarra.ab(this,event,'action',0,'content');return false">Quellcode durchsuchen</a><a id="j_idt4:j_idt7" href="#" onclick="mojarra.ab(this,event,'action',0,'content');return false">Top1500</a>Ausloggen
</form>
<h2>Suche in Quellcode</h2>
<br />
<form id="j_idt10" name="j_idt10" method="post" action="/bwa/user/textSearch.xhtml;jsessionid=2o_BGXk3sRokUbdd2ta2TO_Sl2u-pPduIiijrwtW.pcwer1819" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_idt10" value="j_idt10" />
<table>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td><input type="text" name="j_idt10:j_idt12" />
</td>
<td><input type="submit" name="j_idt10:j_idt14" value="Suchen" />
</td>
</tr>
</table>
</form></body>
</html>]]></update><update id="j_id1:javax.faces.ViewState:0"><![CDATA[2371578821549273726:500402066268747694]]></update></changes></partial-response>
Request-header:
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
Accept: */*
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Faces-Request: partial/ajax
Content-type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 304
Connection: keep-alive
Referer: http://localhost:8080/bwa/login.xhtml;jsessionid=2o_BGXk3sRokUbdd2ta2TO_Sl2u-pPduIiijrwtW.pcwer1819
Request-body
j_idt4=j_idt4&javax.faces.ViewState=2371578821549273726%3A500402066268747694&javax.faces.source=j_idt4%3Aj_idt6&javax.faces.partial.event=click&javax.faces.partial.execute=j_idt4%3Aj_idt6%20j_idt4%3Aj_idt6&javax.faces.partial.render=content&javax.faces.behavior.event=action&javax.faces.partial.ajax=true
The problem was that the action of the commandLinks returned a value and this overwrites the expected behavior with ajax. The solution is to set the a page variable with the url:
<h:form>
<f:ajax render="content">
<h:commandLink value="#{msg['menu.1']}" action="#{sessionData.setPage('/user/1.xhtml')}"/>
<h:commandLink value="#{msg['menu.2']}" action="#{sessionData.setPage('/user/2.xhtml')}"/>
<h:commandLink value="#{msg['menu.3']}" action="#{sessionData.setPage('/user/3.xhtml')}"/>
</f:ajax>
<h:commandLink value="#{msg['menu.logout']}" action="#{homeBean.logOut()}"/>
</h:form>
And later use this variable to load the page:
<h:panelGroup layout="block" id="content">
<ui:include src="#{sessionData.page}" />
</h:panelGroup>
I also replaced my <div> with <h:panelGroup layout="block"> because JSF isn't able to locate it and the changes were not rendered.
See also
How to ajax-refresh dynamic include content by navigation menu? (JSF SPA)
Is it possible to update non-JSF components (plain HTML) with JSF ajax?
Related
I have two drop-down menus in a form, on changing the value on the first menu the second menu is refreshed(AJAX) and then I can submit the form using a button which performs some action in a view scoped bean and on completion redirects to success page, am facing a problem which I can't figure out
that is, when I was using the <f:ajax> tag:
When I submit the form without changing the menus, the action is performed and I get redirected normally.
when I change the menus and click submit button the action is performed but the page is never redirected
when using the <p:ajax> tag it worked as expected, I've been searching for awhile now, I guess the problem is about requesting ajax but I can't figure the specific reason, this is a snippet from the page.
XHTML
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4">
<div class="form-group arabic">
<h:selectOneMenu id="governorates" required="true"
requiredMessage="#{msgBean.getRequired()}"
styleClass="btn btn-white dropdown-toggle" style="width:100%"
value="#{propertyBean.property.propertyDetails.governate}"
converter="#{governateConverter}">
<f:selectItem itemValue="#{null}" itemLabel="اختر المحافظة"
noSelectionOption="true" />
<f:selectItems value="#{dataBean.availableGovernates}"
var="governateObj" itemValue="#{governateObj}"
itemLabel="#{governateObj.name}"/>
<p:ajax listener="#{propertyBean.setValidCities}"
update="governorate_message cities" />
</h:selectOneMenu>
<h:message id="governorate_message" for="governorates"
infoClass="help-block" errorClass="help-block error" />
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4">
<div class="form-group arabic">
<h:selectOneMenu id="cities" required="true"
requiredMessage="#{msgBean.getRequired()}"
styleClass="btn btn-white dropdown-toggle" style="width:100%"
value="#{propertyBean.property.propertyDetails.city}"
converter="#{cityConverter}">
<f:selectItem itemValue="#{null}" itemLabel="اختر المدينة"
noSelectionOption="true" />
<f:selectItems value="#{propertyBean.validCities}"
var="cityObj" itemValue="#{cityObj}"
itemLabel="#{cityObj.name}"/>
<p:ajax update="cities" />
</h:selectOneMenu>
<h:message id="city_message" for="cities" infoClass="help-block"
errorClass="help-block error" />
</div>
</div>
<h:commandButton id="update" value="تعديل"
onclick="if( validate('submitForm')==true){ updateProperty();} else{ return false;}"
action="#{propertyBean.update}"
class="btn btn-green btn-lg arabic"
rendered="#{propertyBean.isNew == false}">
<f:param name="propertyId" value="#{propertyBean.property.id}">
</f:param>
</h:commandButton>
Java class
public String update() {
System.out.println("updating");
return navBean.redirectToSuccess();
}
using <f:ajax> tag
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4">
<div class="form-group arabic">
<h:selectOneMenu id="governorates" required="true"
requiredMessage="#{msgBean.getRequired()}"
styleClass="btn btn-white dropdown-toggle" style="width:100%"
value="#{propertyBean.property.propertyDetails.governate}"
converter="#{governateConverter}">
<f:selectItem itemValue="#{null}" itemLabel="اختر المحافظة"
noSelectionOption="true" />
<f:selectItems value="#{dataBean.availableGovernates}"
var="governateObj" itemValue="#{governateObj}"
itemLabel="#{governateObj.name}"/>
<f:ajax event="blur" listener="#{propertyBean.setValidCities}" render="governorate_message cities" />
</h:selectOneMenu>
<h:message id="governorate_message" for="governorates"
infoClass="help-block" errorClass="help-block error" />
</div>
</div>
the browser network shows the following when using f:ajax
request:
POST /Newgar_revamp/pages/add.xhtml HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 2207
Pragma: no-cache
Cache-Control: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://localhost:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryFE3725BjJXsA1xKf
Referer: http://localhost:8080/Newgar_revamp/pages/add.xhtml?propertyId=3
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6,ar;q=0.4
Cookie: JSESSIONID=B81FF21F23988CC8C98D84DA14B36F54
response:
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Location: http://localhost:8080/Newgar_revamp/pages/status/success.xhtml
Content-Length: 0
Date: Fri, 20 Nov 2015 21:24:32 GMT
but the browser never redirects to the success page
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.
I would like to ask why partial rendering for primefaces does not work. POST requests are keeping sent, but it does not rerender.
<?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:p="http://primefaces.org/ui">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<p:messages />
<h:form>
<table style="width: 100%">
<tr>
<td><p:outputLabel for="inp1" value="S1" /></td>
<td>
<p:inputText id="inp1" value="#{form.e.s1}">
<p:ajax process="inp1" update="msg1"
event="keyup" />
</p:inputText>
<p:watermark for="inp1" value="Wpisz S1" />
<p:message for="inp1" id="msg1" />
</td>
</tr>
<tr>
<td>Toolbox</td>
<td>
<p:selectBooleanCheckbox id="inpToolbox" value="#{form.toolbox}">
<p:ajax process="inpToolbox" update="toolboxOptions" />
</p:selectBooleanCheckbox><br />
<p:panel id="toolboxOptions" rendered="#{form.toolbox}">
Name: <p:inputText value="#{form.toolboxDescription}" /><br />
Number: <p:inputText value="#{form.toolboxNr}" /><br />
</p:panel>
</td>
</tr>
</table>
<p:commandButton action="#{form.save}" ajax="false"
value="Save" />
</h:form>
</h:body>
</html>
I have no idea, why it should not work. I want every time changes the toolbox value to show the additional information form about toolbox
When you would like to update some part of the view you have to specify an id of an element which is actually present in the DOM. But the panel you are trying to update is not always present in the DOM, only in the case that form.toolbox evaluates to true. So when it is false it cant be updated and so it will not be added to the view.
What you can do to solve this problem is, to wrap the panel inside another element and update that element. This will work because the wrapper-element is always present.
So try the following for the part of the panel:
<h:panelGroup id="toolboxOptions">
<p:panel id="toolboxOptionsPanel" rendered="#{form.toolbox}">
....
</p:panel>
</h:panelGroup>
Have a look at to answer of the following question for further explanation:
JSF + PrimeFaces: `update` attribute does not update component
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!? :)
I am facing a problem rendering a data table when selecting a date from <rich:calendar>. I use <a4j:ajax> for the rendering but with no effect. Here is the code sample:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:composite="http://java.sun.com/jsf/composite">
<rich:panel header="#{lang.reportPanelHeader}" id="panel" rendered="#{navigation.reportRendered}" width="700px" style="margin-left:250px">
<a4j:status onstart="#{rich:component('statPane')}.show()" onstop="#{rich:component('statPane')}.hide()" />
<h:form id="data_table_form">
<rich:dataTable value="#{validateReportAction.reportList}" var="report" iterationStatusVar="it" id="data_table" rows="5">
<rich:column>
<f:facet name="header">#</f:facet>
#{it.index + 1}
</rich:column>
<rich:column>
....
</rich:column>
<f:facet name="footer">
<rich:dataScroller page="#{validateReportAction.page}" />
</f:facet>
</rich:dataTable>
</h:form>
<rich:popupPanel id="statPane" autosized="true" style="border: none; background-color: #e6e6e6;">
....
</rich:popupPanel>
<div id="bottom">
<h:form id="calendarForm">
<div id="left">
<div class="input" id="test_cal">
<rich:calendar
dataModel="#{calendarModel}"
value="#{validateReportAction.selectedDate}"
boundaryDatesMode="scroll"
required="true"
requiredMessage="#{lang.dateRequiredMsg}"
mode="ajax"
id="date"
datePattern="dd.MM.yyyy"
popup="false">
<a4j:ajax event="change" render="#all"/>
</rich:calendar>
<span class="error_msg">
<rich:message for="date" ajaxRendered="true"/>
</span>
</div>
</div>
</h:form>
</div>
</rich:panel>
</ui:composition>
I am forced to use #all in the calendar in <a4j:ajax event="change" render="#all"/> but I want to render only the data table. How can I do this?
Since it's located in a different naming container parent, you need to refer it by its absolute client ID. To find it out, open the page in the webbrowser. Rightclick and View Source. Locate the HTML <table> element which is generated by <rich:dataTable id="data_table">. It'll look something like this:
<table id="data_table_form:data_table">
You need to take exactly that ID, prefix with the JSF naming container separator character (which defaults to :) and use it in the render attribute.
<a4j:ajax event="change" render=":data_table_form:data_table" />
See also:
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"