Unable to find component for ID in view - jsf

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>

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.

how update/render <for:forEach with ajax

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" />

Context path generated twice when using #{resource} value expression within facelet page

I'm using the expression #{resource['library:file']} within a facelets page to generate an ajaxified button with an image within an RichFaces (4.2.2.Final) toolbar.
<h:form>
<rich:toolbar height="40px">
<rich:toolbarGroup>
<a4j:commandButton value="my label" image="#{resource['icons:icon32.gif']}"/>
</rich:toolbarGroup>
</rich:toolbar>
</h:form>
generates the following code for the a4j:commandButton where the context path is generated twice.
<input type="image" alt="my label"
src="/com.test.my.context/com.test.my.context/faces/javax.faces.resource/icon32.gif?ln=icons"
value="my label"
onclick="RichFaces.ajax("j_idt73:j_idt76",event,{"incId":"1"} );return false;"
name="j_idt73:j_idt76" id="j_idt73:j_idt76">
If I use <h:graphicImage library="icons" name="icon32.gif"/> within rich:toolbarGroup the generated URL is right.
Furthermore I've include the image by css using background: url(#{resource['library:file']}) which doesn't gives the result I've searched for, but it works!
Is the expression #{resource['library:file']} only allowed within css files?
Where is the problem within my code?
According to JIRA Issue RF-12523 it's fixed in 4.3.1.Final.

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.

Seam / RichFaces + forceId

I'm having trouble with a4j:repeat and it's id generation. Every element inside the loop has it's id preceded with a unique identifier. I don't want this. I want certain elements to contain the id that I present them (I'm ensuring they're unique).
I've search around and it looks like Tomahawk tags have an attribute forceId which will cause the element to use the id provided. The only thing is, it looks like it's not recommended to use Tomahawk tags with Seam / RichFaces.
Is there anything similar in anyone of the tag libraries recommended to be used with Seam? Barring that, is it reasonably feasible for me to subclass a4j:repeat (or possibly even ui:repeat) and change the way it handles id generation?
Any ideas? All I need is a way to loop through elements giving them dynamic ids.
This is not a RichFaces problem. It is JSF. JSF adds a unique id to each components. This is a known JSF feature.
However, there is something you can do.
In your <h:form> you can set prependId="false". This will tell JSF not to add any ID's from each component.
(Also make sure you are not using s:decorate="/layout/template.xhtml because the template.xhtml and edit.xhtml will add id's of their own.
So do something like this:
<h:form prependId="false">
<a4j:repeat value="#{foo}" var="f" rowKeyVar="row">
<h:inputText id="unique#{row}"/>
</a4j:repeat>
</h:form>
This will make the id like this: unique1 unique2 unique3 etc
Update
Seems you are right. For some reason, the id tag doesn't support this type of EL expression.
I tried the following:
<a:repeat id="table" value="#{foo}" var="k" rowKeyVar="row">
<h:inputText id="test#{row}" value="row is #{row}" styleClass="test#{row}"/><br/>
</a:repeat>
And it produces the generated html
<input type="text" class="test0" value="row is 0" name="table:0:test" id="table:0:test">
<input type="text" class="test1" value="row is 1" name="table:1:test" id="table:1:test">
<input type="text" class="test2" value="row is 2" name="table:2:test" id="table:2:test">
So as you can see, I still get a unique id because. Probably is adding the number for me automatically.
It doesn't matter if you add or not. The result is the same.
Maybe useful: You can get real ids in JSF (RichFaces) with #{rich:clientId('id')}. So you can use the generated id in JS.
I don't know why you wouldn't let JSF do the ID generation for you, but I understand that it isn't easy to figure out, since JSF has very little documentation on this subject in my opinion.
I'll tell you my findings on this subject by giving an example (using JSF 2.0.3 Mojarra by the way):
<h:form id="myForm">
<ui:repeat id="loopzor" var="#{myItem}" value="#{myController.myList}">
<h:outputLabel for="myName" value="#{labels.name}:" />
<h:inputText id="myName" value="#{myItem.name}" />
</ui:repeat>
<h:selectOneMenu id="type" value="#{address.type.id}">
<f:selectItems value="#{types}" var="type" itemLabel="#{type.label}" itemValue="#{type.id}"/>
</h:selectOneMenu>
<h:inputText id="value" value="#{address.value}"/>
</h:form>
This is a typical example of how a form might look like. This is what happens when the page is rendered with a list size of 2 items:
<form id="myForm">
<label for="myForm-loopzor-0-myName">Name:</label>
<input id="myForm-loopzor-0-myName" type="text" value="someName" />
<label for="myForm-loopzor-1-myName">Name:</label>
<input id="myForm-loopzor-1-myName" type="text" value="someName2" />
<select id="myForm-type" name="myForm-type>
<option value="1" selected="selected">Label1</option>
<option value="2" >Label2</option>
</select>
</form>
So the ID generation is as follows:
Give IDs to all h:form elements, this will prefix all elements in this form with this ID
If you don't want the form ID prefixed to each element, add the attribute prependid="false" to the h:form element
Give IDs to all ui:repeat elements (even though the id attribute is not specified in the specs)
Give IDs to all h:inputText and other input elements, even inside ui:repeat elements they will get a unique ID based on their position in the loop
You can give IDs to f:selectItems elements but they will not be taken into account
You can suffix the IDs with the varStatus object but this will always return an empty string, probably because when generating the dynamic IDs the varStatus object does not exist
I hope this can clear out some of the confusions about ID generation!

Resources