How to update a component inside of dataTable from outside of it - jsf

I am using Mojarra implementation of JSF 2.1 with Primefaces 3.2.
My problem approximately looks like this:
<p:dialog id="someDialog">
..
<h:form id="dialogForm">
<p:commandLink action=".."update=":someForm:someUIRepeat:someDataTable:someInputTextArea"/>
</h:form>
</p:dialog>
<h:form id="someForm">
<ui:repeat id="someUIRepeat" value=".." ..>
<p:dataTable id="someDataTable" value=.. >
<p:column>
<p:inputTextarea id="someInputTextarea" value=../>
<p:column>
.. here go other columns
<ui:repeat>
</h:form>
The issue is that when I click on the commandLink in the dialog the inputTextarea is not updated. However, if I write this in the update of the commandLink:
update=":someForm:someUIRepeat:someDataTable,:someForm:someUIRepeat:someDataTable:someInputTextArea"
then the whole dataTable gets updated and the inputTextarea updates as well, but the values in the fields located in other columns get erased after I click on the commandLink in the dialog.
The reason why I put dataTable inside of ui:repeat is that I need to bind a dataTable with each row of one collection and I think it's not related to my problem.
Any ideas how I can solve this problem?
Thanks in advance,
Nurzhan.

for start try this
added onclick="jQuery('#someForm:someButton').click();"(check the exact id of your hidden button) to your <p:commandLink inside the dialog
set the update to update=":someForm:someUIRepeat:someDataTable"
and add
<h:commandButton id="someButton" style="display:none">
<f:ajax execute="#form"></f:ajax>
</h:commandButton>
to <h:form id="someForm">
explanation: the purpose of the hidden button is to execute (send its values) the form to the server so that when you do call update the fields wont be erased...

Related

JSF Datatable update component when changing page (outside of Datatable)

<p:dataTable value="#{bean.list}"
var="q"
styleClass="data-apresenta"
rowIndexVar="qi" itemType="none"
paginator="true"
rows="1"
id="dataL">
</p:dataTable>
<h:outputLabel id="anyComponenteID" value="Test"/>
I have this test code but, how can i update anyComponenteID when I paginate through primefaces datatable ?
Note : component is outside of dataTable.
You could bind an ajax listener to the page event inside primefaces datatable, you will need to set your form to prependId="true" so you can reach components outside of the datatable.
The code will look like something like this:
<p:ajax event="page" process="#this" update=":form-id:mycomponent-id"/>

Multiple values for the update attribute on p:commandButton

I am new in Primefaces, i would like to know if i can use two values for the attribute update on primefaces commandButton component:
My code
<p:messages id="messages" ...../><!-- not always updated -->
<h:form>
...
<p:commandButton ....action="search" update="#all :messages"/>
..
</h:form>
<h:form>
<p:panel header="Number of element in the the table:#{bean.number}">
<!--not always updated -->
<p:datatable>
<!-- always updated -->
</p:datatable>
</p:panel>
</h:form>
When i did this, the header of the panel component is not updated.
When i put only update="#all", the messages component (p:messages) is not updated even with autoUpdate="true"
Can you help me please !
Don't use #all, is bad practice (http://forum.primefaces.org/viewtopic.php?f=3&t=6956#p36841).
If you want to update a specific component or form you can use jQuery Selectors: PFS (PrimeFaces Selectors) - Showcase
So, you can put an id on the second form and specify it in the update attribute.

Primefaces blockUI to block a DataTable doesn't work when the DataTable is updated via AJAX [duplicate]

I am trying to create a datatable that displays a blockUI whenever it is busy, and I have been mostly successful. It now grays out and shows "Loading..." whenever I click either of two commandButtons, sort the datatable by clicking on a header, or page through the datatable. You can see the code for it below.
The problem is that after I have used one of the commandButtons (which runs an ajax update on the blocked element), subsequent actions do not trigger the blockUI (until I refresh the page). For example:
Load page
Click a datatable header - blockUI appears until table is finished sorting
Click one of the datatable page navigation buttons - blockUI appears until the page is loaded
Click one of the commandButtons - blockUI appears until the button's actionListener has finished
Click a datatable header - table sorts, but blockUI does not appear.
Click one of the datatable page navigation buttons - page loads, but blockUI does not appear
Click one of the commandButtons - actionListener runs and table updates, but blockUI does not appear
Reload the page - everything works properly again
Changing the commandButtons' update="" attribute to ajax="false" causes the sorting/paging to always display the blockUI, but the commandButtons to never display the blockUI.
Any ideas?
<div class="buttonDiv">
<p:commandButton ... update="resultsPanel" id="submitButton" ... />
...
<p:commandButton ... update="resultsPanel" id="resetScenarioButton" ... />
</div>
<p:panel header="Results Grid" id="resultsPanel">
...
<p:dataTable ... id="VAResults" ... >
...
</p:dataTable>
....
</p:panel>
<p:blockUI block="resultsPanel" trigger="submitButton, resetScenarioButton, VAResults">
Loading...
</p:blockUI>
The trigger attribute binds jQuery listeners on the specified elements. However if you update an element the binding gets lost. I don't know if it works, but you could try moving the <p:blockUI inside the resultsPanel. I suspect that when you update the panel the blockUI gets updated too and thus re-binding the listener to the data table.
<p:panel header="Results Grid" id="resultsPanel">
...
<p:dataTable ... id="VAResults" ... >
...
</p:dataTable>
....
<p:blockUI block="resultsPanel" trigger="submitButton, resetScenarioButton, VAResults">
Loading...
</p:blockUI>
</p:panel>
I've had the same problem and kind of simillar scenario:
<p:dataTable>
....
<p:ajax event="rowSelect" update="buttons" global="false" onstart="blockMessageButtons.show();" oncomplete="blockMessageButtons.hide();"/>
</p:dataTable>
<p:outputPanel layout="block" id="buttons">
<!-- content to be blocked -->
</p:outputPanel>
<p:blockUI block="buttons" widgetVar="blockMessageButtons"/>
The problem was that panel buttons was both updated by ajax, and blocked by blockUI. I had to divide it in two:
<p:dataTable>
....
<p:ajax event="rowSelect" update="buttons-content" global="false" onstart="blockMessageButtons.show();" oncomplete="blockMessageButtons.hide();"/>
</p:dataTable>
<p:outputPanel layout="block" id="buttons-container">
<p:outputPanel layout="block" id="buttons-content">
<!-- content to be blocked -->
</p:outputPanel>
</p:outputPanel>
<p:blockUI block="buttons-container" widgetVar="blockMessageButtons"/>
#siebz0r already provided the explanation why blockUI stops working when a component is updated.
I am using a one blockUI element in the template for all other pages and thus don't want to include more blockUI elements.
If the blockUI element is updated as well one does not need to move the blockUI inside the component that will be updated.
Here is an example:
<p:panel id="surroundingPanel">
...
<p:commandButton value="ButtonName" styleClass="blockUi"
action="actionToBeExecuted" update=":surroundingPanel :blockUiBinding" />
</p:panel>
<p:outputPanel id="blockUiBinding">
<p:blockUI block=":elementToBeBlocked" trigger="#(.blockUi)">
Loading ...
</p:blockUI>
</p:outputPanel>
The element blockUiBinding can be located anywhere, as long as it can be updated. It is wrapping the blockUI element, because blockUI generates at least two different divs. So when the wrapping element is updated also the blockUI will be updated.

