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

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.

Related

Pagination not working in jsf rich:datascroller

how to make work rich:datascoller with nested components.
Data table iteration works fine but pagination is not working.
does rich:datascroller works with nested component?
<a4j:repeat >
<rich:datatable id="test">
......
</rich:datatable>
<rich:datascroller for="test"></rich:datascroller>
</a4j:repeat >
any help will be greatly appreciated
Firstly please answer the my question asked in comment section.
About your issue i do not know why you did not add at lease full code of Datatable .
If you read the documentation of the component(Rich_Datascroller) its mentioned below thing
The component should be placed into the footer of the parent table or be bound to it with the "for" attribute. Note, that "for" is
evaluated on view build, not on view render, that is why it will
ignore JSTL tags.
The table should also have the defined "rows" attribute limiting the quantity of inputted table rows.
The scroller could limit the maximum quantity of rendered links on the table pages with the help of the "maxPages" attribute.
So according to above points its look like you missed
The table should also have the defined "rows" attribute limiting the
quantity of inputted table rows.
As per documentation its a mandatory. point to remember . Apart from your issue its good practice before asking in stackoverflow create a simple example and try it out of the box.
About my question I am more interested to know how your code will be work without generating dynamic id as per your code your component id is Static . It should throw the exception because <a4j:repeat> nothing but a for loop.

How to make Bootsfaces datatable display a dialog box on row selection

Currently working on a project which uses Bootsfaces. I have a bootsfaces datatable in which i need to open a dialog box upon row selection. Please advice how to proceed.
Below is the code
<b:dataTable onclick="$('viewBKDDialog').show()"
update=":ViewBKDForm"
value="#{bookingAdminController.itemsBookDet}"
var="car" ajax="true" select="true" responsive="true" >
</b:dataTable>
and i m using
<ui:include src="ViewBookingDetails_all.xhtml"/>
as the dialog box.
Currently, I don't have the complete solution, but let's analyze your code. That's interesting enough.
First of all, you want to open a modal dialog based on the selected row. (Actually, the "modal dialog" bit is an educated guess). However, you added the onclick handler to the entire table. JSF doesn't make the rows explicit, so you have to add the onclick handler to the cells of the table. For the sake of simplicity, let's assume you've assigned the onclick handler to a button within the table.
Second, there's a bug in every BootsFaces version <= 0.9.1 that prevents you from detecting which row has been selected. So you have to use a version >= 0.9.2. At the time of writing, that's the developer snapshot BootsFaces-0.9.2-SNAPSHOT. See issue 369 on how to get it and issue 486 on the row-select bug I've recently solved.
Third, you should take in mind that the JavaScript code of the onclick handler is executed before the AJAX request. I can only guess, but I assume that you want to update the content of the modal dialog based on the row selection. I also assume that the content is defined by an AJAX request. If both assumptions are true, you've got a problem. The onclick handler is executed before the AJAX call. So I suggest you use the oncomplete JavaScript callback handler that's offered by some BootsFaces components, such as b:commandButton.
Like I've said before, that's not a complete solution, but I hope it helps nonetheless.

How to show edit button in datatable for limited number of records in primefaces?

I am displaying records using datatable. I am showing a edit & delete button for each row. But now I want to show edit/delete button only for first 30 records. Can someone tell me how can I do this?
First of all define rowIndexVar attribute value for p:datatable
<p:dataTable rowIndexVar="rowIndex">
Now you can achieve it client side using rendered attribute :
rendered="#{rowIndex lt 30}"
Since you are using primefaces button then code would be :
<p:commandButton value="edit/delete" rendered="#{rowIndex lt 30}" />
Steps:
You want the button to conditionally render, so confirm that you
understand how to conditionally render a component (use rendered).
You want to only render the first 30 records, so confirm that you
understand how to access the loop index.
Combine the two, and you have a working solution.
If you have any specific problem performing these steps that you cannot solve yourself, please feel free to post another question.
I feel that your question lacks information but I'll try to be of some help..
You seem to be using JSF. Since you are using JSF you'd probably best solve this on the server side, in your backing-bean.

Unable to paste the context in Primefaces Extension pe:inputNumber using mouse

We've been using Primefaces (v 3.5) and Primefaces Extensions (v 0.7.0) in our project and it's been great, cheers for the developers and community!
The inputNumber component takes care of pretty much all of our needs when dealing with decimal fields.
The one thing that isn't working is when the user paste a value into the field using the mouse right button then paste option.
When that happens, it seems these values aren't processed, since when I submit the form they are cleared, no matter it's a valid or unvalid value.
The user can even paste a text into the pe:inputNumber. The control c + control v works as expected, no problem at all.
The code we are using is like this:
<pe:inputNumber id="AmtInTxt" value="#{myController.amtField}" symbol="$ "/>
Any ideas of how can we make the context menu paste works like the control c + control v?
Community Post
Was this ever solved? For future viewers - this looks like an issue with not posting the data to the bean when using the mouse. Try putting an ajax event handler in your input field.
<pe:inputNumber ...>
<p:ajax event="blur"/>
</pe:inputNumber>
I've encountered same problem. At first I thought it happens only when using browser's autocomplete feature. From this post I've learned that it is strictly connected with just changing value via mouse. I am using <p:ajax event="blur" process="#this" /> and it doesn't change anything. More specifically, the value is empty within the InputNumberRenderer.getConvertedValue method and since then it passes null value to setter/listener.
EDIT: Also tried putting onstart="$(event.target).keypress()" within the ajax to simulate user's keypress. Sadly doesn't work.

JSF datatable working with two sets of data

I'm new to JSF and have a problem trying to display a subset of data in JSF datatable.
Problem description:
1. I have a datable bound to the model like below:
<h:dataTable border="1" cellspacing="0" cellpadding="0" id="invoiceLinesUpperDt" styleClass="basic-table" value="#{pc_InvoiceCRMVUpdate.viewBean.showInvoiceLinesInError? pc_InvoiceCRMVUpdate.viewBean.invoice.invoiceLinesInError : pc_InvoiceCRMVUpdate.viewBean.invoice.invoiceLines}" var="invoiceLine">
I have a checkbox that triggers between two datasets like below:
<h:selectBooleanCheckbox id="displayOnlyLinesInErrorCb" immediate="false" value="#{pc_InvoiceCRMVUpdate.viewBean.showInvoiceLinesInError}" onclick="javascript: document.forms['invoiceCRMVUpdateForm'].submit();" valueChangeListener="#{pc_InvoiceCRMVUpdate.displayOnlyLinesInError}"/>
When the full list of data (returned by pc_InvoiceCRMVUpdate.viewBean.invoice.invoiceLines)is displayed there is no problem - I can edit and submit values and get them populated in data model correctly
The problem appears when the subset of data (returned by pc_InvoiceCRMVUpdate.viewBean.invoice.invoiceLinesInError) is displayed. I still can edit the data BUT when I trigger back to full list the data appears in wrong rows. For example if the first row of subset was edited then they appear in the first row of full set and so on.
In the restore view phase the correct data model method is called. So I expect to get values at the correct places in the subset. But I don't get them.
What can be the problem?
Thanks in advance!
Roman.
Found the problem. It was a luck of experience with JSF and stupid mistake.
Just left FacesContext.getCurrentInstance().renderResponse(); inside the value change listener #{pc_InvoiceCRMVUpdate.displayOnlyLinesInError}.
After removed that line of code everything became working!

Resources