jsf ajax rendered does not work - ajax

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

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>

Primefaces command button action is not called for the second time

I have spring integrated with JSF and I am facing a strange behavior:
I hit the command button the action method in the managed bean is hit successfully (I removed it in the below example).
The Ajax update works perfect and the form is updated.
I hit another button the action method now in the managed bean isn't hit.
The panel is restored to the initial view and it freezes on this view.
I can't get the form updated except if I refresh the page and these steps are repeated.
DealerInfo.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<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:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:composition template="/WEB-INF/templates/default.xhtml">
<ui:define name="content">
<h:form id="toolBarForm">
<p:toolbar style="margin-bottom:5px;">
<p:toolbarGroup align="right">
<p:commandButton value="Add"
update=":toolBarForm" icon="ui-icon-plusthick" />
</p:toolbarGroup>
</p:toolbar>
<p:messages id="dealerInfoMessages" />
<ui:include src="/pages/dealers/DealerMainInfo.xhtml" />
</h:form>
</ui:define>
</ui:composition>
</html>
pages/dealers/DealerMainInfo.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<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:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:composition>
<p:panel id="dealerMainInfoPanel" header="Dealer Main Info"
style="margin-bottom:5px;">
<h:panelGrid columns="2">
<p:outputLabel for="dealerCode" value="Dealer Code" />
<p:inputText id="dealerCode" required="true"
value="#{dealerMainInfoBO.dealerCode}" style="width:200px;" />
<p:outputLabel for="dealerName" value="Dealer Name" />
<p:inputText id="dealerName" required="true"
value="#{dealerMainInfoBO.dealerName}" style="width:200px;" />
</h:panelGrid>
</p:panel>
</ui:composition>
</html>
Update:
I created a very simple single page and I noticed that when I remove the <h:head></h:head> tags the ajax works like a charm BUT without the fancy primefaces UI, and when I add the tags the ajax stop (this is normal cause <h:head></h:head> tags fetch all the needed JSs and CSSs), What Can I Do?
Example.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<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:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<f:view contentType="text/html">
<h:head>
</h:head>
<h:body>
<h:form id="toolBarForm">
<p:toolbar style="margin-bottom:5px;">
<p:toolbarGroup align="right">
<p:commandButton value="Add" update=":toolBarForm"
action="#{bean.add}" />
</p:toolbarGroup>
</p:toolbar>
<p:messages id="operationDefinitionMessages" />
<h:panelGrid columns="2">
<p:outputLabel for="text" value="Text" />
<p:inputText id="text" required="true" value="#{bean.text}" />
</h:panelGrid>
</h:form>
</h:body>
</f:view>
</html>
My Environment
Primefaces:3.5
JSF-Mojarra:2.2
Spring:3.2.3.RELEASE
In case anyone faces the same issue. I noticed that the Primefaces showcase is using JSF-Mojarra-2.1.22. I downgraded my JSF-Mojarra version from 2.2 to 2.1.22 and it worked like a charm.
If I am not wrong, I guess it should be reported to primefaces (if it isn't a current issue).

<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!? :)

Update component with Ajax results in Exception

It seems like I am simply unable to grasp, how updating components with Ajax works. I keep on getting an Exception "Cannot find component with identifier ":menu-item-container" referenced from "j_idt12:0:j_idt16:j_idt76"."
This is my code:
<!DOCTYPE html>
<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:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<f:view contentType="text/html">
<h:head>
<title><ui:insert name="pageTitle"></ui:insert></title>
</h:head>
<h:body>
<h:outputStylesheet library="css" name="style.css" />
<div class="menu-navigation">
<ul>
<li>Menu</li>
<ui:repeat var="category"
value="#{restaurantsBean.restaurant.categories}">
<h:form>
<li><p:commandLink update=":menu-item-container">
<div>
#{category.name}
<f:setPropertyActionListener value="#{category.id}"
target="# {restaurantMenuBean.selected}" />
</div>
</p:commandLink></li>
</h:form>
</ui:repeat>
</ul>
</div>
<div id="menu-item-container">
<ui:repeat var="category"
value="#{restaurantsBean.restaurant.categories}">
<p:outputPanel>
<h:panelGroup id="pangroup" layout="block"
rendered="#{restaurantMenuBean.active(category.id)}">
<div class="some-heading">
<h2>#{category.name}</h2>
</div>
<div class="category-description">#{category.description}</div>
<ui:repeat var="item" value="#{category.items}">
<p:outputPanel
rendered="#{restaurantMenuBean.needLightbox(item)}">
<ui:include src="/lightbox-item.xhtml"></ui:include>
</p:outputPanel>
<p:outputPanel
rendered="#{!restaurantMenuBean.needLightbox(item)}">
<ui:include src="/nolightbox-item.xhtml"></ui:include>
</p:outputPanel>
</ui:repeat>
</h:panelGroup>
</p:outputPanel>
</ui:repeat>
</div>
</h:body>
</f:view>
</html>
This is the related area of html source output, which tells me, my "menu-item-container" is right at the root and the update-attribute only needs a separation marker ":" in front of its id.
<div id="menu-item-container"><span id="j_idt17:0:j_idt64"></span><span id="j_idt17:1:j_idt64"><div id="j_idt17:1:pangroup">
<div class="some-heading">
The to-be-updated components are resolved using the algorithm as described in UIViewRoot#findComponent(). It should be obvious that it can find fullworthy JSF components only.
Your menu-item-container is however a plain HTML <div> element and thus unavailable in the JSF component tree.
Replace it by a fullworthy JSF component.
<h:panelGroup id="menu-item-container" layout="block">
The <h:panelGroup> renders by default a <span> and the layout="block" turns it into a <div>.

Ajax-render a table which is inside a different form

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"

Resources