How to display a 2d array of elements - jsf-2

I'd like to display 2d array of floats in a table on a xhtml page using JSF2 and I have no idea how to do that. I tried to find the answer in google but I couldn't. All examples were displaying classes objects and I was not able to make it working with the table.
The sitation is:
I have the array of some size - the size of the array depends on entered data:
float [][] variables = new float[size1][size2]
After user enters data and pressess button a method is called in the managed bean. The calculation begins and the table is filled with data.
Please tell me how can I display the array.

To achieve that you can use c:forEach tag to dinamically buid a h:panelGrid. Just save size2, which is the column number as a property and store all the input numbers in a normal java.util.List. Then you set that size to the h:panelGrid columns attribute and the component will split the rows for you. You can also style the content inside the c:forEach tag, bordering it in order to give it a table behaviour.
<h:form>
<h:panelGrid columns="#{bean.numberCount}">
<c:forEach var="num" items="#{bean.numberList}">
#{number}
</c:forEach>
</h:panelGrid>
</h:form>
EDITED
If you want to maintain the original structure but in a List, you can create a List<List<Float>>. That means a List which is composed by List which contains Float Objects. The same as a 2d array.
private List<List<Float>> _Matrix;
public List<List<Float>> get_Matrix() {
return this._Matrix;
}
/**
* Constructor for BackingBean.
*/
public BackingBean() {
this._Matrix = new ArrayList<List<Float>>();
this._Matrix.add(new ArrayList<Float>());
this._Matrix.add(new ArrayList<Float>());
this._Matrix.get(0).add(1.0f);
this._Matrix.get(0).add(2.0f);
this._Matrix.get(0).add(3.0f);
this._Matrix.get(1).add(1.0f);
this._Matrix.get(1).add(2.0f);
this._Matrix.get(1).add(3.0f);
}
In the code above I'm constructing the equivalent to a 2d array with 2 rows and values 1.0,2.0 and 3.0 on each row. You can use this code to iterate it over the view:
<h:panelGrid columns="#{backingBean._ColumnNumber}">
<c:forEach var="row" items="#{backingBean._Matrix}">
<c:forEach var="value" items="#{row}">
#{value}
</c:forEach>
</c:forEach>
</h:panelGrid>
Where #{backingBean._ColumnNumber} will be the length of the first array of the List (supposing all of them have the same length).
Good Luck.

Related

Sorting of primefaces dataTable with p:columns and converter

I have a primefaces data table with dynamic colums:
<p:dataTable value="#{curSearch.getSearchResults()}" var="curSearchResult" sortMode="multiple" rowKey="#{curSearchResult.getUniqueId()}">
<p:columns value="#{curSearch.determinePrimaryPropertyNames()}" var="curPrimaryPropName" sortBy="#{curSearchResult[curPrimaryPropName].getValue()}">
...
</p:columns>
</p:dataTable>
In most cases the value of sortBy expressions fits (e. g. for a date or a string), but I have one special data type which must be translated. This means sortBy="#{curSearchResult[curPrimaryPropName].getValue()}" delivers a string which must be converted in a i18n string. This i18n string should be sorted then. Unfortunately the attribute sortBy throws an IndexOutOfBoundsExcpetion if the expression does not contain brackets []. My idea was to call a method and distinguish there between the "normal" values and the values which must be translated. So my 2nd idea is to define a converter for the value which has to be translated. But is converted value evaluated by primefaces? I guess not. Is there maybe another approach for this?
I'm using something like the following code snippet in a Lazy Loading data table and it's working fine.
<p:columns value="#{listController.ColumnModel}"
width="#{column.width}" var="column" field="#{column.field.fieldName}" sortBy="#{ticket[column.field.fieldName]}"
columnIndexVar="colIndex">
I'm storing the field name in the column model as you can see. In the backing bean method used for loading table data you will receive a list of sortmeta so you can sort your result set. I hope this can help you.

Expand a Richfaces collapsibleSubTable via javascript

How can I expand a rich:collapsibleSubTable with expandMode="client" via Javascript?
As I understood, the usual way to expand the subTable would be to either use the expanded-attribute
<rich:collapsibleSubTable
value="#{list.items}"
var="item"
expandMode="client"
expanded="true">
<rich:column><h:outputText value="#{item.model}" /></rich:column>
</rich:collapsibleSubTable>
or use the rich:collapsibleSubTableToggler. But because we have the need to open every second sub-table on a datatable, I'm looking for a way to do that via javascript on client-side. Is there a way, to trigger the expand via the javascript RichFaces object or anything? Help appreciated...
The subTable has collapse() and expand() methods.
If you need to access all subtables you can do it with jQuery:
$('[id$=sbtbl]');
then as you go through the elements, the JS object that represents the table is:
element.rf.component; // element = $('[id$=sbtbl]')[n];

Binding value of UISelectOne and UISelectMany to same property

I'm trying to create a dynamic survey application in Prime Faces. I have a list of Question Objects that each contains a list of AnswerChoices. These are given to the f:selectItems value attribute. This is fine. The question object also contains a List of selectedValues which is given to the relevant selectOne/many component.
Because I'm looking to be generic, there will be questions that have multiple selected values and also some that have only one selected value. I wanted to be able to point the selectOne and selectMany components to the List of strings within the relevant Question object that represents the selectedValues.
This works ok for the selectMany component, but not for the selectOne component which needs to be pointed at a singular object rather than a list. Is there an easy way around this that I'm missing - as I'd like to only have one object representing the selectedValues if possible
You can use brace notation to bind the value to a list/array item at a specific index. The below example binds the value to the 1st item of the list/array.
<h:selectOneMenu value="#{bean.selectedAnswers[0]}" />
There's however a caveat: you need to prepare the list/array with the single item yourself during bean's (post)construction. JSF/EL won't do that in case of a <h:selectOneMenu>.
E.g.
#PostConstruct
public void init() {
selectedAnswers = new ArrayList<Answer>();
selectedAnswers.add(null);
}
It doesn't harm to reuse this preinitializated property for UISelectMany components by the way.

