Display tag external sort overriden? - sorting

I am using display tag and spring mvc.
Basically, i have a simple table like this. Note the use of external.
<display:table id="tableId" name="data" sort="external" defaultsort="1" sort="external">
<display:column property="id" title="ID" sortable="true" sortName="id" />
<display:column property="firstName" sortable="true" sortName="firstName" title="First Name" />
<display:column property="lastName" sortable="true" sortName="lastName" title="Last Name" />
<display:column property="address" sortable="true" sortName="address" title="Email Address"/>
</display:table>
On the controller side, i get the sorted column index and the sort order.
String c = request.getAttribute(new ParamEncoder("tableId").encodeParameterName(TableTagParameters.PARAMETER_SORT));
To get the order (ASC/DESC):
String order = request.getAttribute(new ParamEncoder("tableId").encodeParameterName(TableTagParameters.PARAMETER_ORDER)));
All this is working fine. For the last step i used customized comparator to sort my list and put it back into the attribute "data" mapped himself to the table (see display tag "name" property).
public void populateModel(Model model, HttpRequest request){
String c = request.getAttribute(new ParamEncoder("tableId").encodeParameterName(TableTagParameters.PARAMETER_SORT));
// here the comparator is computed with column and order value eg
Comparator comp = new DefaultComparator();
if(c == 1){
comp = new NumericComparator();
}
List<Employe> list = Collection.sort(dao.getEmployee(), comp );
model.addAttribute("data", list);
// here the list is sorted properly
return "mypage";
}
Unfortunatly the display in the final jsp does not care about order in the list. It seem's something is overriding to a default and alphanumeric sorter...so even if i use my NumericComparator the column is still wrong sorted and i assume the "list" object has been sorted back by the librairie before the display.
To summup:
Get display tag indexes : ok
Sort the list and put it back to jsp : ok (list is sorted depending on display tag params in the controller)
Display the sorted list in the jsp side with display tag : KO (the library do not care about list order, sorting it with default sort)
Display the sorted list in the jsp side without display tag : OK
Any got the explanation about this, is there something wrong or missing ?

Related

Customizing how values get displayed in a Liferay SearchContainer

