How do I get h:outputText inside of a ui:repeat nested in h:dataTable to update when the datatable is updated? - jsf

So the relevant sections of my code is:
<h:panelGroup id="pnlGrp" style="padding:10px" width="100%">
<div>
<h:dataTable id="availableCrList"
value="#{searchData.availableCrList}"
var="avail"
varStatus="thisVarStatus" rows="#{searchData.rowsPerPage}"
sortColumn="#{searchData.crSortColumnName}"
sortAscending="#{searchData.crAscending}" style="width:100%;">
<h:column>
<ui:repeat value="#{avail.crRsnCdList}"
var="crRsnCd"
varStatus="status">
<h:outputText value="#{crRsnCd}<br />"
title="#{avail.crRsnDescList[status.index]}"
escape="false"/>
</ui:repeat>
</h:column>
</h:dataTable>
</div>
</h:panelGroup>
I'm working inside a legacy application and my goal is to display a list of codes which indicate reasons why a given item in this table might be completed, or cancelled, et cetera. The title is converted into a hovering tooltip which displays the description for each of these codes.
Now, I managed to get this working for singular codes no problem, but since switching from a String to a List of strings it's been a nightmare trying to get this to work.
Right now with the above code it displays the codes correctly the first time, but when I update the datatable by searching for a new value all the other columns (not shown) are correctly displayed while the RsnCd column continues to display the same data from the first search.
As an example, the first time I search for records the datatable might pull up:
Row1:A1
Row2:A1
Row3:A1
A3
Row4:A1
The second time I search for data I would expect to see only:
Row1:
Row2:
Row3:
Row4:
Row5:
Row6:
Row7:
But instead I get:
Row1:A1
Row2:A1
Row3:A1
A3
Row4:A1
Row5:
Row6:
Row7:
Really not sure if I'm explaining this adequately/understandably.

I solved this issue by changing
<ui:repeat value="#{avail.crRsnCdList}"
var="crRsnCd"
varStatus="status">
<h:outputText value="#{crRsnCd}<br />"
title="#{avail.crRsnDescList[status.index]}"
escape="false"/>
</ui:repeat>
To:
<ice:column>
<ice:repeat value="#{avail.crRsnCdList}"
varStatus="status">
<ice:outputText value="#{avail.crRsnCdList[status.index]}<br />"
title="#{avail.crRsnDescList[status.index]}"
escape="false"/>
</ice:repeat>
</ice:column>
I tried getting rid of the value but it stopped displaying anything.

Related

Primefaces Diagram - Generating IDs for DOM Elements

I'm trying to create a <p:diagram> with elements which contain input fields, but the problem is that for each added element, the name and ID are the same for each input field.
What I've tried to do to give each field a unique id is adding a bean-generated ID for each element, but this just gets omitted in the final code. Here's my EL/xhtml:
<p:diagram value="#{Controller.model}" style="height:600px;width:1500px" styleClass="ui-widget-content" var="lrvEl" scrollable="true">
<f:facet name="element">
<div onmouseleave="nodeOnMouseOut(this)" onclick="nodeOnClick(this)">
<h:outputText value="#{lrvEl.title}" style="display:block;margin-top:1em;width:100%;height:10px;padding-left:4px"/>
<h:outputText value="#{lrvEl.description}" style="display:block;margin-top:1em;width:100%;height:10px;padding-left:4px"/>
<h:inputText id="inputEpValue_#{lrvEl.id}" name="inputEpValue_#{lrvEl.id}" onchange="setScoreVal('#{lrvEl.id}', this)" rendered="#{lrvEl.isScore()}" style="display:block;margin-top:1em;height:10px;padding-left:4px">
</h:inputText>
</div>
</f:facet>
<p:ajax event="connect" listener="#{Controller.onConnect}" />
<p:ajax event="disconnect" listener="#{Controller.onDisconnect}" />
<p:ajax event="connectionChange" listener="#{Controller.onConnectionChange}" />
</p:diagram>
The important bit here is the <h:inputText id='inputEpValue_#{lrvEl.id}' ... > - this comes out on the page as the following:
editor:LRVContent:overlayForm_lm:inputEpValue
as if the value wasn't set, however, as you can see in the onchange field I use the same constellation. This gets rendered as onchange="setScoreVal('ep:2', this)" so that works.
Can I not dynamically set IDs for elements in this fashion? Is there another way?
Edit:
The actual Reason I want to do this is that, if I have more than one input with the same generated ID, the focus(/cursor) will automatically jump into the last generated input field when I click on any one of them, meaning I won't be able to actually change the value of any of those fields.

Two buttons ( that generate inputtexts when clicked ) don't work on the same Facelet

