how update/render <for:forEach with ajax - jsf

I got a list with steps which I displays as follow:
<ul >
<for:forEach id="steps" items="#{RecipeBean.recipe.steps}" var="step">
<li> <com:Step description="#{step.stepDescription}"/></li>
</for:forEach>
</ul>
<p:commandButton id="addstep" value="#{msg['step.add']}" action="#{RecipeBean.addStep}" update="steps" />
The button addStep adds a Step to the RecipeBean.recipe.steps collection. Now the new added step should be displayed. But like that I get the error message Cannot find component with identifier "steps" referenced from "j_idt8:addstep" and this is probably of the for:forEach component.
So does someone know how I can fix this issue?

The update attribute of the <p:commandButton> component should point to a component. Since <for:forEach> is not a component, but a taghandler, you receive an error message.
I would suggest you take a look at the existing PrimeFaces components like DataList, which presents a list objects in unordered format.
Then, you can refactor your code as follows:
<p:dataList id="steps" items="#{RecipeBean.recipe.steps}"
var="step" itemType="disc">
<com:Step description="#{step.stepDescription}" />
</p:dataList>
<p:commandButton id="addstep" value="#{msg['step.add']}"
action="#{RecipeBean.addStep}" update="steps" />

Related

JSF id value to the component behaves different

I have the following code in my xhtml
<h:form id="xyForm">
<p:dataGrid id="xyGrid" ....>
<p:selectOneMenu id="code" ...> </p:selectOneMenu>
</p:dataGrid>
</h:form>
But when I saw the code generated, it looks like the following
<select name="xyForm:xyGrid:0:code_input" tabindex="-1" id="xyForm:xyGrid:0:code_input"> </select>
My question here is: why _input is getting appended with name and id.
As per my understanding id should be only xyForm:xyGrid:0:code not with appended _input. Could someone please clarify or tell me how to remove that _input?
An id attribute should be unique within an html page.
While rendering the SelectOneMenu, the select tag is wrapped inside a div tag. The div tag will have the id of the component i.e. xyForm:xyGrid:0:code, and so it makes sense that the select tag should have a different id.
Also, this is a common pattern in Primefaces, observed in other components like SelectBooleanCheckbox etc.
Instead of trying to removing _input, you will have to figure around how to work around it.

Unable to find component for ID in view

In a JSF, Primefaces 6 project, I get the following warning:
Unable to find component for ID dateFrom_input in view
Here is the view:
<h:outputLabel for="dateFrom_input" />
<p:autoComplete id="dateFrom" ...></p:autoComplete>
p:autoComplete is replaced by:
<span id="searchForm:dateFrom">
<input id="searchForm:dateFrom_input" name="searchForm:dateFrom_input" type="text" autocomplete="off">
...
</span>
Basically, I have to set the label for component dateFrom_input to get the feature working (I mean clicking on label to jump in the field...). It works but the warning appear.
It looks I cannot make reference to something in a widget...
How two shut this warning up?
UPDATE
In a DOM point of view, what I do is correct (label for parameter set with the input ID). But in a JSF point of view, p:autocomplete field is not yet "compiled" as HTML and it cannot reach the input (which effectively take ID dateFrom_input once compiled)
Please try to use the following:
<p:outputLabel for="dateFrom" value="Click here! "/>
<p:autoComplete id="dateFrom" ...></p:autoComplete>

h:selectOneRadio doesn't work with ajax change event

