I have a data table that needs to be refreshed upon using an ajax command found in each row.
<div class="authorSection">
<h:dataTable id="author-table" var="author" value="#{authorPOCBean.getauthors()}">
<h:column>
<f:facet name="header">
<h:outputText value="Org Short Name" />
</f:facet>
<h:outputText id="authorOrganizationShortName" value="#author.orgShortName}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Organization Name" />
</f:facet>
<h:outputText id="authorOrganizationName" value="#{author.orgName}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Location" />
</f:facet>
<h:outputText id="authorLocation" value="#{author.orgLocation}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="author Type" />
</f:facet>
<h:outputText id="authorType" value="#{author.authorName}" />
</h:column>
<h:column>
<h:form id="deleteauthorForm">
<h:commandLink action="#{authorPOCBean.deleteauthor(author)}" value="Delete">
<f:ajax render=":author-table"/>
</h:commandLink>
</h:form>
<h:form id="setInitialauthorForm">
<h:commandLink action="#{authorPOCBean.makeInitialauthor(author)}" value="Make Initial"/>
</h:form>
</h:column>
</h:dataTable>
</div>
When the delete function is used it seems to leave the table unchanged or perhaps renders it with old data? I've got it set now to the first thing the called method does is change the internal array THEN changes the database stuff but it still uses the old data.
Is there something obviously wrong with my code?
I have looked at the below link and tried the recommendations and have no new result. In fact if I surround the table with a form the table won't build right.
JSF- <f:ajax> can't render datatable
Please be noted that you have placed the Delete Button and Make initial Buttons enclosed in a separate form whereas the DataTable component is placed outside the form .
Try having a single form starting at at the start of the table . (ie) Your table component and the two buttons should be enclosed within the same form
and for Ajaxical refresh, the following should work for you .
<f:ajax render="#form"/>
If for some other reason you cannot use a single form and need multiple forms , Please refer this question How to retain form data in a multi form page
Related
I have a datatable listing some items with several details :
<h:dataTable id="versionInterfaces_datatable"
styleClass="datatable" rowClasses="odd,even"
value="#{versionToolManager.version.interfaces}"
var="lInterface">
<h:column>
<f:facet name="header">Interface Name</f:facet>
<h:commandLink id="versionInterfacesName_columnLink"
value="#{lInterface.name}"
action="#{interfaceManager.consult}">
<f:setPropertyActionListener
target="#{interfaceManager.interfaceEntity}"
value="#{lInterface}" />
</h:commandLink>
<h:outputText id="versionInterfacesName_column" value="#{lInterface.name}" />
</h:column>
<h:column id="interfaceVersions_column">
<f:facet name="header">Interface Version(s)</f:facet>
<ui:repeat value="#{lInterface.versionsInterface}" var="lVersionI"
varStatus="lStatus">
<h:outputText rendered="#{lVersionI.versionsTools.contains(versionToolManager.version)}" value=" #{lVersionI.name} | " />
</ui:repeat>
</h:column>
<h:column>
<f:facet name="header">Interface Description</f:facet>
<h:outputText id="versionInterfacesDescription_column"
value="#{lInterface.description}" />
</h:column>
and then I have a button calling a modal view allowing to add items :
<h:commandButton id="#{id}OpenModal_button"
value="#{openButtonValue}"
onclick="document.getElementById('#{formId}:#{modal_panel}').style.display='block'; return false;" />
<br />
when closing this modal view, I try to "refresh" the datatable to see the items added :
<h:commandButton id="#{id}CloseModal_button"
value="#{closeButtonValue}">
<f:ajax execute="#this"
render="#{renderOnClose} #{formId}:#{modal_panel}" />
</h:commandButton>
But the columns of my datatable are not all updated, the column "Interface Version(s)" is empty for the new lines corresponding to the new items even though when I save, they have been well added.
Do you have any idea ?
the problem is <f:ajax execute="#this" ...
use <f:ajax execute="#all" ...
So I succeed to solve my problem but it wasn't a problem about the syntax but a bad use of the model and beans structure. Without going into details, I was trying to reach data which weren't linked to the corresponding items.
i have an h:dataTable with
<h:column>
<f:facet name="header">
<h:inputText value="#{proxyUserListHandler.usernameSearch}" styleClass="form-control" p:placeholder="username">
<f:ajax event="keyup" execute="#this" render=":form1:updateme" />
<f:ajax event="change" execute="#this" render=":form1:updateme" />
</h:inputText>
</f:facet>
</h:column>
is it possible to only render the tbody? Because when i render the whole table the input looses focus
the only possibility i found was creating the table manually with ui:repeat and then give the tbody an id with the new html5-jsf integration
xmlns:jsf="http://xmlns.jcp.org/jsf"
<tbody jsf:id="table_body">
now i can access it
<f:ajax render="table_body"
I have a <h:dataTable> with a <h:commandLink> in a column and a <h:outputext> outside the <h:dataTable> which I need to render by the command link.
<h:form>
<h:dataTable value="#{userControl.lista}" var="c">
<h:column>
<f:facet name="header" >
<h:outputText styleClass="leftColumn" value="Nombre"/>
</f:facet>
#{c.nombre}
</h:column>
<h:column>
<f:facet name="header" >
Usuario
</f:facet>
<h:commandLink actionListener="#{userControl.setAdmin_user(c.user)}" value="#{c.user}">
<f:ajax render="output" />
</h:commandLink>
</h:column>
</h:dataTable>
<h:outputText id="output" value="#{userControl.admin_user}"/>
</h:form>
It does not work. If I move the <h:outputText> inside the same column, then it works.
How is this caused and how can I solve it?
The client ID as you currently have in the <f:ajax render> does not start with the default NamingContainer separator character : and is therefore relative to the current NamingContainer component, which is in your case the <h:dataTable>. So it will work only when the outputtext component is also in the same datatable.
You need to refer the outputtext component by an absolute client ID instead. For starters who do not have memorized all NamingContainer components yet, the easiest way to find it out is to check the id attribute of the generated HTML element in the webbrowser. Open the page in webbrowser and do View Source and locate the <span> element generated by <h:outputText id="output"> and take exactly this ID and prefix it with : to make it absolute to the view root.
E.g.
<span id="formId:output">
where formId is the ID of any <h:form> for the case the outputtext is enclosed in a <h:form>. If you don't have specified a fixed ID for the <h:form>, then JSF will autogenerate one. You'd like to specify a fixed ID then like <h:form id="formId">.
So the <f:ajax render> should look like this then
<f:ajax render=":formId:output" />
I have a datatable which has a "delete" button at each row,
and I want to re-render the table when the data at the row is deleted.
But I can not make f:ajax work properly.
Here is the datatable at facelet page:
<h:form>
<h:dataTable value="#{adminPanelBean.activitiesList}" var="activityItem" id="allActivities"
styleClass="datatable" cellpadding="2" cellspacing="4"
columnClasses="ColName,colType,colTime,colPlace,colSummary" >
<h:column>
<f:facet name="header">
<h:outputText value="Etkinlik"/>
</f:facet>
<h:outputText value="#{activityItem.name} "/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Türü"/>
</f:facet>
<h:outputText value="#{activityItem.type}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Tarih "/>
</f:facet>
<h:outputText value="#{activityItem.time}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Yer "/>
</f:facet>
<h:outputText value="#{activityItem.place}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Açıklama "/>
</f:facet>
<h:outputText value="#{activityItem.summary}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value=" "/>
</f:facet>
**<h:commandButton value="Delete activity" onclick="if(confirm(' Delete #{activityItem.name} ?'))return true; else return false;" action="#{adminPanelBean.deleteActivity(activityItem.id)}">
<f:ajax event="click" render="allActivities" execute="#all" immediate="true"/>
<f:param name="activityId" value ="#{activityItem.id}" />
</h:commandButton>**
</h:column>
</h:dataTable>
</h:form>
When I refresh the page, I see the row is deleted. But I want it to be done dynamically.
In the action method you need to remove the item from the list as well (and thus not only from the DB). I'd suggest to pass the whole item instead of only the ID so that you can utilize List#remove() method.
action="#{adminPanelBean.deleteActivity(activityItem)}">
So that you can do
public void deleteActivity(Activity activity) {
activitiesList.remove(activity);
// ...
}
Unrelated to the concrete problem, they way how you used confirm() is pretty clumsy.
onclick="if(confirm(' Delete #{activityItem.name} ?'))return true; else return false;"
That function returns a boolean already. You do not need to test the obtained boolean within an if in order to return another boolean. Just simplify it as follows:
onclick="return confirm('Delete #{activityItem.name}?')"
I have tried making an ajax call for a selectOneMenu using JSF 2 and primefaces 2.2. The actionListener method is being called. But the columns I specified in the update attribute are not getting updated. When I refersh the page, I could find the updated values. Please help me out in this.
The code I used was
<h:form id="mainForm" prependId="false">
<p>
<p:tabView>
<p:tab title="Receipt">
<p:dataTable id="table1" var="recepit" rowIndexVar="rowIndex" value="#{ReceiptDetailsBean.iterativeList}" scrollable="true" height="120px" styleClass="leftTable">
<p:column style="background-color: #EFF2F9">
<f:facet name="header">
<h:outputText value="SL NO" />
</f:facet>
<h:outputText value="#{rowIndex+1}" />
</p:column>
<p:column >
<f:facet name="header">
<h:outputText value="Buss." />
</f:facet>
<h:selectOneMenu id="selectOneCb4" value="#{ReceiptDetailsBean.bussCode}" >
<f:selectItem itemLabel="V_BUSS_CODE" itemValue=""/>
<f:selectItems value="#{ReceiptDetailsBean.rdetails}" var="model" itemLabel="#{model.buss}" itemValue="#{model.buss}"/>
<p:ajax update="table1:#{rowIndex}:receiptCode, table1:#{rowIndex}:referenceType" actionListener="#{ReceiptDetailsBean.obtainReceiptDatabasedOnBussCode}" event="change"/>
</h:selectOneMenu>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Receipt Code" />
</f:facet>
<h:inputText value="#{ReceiptDetailsBean.receiptCode}" id="receiptCode" style="font-family: verdana;font-size: 10px;width:80px;height:15px" onkeypress="return showForhotKey(event,'#{rowIndex}');"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Ref Type" />
</f:facet>
<h:inputText value="#{ReceiptDetailsBean.receiptType}" id="referenceType" style="font-family: verdana;font-size: 10px;width:80px;height:15px" onkeypress="return showForhotKey(event,'#{rowIndex}');"/>
</p:column>
</p:dataTable>
</p:tab>
<p:tab title="Print">
</p:tab>
Try f:ajax instead of p:ajax and re-render the whole form to get closer to the problem source :
<h:selectOneMenu id="selectOneCb4" value="#{ReceiptDetailsBean.bussCode}" >
<f:selectItem itemLabel="V_BUSS_CODE" itemValue=""/>
<f:selectItems value="#{ReceiptDetailsBean.rdetails}" var="model"
itemLabel="#{model.buss}" itemValue="#{model.buss}"/>
<f:ajax render="#form"
listener="#{ReceiptDetailsBean.obtainReceiptDatabasedOnBussCode}"/>
</h:selectOneMenu>
This should work as stated in my answer to your previous question.
Partial updates of dataTables and ajax updates of dataTables triggered from a component within the dataTable are not working in the 2.2 version of Primefaces. This is a known bug that may have been resolved in version 3.
One suggestion you can try is to use a single form for each dataTable and only update elements from within that one form.