I have two buttons that generate inputtexts when clicked. The problem is, when these two buttons are on the same xhtml, wichever is the first one, it is the only one that works.
If you need, here is an explanation on the Code 1 below:
It represents two inputtexts to get the name
and email of the author of a Document. moreAuthors represents
the method getMoreAuthors() that belongs to the Managed Bean inserirBean.
getMoreAuthors() returns a List<AuthorBean>.
The List<AuthorBean> is a property from the Managed Bean inserirBean.
The class AuthorBean creates the instances of Author, it has a property called
Author author.
AddAuthor() adds one more AuthorBean to the List<AuthorBean> in
Managed Bean inserirBean.
If you need, here is an explanation on the Code 2 below:
It follows the same structure from Code 1. Here, there's only one
inputtext that is used to get a subject of a Document.
moreSubjects returns a List<SubjectBean>. The class SubjectBean
creates the instances of the class Subjects.
SubjectBean has a property Subject sub,
and Subject has a property called String subject.
AddSubject() adds one more SubjectBean to the List<SubjectBean> in
Managed Bean inserirBean.
Code 1- If this is the only one on the xhtml, it works:
<h:form >
<h:dataTable value="#{inserirBean.moreAuthors}" var="authorBean">
<h:column>
Nome do Autor:
<h:inputText value="#{authorBean.author.name}" />
</h:column>
<h:column>
Email do Autor:
<h:inputText value="#{authorBean.author.email}" />
</h:column>
<f:facet name="footer">
<h:panelGroup>
<h:commandButton value="+" action="#{inserirBean.addAuthor()}" />
</h:panelGroup>
</f:facet>
</h:dataTable>
</h:form>
2- If this is the only one on the xhtml, it works too:
<h:form >
<h:dataTable value="#{inserirBean.moreSubjects}" var="subjectBean">
<h:column>
Palavras-chave:
<h:inputText value="#{subjectBean.sub.subject}" />
</h:column>
<f:facet name="footer">
<h:panelGroup>
<h:commandButton value="+" action="#{inserirBean.addSubject}" />
</h:panelGroup>
</f:facet>
</h:dataTable>
</h:form>
BUT, if I put these two blocks on the same xhtml, the one that appears first on the browser, always works, and the second, never - and I've already tried to change their position, but whichever I put first place on screen is the one that works.
What's causing this problem?
Thank you!
I just put the two datatables in code 1 and 2 inside the same <form> block and both worked.

jsf tabledata dynamic inputtext

I have a List in my backing bean. I want to present it in a table. I want table to have two rows - on left side, values from the list, and on the right side inputBoxes. It's the easy part. Here's my code:
<div class="table">
<h:dataTable id="korekty" styleClass="table table-hover"
value="#{searchBean.listX}" var="v">
<h:column>
<f:facet name="header">XXX</f:facet>
#{v.string}
</h:column>
<h:column>
<f:facet name="header">YYY</f:facet>
<h:inputText styleClass="form-control">
</h:inputText>
</h:column>
</h:dataTable>
</div>
The hard part of my problem is : in those inputtext user might put some numbers. Then after hitting SUBMIT button I want to create a list/map/whatever of inputed values. How can I do that? Thanks for help
First of all, prepare an array, or a list, containing placeholders for the given data alongside the list you've got:
List<String> initialData = ...;//initial data of n size
String[] submittedData = new String[initialData.size()];//array of the same size
Then, bind the <h:dataTable> component to the view to get access to the current row index of the iteration. This way you can finish your job by binding value of input elements to the corresponding objects in the array/list:
<h:dataTable binding="#{table}" ... >
<h:column>
<f:facet name="header">YYY</f:facet>
<h:inputText value="#{searchBean.submittedData[table.rowIndex]}" ... />
</h:column>
</h:dataTable>

Making h:outputtext don't print a line break on a jsf page

I have some code like the below and it works, but instead of showing just a number, I want to show "number%". Here's what I have:
<h:outputtext value="#{somebean.doubleValue}">
<f:convertnumber maxfractiondigits="2">
</h:outputtext>
If I put the "%" sign inside the value property, the converter won't work (I believe because the evaluated result is not just a number), but if I put the "%" sign in other outputtext tag, one line break appears between the number and it. I don't want that.
<h:outputtext value="#{somebean.doubleValue}">
<f:convertnumber maxfractiondigits="2">
</h:outputtext>
<h:outputtext value="%"> <!--prints a new line-->
What's the best way to achieve a "xx.xx%" formatting on jsf?
Set the CSS white-space property of the common parent element to nowrap.
E.g.
<span style="white-space: nowrap;">
<h:outputText value="#{somebean.doubleValue}">
<f:convertNumber maxfractiondigits="2">
</h:outputText>%
</span>
(note: you don't necessarily need <h:outputText> for plain text)
If you are actually using this in a <h:column> (as I would initially guess), you could specify a classname for the <td> by the columnClasses attribute of the <h:dataTable>.

jsf repeat inside datatable

I'm using datatable and i get number of columns dynamically. I tried to put repeat inside like this way:
<h:dataTable value="#{movieUserBean.sits}" var="row"
rowClasses="oddRows,evenRows" headerClass="header"
styleClass="table" cellpadding="5" cellspacing="0">
<ui:repeat value="#{row}" var="sit">
<h:column>
<h:selectBooleanCheckbox value= "#{movieUserBean.checked[sit.id]}"/>
</h:column>
</ui:repeat>
Which sits is a two dimensions array, my thought was that datatable should loop over the sits rows and repeat loops over every value inside every row (which is an object named Sit with get method: getId).
The problem is that I get an empty table. Seems like var "sit" is not getting value.
Can the problem be the fact that datatable ignores any elements who's not in column scope?
ui:repeat is called before the render response phase, i suggest you to use DynamicColumns of primefaces http://www.primefaces.org/showcase/ui/datatableDynamicColumns.jsf
A simple solution would be
<table>
<ui:repeat value="#{movieUserBean.sits}" var="row">
<tr>
<ui:repeat value="#{row}" var="sit">
<td><h:selectBooleanCheckbox value= "#{movieUserBean.checked[sit.id]}"/></td>
</ui:repeat>
</tr>
</ui:repeat>
</table>
If you have variable columns per row it might mess up with css styles. For example 5 columns on row one and 3 columns on row 2, how would you style them. The way i see it you want to show seats in a theater occupied with a checkbox.
You can try using ui:repeat's with ul,li or div's instead of going with the table. approach.

Resources