What is the correct code pattern to fetch data base entries?

In two other questions (here and here) BalusC makes a straight up declaration:
Getters are solely there to access bean properties, not to do some business logic. There you have the bean constructor, initialization blocks or event methods for. All are executed only once during bean's life and that's exactly what you want.
Well gee -- this just invalidated a gazillion lines of code I have already written. Ok, then, what is the correct way of implementing a backing bean that fills a data table? I understand his point and the concept, but not the practice. My question is twofold:
Why is the way I am doing it wrong?
How do I fix it?
I use PrimeFaces p:dataTable a lot, and it's value attribute resolves to a collection. For reasons I don't go into here, I do not use PrimeFaces' lazy table loading feature. Instead I implement my own filter/sort controls, but they trigger AJAX events, which then results in the table being filled with records fetched from the data base.
The table is marked up like this:
<p:panel id="mqTable">
<h:outputText value="Sort/Filter: #{maintCategory.tableQueryParameters}" />
<p:dataTable
id="mqDataTable"
rows="#{maintCategory.pageSize}"
value="#{maintCategory.dataModel}"
selection="#{maintCategory.selected}"
var="cat"
selectionMode="single"
emptyMessage="No Categories Found">
Now the INCREDIBLY BAD UN-JSFish (or so I just found out) getter for dataModel goes like this:
public ATMDataModel getDataModel() {
TableQueryParameters p = getTableQueryParameters();
if (p.isChangePending()) clearDataModel();
p.setChangePending(false);
if (dataModel != null) return dataModel;
List<ET> list = getDAO().runQuery(p);
if (p.isNeedResultSize()) p.setResultSize(getDAO().runQueryCount(p));
dataModel = new ATMDataModel(list);
return dataModel;
}
A few explanations.
This is from an abstract super-class where ET is the "Entity Type." All my CRUDs use this same routine.
The class ATMDataModel is a wrapper for the list which implements SelectableListModel. The row selection logic in PrimeFaces requires this. (It is a pain that appeared in PF 3 but it makes row selection work more reliably.)
The class TableQueryParameters is something I wrote to encapsulate the current state of the table on the user's screen. It includes what sort parameters, what filter parameters, what page we are on, etc. Because this needs to be preserved, the backing bean is ViewAccesScoped (via MyFaces CODI) and the TableQueryParameters is a property within it.
The TableQueryParameters are updated in response via AJAX events, which also update the form causing getDataModel to be called. The method isChangePending goes true when anything changes. So the getDataModel method uses this to generate only one fetch from the DAO between changes no matter how many times it is called.
BUT if the TableQueryParameters do change, I have to call runQuery with those parameters to fetch the new set of records the user wants to see. If I don't call it in getDataModel where do I call it?
Please advise.
You're basically lazily loading the data in the getter. You're not hitting the DB on every getter call within the same request (or view) scope. This is affordable. I don't use CODI, but I'd imagine that the getTableQueryParameters() call is also particularly cheap and nothing to worry about.
As to the concrete question, you'd normally do the DB/business job in an action(listener) method which is attached to the UICommand component and/or the ajax event tag.
For example (works also as <p:commandButton action> though)
<p:ajax listener="#{bean.deleteSelectedRow}" />
...
<p:ajax listener="#{bean.saveRowDetail}" />
with
public void deleteSelectedRow() {
someService.delete(selectedRow);
dataModel = loadDataModel();
}
public void saveRowDetail() {
someService.save(selectedRow);
dataModel = loadDataModel();
}
Depending on the meaning of p.isChangePending(), I think you could also get rid of it this way, it look like that you were setting it in the action(listener) methods.

Struts2 - Iterating over embedded object lists in JSP

I have a class on the value stack that contains a list of objects, each object is another list of objects and finally there is the object I want to access. For Example:
FruitGroupsList-->FruitGroup-->Fruit
Let's say FruitGroupsList contains 2 FruitGroup Lists:
EdibleFruits
NonEdibleFruits
The EdibleFruits is a FruitGroup (list) that contains a bunch of Fruit Objects:
Apple
Pear
Plum
...
Each Fruit has a Name property.
I understand that I can Iterate through the FruitGroupsList like so:
<s:iterator value="FruitGroupsList" var="fgl">
<s:property value="%{#fgl.name}" />
</s:iterator>
How do I loop through each FruitGroup and get a property (such as FruitName)? I've tried various types of embedding other iterator tags but thus far I can't seem to solve this...
Thanks!
I'll assume you've only put one type in each list, otherwise you should really use a map.
So your veiw has access to your actions:
List<List<Fruit>> fruitGroupsList;
In which case you'd say:
<s:iterator value="fruitGroupsList">
<s:iterator>
<s:property value="whatEverPropertyAFruitHas"/> <!-- If this was a simple type such as String, you could just write <s:property/>
</s:iterator>
</s:iterator>
A list of lists requires two iterators. If things get more confusing then putting a getter in the action to extract some deeply nested items might be reasonable.
I have fixed myself. there was issue in Setter and getter of action class

Resources