Tomcat
Tomcat

Reputation: 1415

Can't update component in p:dataTable (not whole p:dataTable) in Primefaces

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.

Upvotes: 0

Views: 2799

Answers (2)

Tomcat
Tomcat

Reputation: 1415

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.

Upvotes: 1

SteveS
SteveS

Reputation: 1030

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.

Upvotes: 0

Related Questions