I use sorting in primefaces datatable and it's does not work with paginator. Where I made a mistake?
<p:column headerText="Year" sortBy="#{questionnaireListBean.getQuestionnaireData(questionnaire, 'YEAR')}">
#{questionnaireListBean.getQuestionnaireData(questionnaire, 'YEAR')}
</p:column>
And view scoped bean with init data in #PostConstruct method:
public String getQuestionnaireData(Questionnaire questionnaire, String column) {
return questionnairesData.get(questionnaire).get(column);
}
So the true title of your question is : "Sorting and pagination not working together in lazy loading datatable, primefaces", that's more of a precise description of your problem.
As for the issue, it apprears that you should expect the problem. In this link, the question was "Is there any datatable JSF component than can perform lazy load pagination, and filtering and sorting on server side. If I need to implement my own solution thanks to the teams that made client side sorting and filtering, they are useless", to which the answer came "No, there isn't. Because the component library cannot know what will be the persistence mechanism.". Of course that dated from 2010...
Taking a look into Primefaces user guide 3.5, it apprears that sorting/paginator/lazy loading can cohabit, but that's more elaborte then just adding sortBy to your columns.
In fact, checking page 144 of the guide, you can see that you need to :
have a LazyDataModel object in your bean ;
Override the load method of this object ;
Bind the value of your datatable to this model.
Doing this, you might have sorting along with lazy loading. Haven't tried it, but this seems to adress your issue.
Best of luck.
Related
Clearly I am missing something. What I read about RowSets(Cached/Filtered/Joined) is that they are Beans capable.
So, on my .xhtml, I have the following kind of code, and I am using PrimeFaces 5.x
...
<p:dataTabel var="aRow" value="#{pageBean.List<Type>}">
<p:column value="#{aRow.property}" / >;
...
</p:dataTable>
If I use one of the RowSets to fetch my data, where do I define it so that I can access it without having to copy everything into Lists ?
Thanks,
Nick
The PrimeFaces datatable at this time of writing (5.2) does not support this. The reason for this is outlined in the link below, but it boils down to the fact that the current implementation of the PF datatable needs the total 'rowcount' and a rowset does not support this.
See also
http://forum.primefaces.org/viewtopic.php?f=3&t=4500
I'm working with JSF 2.2 with Primefaces 4.0 and I need to create a questionnaire with a dynamic amount of questions. This questions are radio type questions with 4 options each and I'm wondering the best (or easiest) way to do this. As far my research goes one way of doing this is using DynaForm from Primefaces extensions (The current way I'm trying to do it). Another possible way of doing this is by creating a List<Question> where
Public class Question{
//Something like this
private String question;
private List<String> options;
and calling it in a similar way as BalusC does it in his answer on dynamic adding radio and InputText in jsf. However, in my opinion, Datatable does not seems like a good solution for a SelectOneRadio type of input (Question plus all 4 options) As it does for inputText like on his original answer.
So which one is the best (easiest/simpler) way of doing this, and if it's like BalusC how should the valueChangeListener of the selectOneRadio be implemented so the String question and the selected answer of that question can be obtained for each question in the questionnaire, following (or Redefining if necessary) the provided Question class.
I'm using Primefaces 3.3.1 with Tomcat 7.0.22.0.
I have p:dataTable which has p:inputText in it. The id of that p:dataTable is "houseTabID:tabView:form0:table". This is copy-pasted from HTML source. And I let dialog (which is outside of the form dataTable resides) open by button in p:dataTable, and p:commandButton in that dialog updates the dataTable.
p:commandButton looks like this;
<p:commandButton ajax="true" action="#{myBean.setInputText()}"
value="OK"
update="#{myBean.getUpdateTarget(0)}"/>
myBean.getUpdateTarget(0) retruns proper string to point target component.
I can successfully update whole dataTable by specifying "houseTabID:tabView:form0:table" (meaning myBean.getUpdateTarget(0) returns that string). But I have many lines in the table so updating whole table takes longer to finish, and scroll position is reset which is really irritating. That makes me want to update only one row in the table, not whole.
So I first returned "houseTabID:tabView:form0:table:inputBox" to update p:inputText that I want to update. In p:dataTable I have something looks like this;
<p:column headerText="Value"
width="300" style="height:16px; font-size:9pt;">
<p:inputText id="inputBox" value="#{myItem.value}"
style="width:95%; height:11px; font-size:9pt;">
<f:ajax execute="#this" event="blur" />
</p:inputText>
</p:column>
Result: no update, no error log. I know "houseTabID:tabView:form0:table:inputBox" won't work since it does not specify row in table. So by using rowIndexVar, I tried with "houseTabID:tabView:form0:table:0:inputBox" with making :0: part from rowIndexVar. The string is copy-pasted from HTML source. But unfortunatelly, I got exception.
javax.faces.FacesException: Cannot find component with identifier ":houseTabID:tabView:form0:table:0:inputBox" referenced from "houseTabID:j_idt181:j_idt186".
Why? There is obviously "houseTabID:tabView:form0:table:0:inputBox", I see it on HTML source, and I can update whole talbe with "houseTabID:tabView:form0:table" but throw exception with "houseTabID:tabView:form0:table:0:inputBox"? It does not make sense to me. Also, then, why it won't throw any exception or spill out error log with "houseTabID:tabView:form0:table:inputBox"? I verified HTML source of that p:commandButton;
onclick="PrimeFaces.ab({source:'houseTabID:j_idt190:j_idt195',update:'houseTabID:tabView:form0:table:inputBox',
I desparately want to update just one row instead of whole p:dataTable. Please help me.
I found a solution. According to this conversation,
position = JQuery(".ui-datatable-scrollable-body").scrollTop();
JQuery(".ui-datatable-scrollable-body").scrollTop(position);
can do the trick. It seems this is the only way to get and set vertical scroll position of p:dataTable. I saved position before opening dialog, and set position after updating p:dataTable from dialog. It worked and this is what I wanted to do.
But above method has serious issue. That code scans given class ".ui-datatable-scrollable-body" from top and perform at the first found one. So it works only for one p:dataTable. Fortunately I could come up with 2nd solution.
<script type="text/javascript">
$ = jQuery;
var scrollPos;
function saveScrollPos()
{
scrollPos = $("#houseTabID\\:tabView\\:form0\\:table_data").parents(".ui-datatable-scrollable-body").scrollTop();
}
function getScrollPos()
{
$("#houseTabID\\:tabView\\:form0\\:table_data").parents(".ui-datatable-scrollable-body").scrollTop(scrollPos);
}
</script>
FireBug in FireFox helped me find out there is componnet id which "_data" is appedded by Primefaces. Please see my question, my data table's id is "table" and someone created "table_data". And I could point it with escaped syntax shown above and function parents() leads to that spot. It is working fine in my applictaion.
I really thank stier01 who posted his solution which is the only one I could find over the net. And I really feel sad that Primefaces p:dataTable does not support such a basic thing. I know many of us wanted to keep scroll position of p:dataTable when updating it. I hope it will be improved in near future.
I am teetering on the edge of what I know here but I suspect that it may be happening because of the timing of the page construction. When the DOM tree is built, your table rows do not yet exist so your button outside of the table cannot find the reference to the row (because it does not yet exist). After the tree is built and the data is filled in, the row is then there. That is why after the page renders you can look up the column id, but not reference it from outside of the table. I am not sure of a solution. Maybe you can put a remote command in the datatable tags to update it. Maybe can do something in JS.
I have one searched arraylist that i am getting from Database for that array list i want to apply paginataion with links First, Prev, Next, Last and Goto page dropdown here i don't want to call database for every request(i.e First,Prev,etc) i want to use arrylist that returned at the time of search.And one more requirement is field level sorting need to do Ascending,descending if user clicks on header field.can any one help me to fix this i want to use only JSF2 no RichFaces,etc
Thank in advance.
Why do you not want to use rich or prime faces or others? Just use primefaces datatable with paginator="true".
If you don't want it, but want to do it the hard way. I suggest you fetch everything from database. Use a datatable and in the getter of that table, you only give back a portion of your array. (index 10 to 20, or index 20 to 40 or...)
On top or bottom of your datatable you put some outputlinks. These can set the indexes you want to retrieve.
Hope my explanation is clear.
In case Myfaces Tomahawk is an option for you...
I see it (Myfaces Tomahawk) as a bit different from PrimeFaces/Richfaces cause MyFaces are responsible for the MyFaces JSF Implementation as well (so it could be an excuse for using Myfaces Tomahawk), so you can use the Myfaces JSF implementation + Myfaces Tomahawk
Take a look at the Myfaces Tomahawk datascroller
This has to be a dumb question, but I can't seem to find the right keywords to google on: I have an action listener that can receive an event from any one of multiple checkboxes that were all generated from the same line of jsp in a dataTable. How can I tell from the action listener which one issued the event?
In particular, I need the index of the component so I can map it to an ordered list in the model. I know I can get the UIComponent object, and from there I can get the client ID of the component. And knowing that the client ID has the component's index embedded in it, yes I could do the sleazy thing, and parse the index from the client ID. But I know that would be a horrible, fragile and unmaintainable hack.
What's the right way to do this?
After an initial search, I think this could help you.
http://illegalargumentexception.blogspot.com/2009/02/jsf-working-with-component-ids.html
Have you tried to use f:param in addition to the checkbox values to pass custom parameters, so that would be more cleaner than working with ID's to manipulate business logic. ID.
Using the DataTables var attribute, you should be able to do this
<h:dataTable ... var="currentRow">
....
<h:selectBooleanCheckbox ... actionListener="#{blah.doThis}">
<f:attribute name="curRec" value="#{currentRow}" />
</h:selectBooleanCheckbox>
bean:
public void doThis(ActionEvent ae)
{
TreeMap myMap = (TreeMap)ae.getComponent().getAttributes().get("curRec");
...
}
Edit: The binding variable of your datatable should have the method getRowIndex();. That should give you the index of the record that caused the event in the table. I'm referencing an ICEfaces project, so I apologize if that isn't correct. Let me know, thx.