primefaces panelgrid update from datatable

I am getting "Cannot find component with identifier "contentForm:tabView:form:addressDialogPanel" referenced from "contentForm:tabView:form:addressBookTable" " error. How can I update my panelGrid inside the widget?
<h:form id="form">
<p:dataTable id="addressBookTable">
<p:ajax event="rowSelect" listener="#{addressBookController.onRowSelect}"
update="contentForm:tabView:form:addressDialogPanel" oncomplete="addressDialog.show()" />
</p:dataTable>
<p:dialog id="addressDialogId" widgetVar="addressDialog">
<h:panelGrid id="addressDialogPanel" columns="2" cellpadding="4">
</h:panelGrid>
</p:dialog>
</h:form>
The main problem is that you are giving the wrong client ID of component's. Also p:tabView is a component it is not a form. When you define a h:form, it generates a standart HTML form element. And when you submit the page JSF uses POST to submit your data into backing bean. So nesting them is going to occur lot's of issues that you don't expect. You should seperate forms into sections like sideForm or searchForm or etc.
You should detect the correct client ID of your component when you try to update it. You can do this with your browser's developer settings(press f12 for chrome). Then select component with the magnifier button and give that ID into update property. Just like here:
You should read to learn basics of JSF for example from here

JSF Primefaces TabView problems

I asked this in the PF Forum but no one seems to want to answer so I though I'd try my luck here.
I have a ui:repeat that is not being updated correctly after an Ajax call when it is within a TabView.
Simple scenario is I have a ui:repeat pointing at an ArrayList (ArrayList contains simple pojos with a String). Within this I have an h:inputText whose value is the pojo's String getter/setter. The ui:repeat is contained within a h:panelGroup. I use a p:commandButton to run an action to update the ArrayList (just add a couple of objects to it a Math.random value for the String) and then update the h:panelGroup. The updated values in the ArrayList are not reflecting in the ui:repeat input fields. This only appears to be affecting input fields as outputText fields do update correctly. Also if I do the same for a p:dataTable the input field are updated correctly. If I remove the Tabview and Tab tags it works fine.
As it works when removing the Tabs I can only assume this is a bug and not designed to work like this. If someone could please confirm if this is so or if there is a viable work around. I need to use a ui:repeat as my fields are not in a tabular format. This has only occurred since migrating from PF 2.2. I'm currently on PF 3.1, Weblogic 10.3.4 and Mojarra 2.0.4
<p:tabView>
<p:tab title="Test">
<h:form prependId="false">
<p:commandButton id="testStringCheck"
value="Test String Check"
process="#form"
update="testPanel"
action="#{testBean.generateVOwithRandomStrings}">
</p:commandButton>
<h:panelGroup id="testPanel" layout="block">
<ui:repeat value="#{testBean.voList}" var="entry">
<h:outputText value="#{entry.randomString}"/>
<p:inputText style="display:block;"
value="#{entry.randomString}"
size="15">
</p:inputText>
</ui:repeat>
</h:panelGroup>
</h:form>
</p:tab>
</p:tabView>
As a workaround I've used a p:datagrid instead of a ui:repeat. This achieves the look I had in the the ui:repeat so I'm happy. Hopefully this bug will be fixed on future releases.
This is something of a bug in Primefaces commandButton. See the following thread:
http://forum.primefaces.org/viewtopic.php?f=3&t=17454
You can try replacing
<p:commandLink id="testStringCheck" ... update="#form" />
With an <h:commandLink>
<h:commandLink id="testStringCheck" render="#form"/>
Also from the above link here is an interesting method that somebody posted that enables you to correctly find the correct clientId to update.
http://paste.kde.org/177698/
temp solution: insert outside h:panelGroup:
<p:outputPanel defered="true" delay="1" ..>
and update outputPanel instead of panelGroup
Or use a datalist component instead of ui:repeat.
One more, i'm not sure but you can try, so update class instead id:
<h:panelGroup id="testPanel" layout="block" styleClass="testPanelCl" ../>
and update : #(.testPanelCl), don't forget id of panelGroup, without id JSF can not update by class

Resources