My Liferay entity Person has a <column name="mother" type="long" /> which points to the primary key of another instance of Person. This long shows up as a number in the SearchContainer table I created:
<liferay-ui:search-container-column-text
name="category"
property="category"
/>
Now, instead of showing up as a long I would like to display the name of the person. So I wrote:
<%
String motherName =
PersonLocalServiceUtil.getPerson( person.getMother() )
.getName();
}
%>
<liferay-ui:search-container-column-text
name="mother"
value="<%= motherName %>"
property="mother"
/>
PROBLEM: The values that get displayed in this column are still the long numbers, not the name. Even after rebuilding and restarting.
What am I doing wrong?
Check the implementation of SearchContainerColumnTextTag:
public int doEndTag() {
...
if (Validator.isNotNull(_property)) {
_value = ...
}
As you can see, you can't set both, property and value. Just set value and you are fine.

a4j:support - Value retrieved from h:selectOneMenu is always NULL

There's a datatable with a h:selectOneMenu in each row. I want to be able to retrieve the value selected in the selectOneMenu in the bean. I'm using richfaces a4j:support tag to make AJAX calls to the backing bean. You can see the code below:
DataTable header:
<t:dataTable id="datatable" var="row" value="#{myBean.dataTableRows}">
SelectOneMenu with A4j:
<h:selectOneMenu id="type" label="Type:" styleClass="tamanho80"
value="#{datatableHolder.selectedValue}" converter="comboConverter" immediate="true" >
<f:selectItem itemValue="#{null}" itemLabel="" />
<t:selectItems var="tp"
itemValue="#{tp}" itemLabel="#{tp.nome}"
value="#{row.comboTypeValues}" />
<f:attribute name="row" value="#{row}"/>
<a4j:support event="onchange" reRender="parent" actionListener="${myBean.executeAjax}" immediate="true" ajaxSingle="true" />
</h:selectOneMenu>
The Backing Bean method to be executed:
public void executeAjax(ActionEvent event){
ValueHolder comboBox = (ValueHolder) event.getComponent().getParent();
comboBox .getValue();
}
comboBox .getValue() is returning NULL, even when I select a value.
PS:
This question has been identified as a possible duplicated of this question, but it's not. My question uses a dataTable and doesn't use binding for each element. Also, I'm using JSF 1.1 and RichFaces 3.3.3.
The problem was identified:
Each "option" generated by the t:selectItems tag was with the item id instead of an index, while the comboConverter was using an index to select the item. So, the list had 12 items (indexes should range from 0 to 11), but the id of the selected item was 22 for example. Then the converter would traverse the list to the index 22 and retrieve the element. However there's not such index in this list, because the max value is 12 and then the converter would always return NULL.
For this problem there are basically 3 ways to solve:
Create a new converter that look for the item by it's id
Adapt/Change the "comboConverter" to look for the item by it's id (doing that so, would impact other pieces of code that use this converter
Adapt the list to use indexes instead of ids
I've chosen the first one, due to the minor impact in the system.

Primefaces 5 dynamic DataTable pre-Sort

I'm trying to build a fully dynamic DataTable with Primefaces 5.0.
I've got a Config-Object for eachs column and I want the DT to sort by one of them from the beginning.
Here's my DT:
<p:dataTable id="ticketTable"
widgetVar="ticketTable"
value="#{ticketBean.ticketDataModell}"
var="ticket"
lazy="true"
paginator="true"
rows="20"
sortBy="#{dataPortletConfigBean.sortByKey}"
>
The sortByKey is a String. It's the name of the Variable I want to sort by.
So I want to replace something like sortBy="key" with sortBy="#{bean.GiveMeAKey}".
But it doesn't work.
I get this: could not resolve property: sortByKey of: [...]
How can I get this to work?
Thanks
I got it working now.
First: The Problem.
I wanted to give the Data-Table the possibilty to have a default-sort (on load).
Thats what the sortBy-Tag in <p:dataTable> does or should do.
As long ass you write your sort-field in the DT-Tag e.g. sortBy="name" it works.
But when you pass a ValueExpression as for Example sortBy="#{bean.giveMeSomeKey}". He just cuts the '#{', everything bevor the '.' and the last '}' away an tries to sort by the field with the name of his result String. In this case 'giveMeSomeKey'.
That makes a default sorting with dynamic values impossible. (At least in PF 5.0)
Second: The Resolve.
I checked out the PF 5.0-Sources and modified the DataTableTemplate-File. (It's a template, wich is filled when PF is being built. It will later be compiled into the DataTable-Class).
There I modified the Method protected String resolveSortField().
Before:
protected String resolveSortField() {
UIColumn column = this.getSortColumn();
String sortField = null;
ValueExpression tableSortByVE = this.getValueExpression("sortBy");
Object tableSortByProperty = this.getSortBy();
if(column == null) {
sortField = (tableSortByVE == null)
? (String) tableSortByProperty
: resolveStaticField(tableSortByVE);
}
After:
protected String resolveSortField() {
UIColumn column = this.getSortColumn();
String sortField = null;
ValueExpression tableSortByVE = this.getValueExpression("sortBy");
Object tableSortByProperty = this.getSortBy();
if(column == null) {
sortField = (tableSortByVE != null)
? tableSortByVE.getExpressionString().contains("[")
? resolveDynamicField(tableSortByVE)
: resolveStaticField(tableSortByVE)
: (String) tableSortByProperty;
}
After building and including it into my project it worked.
So now I can tell my DT:
<p:dataTable [...] sortBy="#{ticket[dataPortletConfigBean.sortByKey]}"
And it will default-sort my DT After the (String)key I pass him with sortByKey, as long as it is a field in my Ticket.
It's not the perfect solution, but it works.
I tested your requirement and it worked fine.
Check if your property sortByKey in dataPortletConfigBean is returning a string like in:
public String getSortByKey() {
return "ticket.number";
}
Also ensure that the targeted column defines the sortBy attribute:
<p:column sortBy="#{ticket.number}" headerText="Number">
#{ticket.number}
</p:column>
I don't remember if this was available in PF 5.0 but now in 5.1 you can use the sortField attribute present in datatable. This was implemented for this exact purpose:
From Primefaces documentation:
sortField: Name of the field to pass lazy load method for
sorting. If not specified, sortBy expression is
used to extract the name.
After that you have to define a similar value for each column using the field attribute. If the columns are not dynamic just the sort then the field attribute will be the same value as the column itself has.
Snippet of code:
<p:dataTable var="repo" value="#{repoStrategy.flaggedRepos}" sortOrder="${repoStrategy.sortOrder}" sortField="${repoStrategy.sortBy}"
style="width: 100%" paginator="true" rows="10" rowIndexVar="rowIndex" >
<p:column headerText="Name" sortBy="#{repo.name}" field="repo.name">
#{repo.name}
</p:column>

How to get checked checkbox value from html page to spring mvc controller

im using spring mvc framework with thymeleaf template engine
the problem is , i have 1 page with multiple check box iterated sing thymeleaf th:each iterator.When i clicked multiple check boxes i want to pass check box values to the controller method..
html content
<table>
<tr th:each="q : ${questions}">
<h3 th:text="${q.questionPattern.questionPattern}"></h3>
<div>
<p >
<input type="checkbox" class="ads_Checkbox" th:text="${q.questionName}" th:value="${q.id}" name="id"/>
</p>
</div>
</tr>
</table>
*Controller*
#RequestMapping(value = Array("/saveAssessment"), params = Array({ "save" }))
def save(#RequestParam set: String, id:Long): String = {
var userAccount: UserAccount = secService.getLoggedUserAccount
println(userAccount)
var questionSetQuestion:QuestionSetQuestion=new QuestionSetQuestion
var questionSet: QuestionSet = new QuestionSet
questionSet.setUser(userAccount)
questionSet.setSetName(set)
questionSet.setCreatedDate(new java.sql.Date(new java.util.Date().getTime))
questionSetService.addQuestionSet(questionSet)
var list2: List[Question] = questionService.findAllQuestion
var limit=list2.size
var qustn:Question=null
var a = 1;
for( a <- 1 to limit ){
println( a );
qustn= questionService.findQuestionById(a)
questionSetQuestion.setQuestion(qustn)
questionSetQuestion.setQuestionSet(questionSet)
questionSetQuestion.setCreatedDate(new java.sql.Date(new java.util.Date().getTime))
questionSetQuestionService.addQuestionSetQuestion(questionSetQuestion) } "redirect:/teacher/Assessment.html" }
I think you pretty much have it. With a checkbox, you can only send one piece of information back with the form...that being the value. So if you are trying to determine which checkboxes are checked when the user clicks the submit button, then I would have the checkboxes all use one name...like "id" (exactly like you have). Value is the actual id of the question (again like you have). Once submitted, "id" will be a String array which includes all the values of the checkboxes that were checked.
So your controller method needs to take param called "ids" mapped to parameter "id" which is a string[]. Now for each id, you can call questionService.findQuestionById.
(I'm not a Groovy guru so no code example sry :)
I have used JSTL with JSP and thymeleaf was something new. I read the THYMELEAF documentation.
There is a section which explains multi valued check boxes.
<input type="checkbox"
class="ads_Checkbox"
th:text="${q.questionName}"
th:value="${q.id}" name="id"/>
In the above code we are not binding the value to the field of the command object. Instead try doing this
<input type="checkbox"
class="ads_Checkbox"
th:text="${q.questionName}"
th:field="*{selectedQuestions}"
th:value="${q.id}" />
here the selectedQuestions is an array object present in the spring command object.

Filter for several open Faces datatables

I have 3 openFaces <o:datatable />s in the same view page (overview.xhtml).
The first displays a list of all music bands
The 2d displays a list of all songs written by music bands
The 3d displays a list of all shows given by music bands
I am using <o:inputTextFilter /> to filter the first datatable using
the row ID (
<h:form>
<o:datatable value="#{bandBean.items}" var="band" ........<o:inputTextFilter
expression="#{band.id}" .../>
</h:form>
<h:form>
<o:datatable value="#{showBean.items}" var="show" ........<o:inputTextFilter
expression="#{band.id}" .../>
</h:form>
<h:form>
<o:datatable value="#{songBean.items}" var="song" ........<o:inputTextFilter
expression="#{band.id}" .../>
</h:form>
The songs and the shows are child objects of music bands.
What I really need is the ability to filter the 3 datatables using the
same inputTextFilter or something similar, since the 3 datatables have each a column with the band ID.
The user will never accept typing the band id three times, first
tilme for the BAND table, second time for the shows table and the
third time for the song table, using 3 filters. Instead he wants to type once the band
ID , and instantly the 3 tables get filtered.
One workaround would be to use three <o:inputTextFilter /> and set their values using javascript or ajax : while the user types something in a filter, the value being typed is appended immediately to the other filters. I can't figure that workaround. yet it seems to be odd to display 3 filters while the user should use only one.
Any ideas and help will be precious!
There's no direct support for attaching a filter to several tables,
however you can simulate this behavior. To so this, you can attach a
hidden ("display: none") to each of your tables
using the "for" attribute, and specify the filtering value for all of
them programmatically.
Here's a simple code snippet which demonstrate this idea:
<o:inputText value="#{MyBean.filterText}"/>
<o:commandButton value="Submit" action="#{MyBean.filterAllTables}"/>
<o:inputTextFilter for="table1" expression="#{book.bookTitle}"
value="#{MyBean.filterCriterion}" style="display: none"/>
<o:inputTextFilter for="table2" expression="#{book.bookTitle}"
value="#{MyBean.filterCriterion}" style="display: none"/>
<o:dataTable id="table1" ...>
<o:dataTable id="table2" ...>
MyBean.java:
private String filterText; // a property w/ getter/setter
private ExpressionFilterCriterion filterCriterion; // a property w/ getter/setter
public void filterTables() {
String filterText = getFilterText();
SimplePropertyLocatorFactory.SimplePropertyLocator propertyLocator =
new SimplePropertyLocatorFactory.SimplePropertyLocator("id"); // "id" is a property name by which you'd like to filter
ExpressionFilterCriterion filterCriterion = new ExpressionFilterCriterion(
propertyLocator, FilterCondition.CONTAINS, filterText);
setFiterCriterion(filterCriterion);
}

Resources