i have two radio buttons and no one is selected by default, and it's mandatory to select one of them, so here's what i did:
<div id="payment_method">
<h:message for="sel_payment_method" style="Color:red;"/>
<h:selectOneRadio id="sel_payment_method" required="true" requiredMessage="Please select a payment method" value="#{myBean.selectedPaymentMethod}">
<f:selectItem itemLabel="Debit or Credit Card" itemValue="credit" />
<f:selectItem itemLabel="Checking Account" itemValue="checking" />
<f:ajax event="change" render="credit_inputs_fragment checking_inputs_fragements" />
</h:selectOneRadio>
</div>
the selectedPaymentMethod property is a string and its default value is null
and the credit_inputs_fragment is a ui:fragement that contains a div
ISSUE: when clicking on a radio buttons the two fragments to be changed are not affected.
please advise, thanks.
You're not entirely clear in describing the concrete problem, but I can see at least two potential problems in the code posted so far:
The <f:ajax event="change"> is wrong in case of radiobuttons and checkboxes. It should be event="click". Or, better, just remove it altogether. It defaults to the right one already. See also What values can I pass to the event attribute of the f:ajax tag?
The component referenced in <f:ajax render> must be a fullworthy JSF UI component and always be rendered to the client side. If the component is by itself never rendered to the HTML, then JavaScript simply can't find it to update its content. You basically need the conditionally rendered components in another component which is always rendered. See also Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?
i followed the example code in the following link, and it solved my issue:
JSF: Dynamically change form

Cannot find component with identifier in View JSF

I was trying to show messages using a p:growl like this.to be updated on the OnRowSelect Method of a Data Table lazy loading like this
<p:growl id="applyMessages" showDetail="false" global="true" /> and <p:ajax event="rowSelect" listener="#{editBean.onRowSelect}" update=":studyPlanEditForm:display applyMessages"/>
but got the error like this
Cannot find component with identifier "applyMessages" in view.
Please Help.
Check the source code of your page in browser. Then identify the p:growl markup and its generated client-id. It surely is longer than applyMessages and has a prefix similar to containerID:applyMessages. Use this id in your update attribute of the ajax call.

How to render an h:panelGroup correctly when using f:ajax and a rendered attribute?

I'm developping an application in JSF2.0. I encountered a problem when mixing ajax and a panelGroup with a rendered attribute.
My page contains 3 panels. In the first panel the user selects an item from a <h:selectOneMenu>. This causes to render the second panel.
The second panel contains an h:dataTable that is connected to a DataModel in the backing bean. The values of the dataTable are determined by the item that was chosen in the <h:selectOneMenu> of the first panel. Each row in the table contains a commandLink to view detailed info about the item of that row:
<h:commandLink action="#{faseController.selectInvulling}">
<f:ajax render="#form" execute="#form" />
</h:commandLink>
Clicking on the commandLink the third panel gets rendered:
<h:panelGroup rendered="#{faseController.invullingSelected}" layout="block" styleClass="panelElement" id="invulling">
<label>
<span>Datum:</span>
<h:inputText value="#{faseController.selectedInvulling.datum}" required="true" requiredMessage="Gelieve een datum in te vullen." converterMessage="Gelieve een geldige datum in te vullen (dd/mm/jjjj)." >
<f:convertDateTime pattern="dd/MM/yyyy" />
</h:inputText>
</label>
<label>
<span>Evaluatie</span>
<h:inputTextarea value="#{faseController.selectedInvulling.evaluatie}" cols="100" />
</label>
<label>
<span>Methode</span>
<h:inputTextarea value="#{faseController.selectedInvulling.methode}" cols="100" />
</label>
</h:panelGroup>
This is where I encounter a problem. The first time I click on a commandLink to view the detailed info about that row in the table, I get the correct data in the third panel. Afterwards I change the item in the <h:selectOneMenu> of the first panel: the correct corresponding dataTable gets rendered in the second panel. However this time when I click on a commandLink in the table to view the details of that item, I get to see the info from the item I clicked the first time.
If I ommit rendered="#{faseController.invullingSelected}" everything works fine, but this causes confusion in the view, since the third panel is now always rendered.
All three panels are located in the same form. My backing bean is ViewScoped. What am I doing wrong? Any help woud be greatly appreciated.
This can happen if you're doing business logic in an getter method instead of in an (action)listener method. I also wonder if you really need to execute and render the entire form. Try to be more specific in specifying the elements which are to be executed and/or re-rendered.
The question is way too broad and the code is not complete enough in order to pinpoint the real cause and propose the a ready-to-use solution.
Try using this.
<a4j:commandLink action="#{faseController.selectInvulling}" execute="#this"
render="thirdPanelId" limitRender="true"/>
Execute only the components which you want to process and render only the components which needs to be refreshed.

Resources