JSF - How to reset the <ice:dataTable> value list - jsf

Couple of days ago I started JSF with Iceface. I have a dataTable and when I delete a row,
It deletes the particular list entry from the back-end. Also dataTable remove a row, but not the one I deleted.
(It is not about the complete row. Its only a column.)
I'm using a suggestion box for each row. Problem only happens with that suggestion box field. But without that suggestion box, it works fine.
I thought if I could refresh/sync again the dataTable with it's bean property, just before rendering it, might solve the problem.
(From back-end it maintains the exact data set that I want to populate in my dataTable.)
At the moment what I want to know is, how can we re-sync the dataTable with it's new value, before render the response.
If you have any other idea please share it with me.
Thanks!

I have done a mistake :(
I haven't add the value="#{o.itemId}" property.
This is my suggestion box.
Thanks!
<ice:selectInputText id="sugestBox" rows="10" width="290"
listVar="item"
valueChangeListener="#{o.itemAutoCompleteBean.updateList}"
actionListener="#{o.lst}"
listValue="#{o.itemAutoCompleteBean.matchesList}"
value="#{o.itemId}">
<f:facet name="selectInputText">
<ice:panelGrid columns="3" style="margin-bottom:20px; "
columnClasses="sgstItemDropCol,sgstItemDescCol,sgstItemCatCol" >
<ice:outputText value="#{item.itemId}"/>
<ice:outputText value="#{item.description}"/>
<ice:outputText value="#{item.category}"/>
</ice:panelGrid>
</f:facet>

Related

Action-listener on Rowtoggle-ajax event in datatable gets incorrect parameter-value

I have a datatable with a rowtoggler:
<p:dataTable expandedRow="#{line.toggled}"
value="#{cartController.getLines(agreement.id)}"
var="line" widgetVar="table" rowIndexVar="rowIndex">
<p:ajax event="rowToggle"
listener="#{cartController.toggleAndSaveLine(line)}"
disabled="#{facesContext.validationFailed}"/>
...
</p:dataTable>
My goal is to keep track of which row that is toggled on the server side, so I call toggleAndSaveLine in my cartController on rowToggle. My problem is that no matter which one of the rows I toggle, the line-parameter in toggleAndSaveLine-method will always be the last element in the provided list of values, making it impossible to keep track of which row that was toggled. The strange thing is that I use the var line in other similar AJAX-calls and there it works perfectly.
Any ideas what might be wrong? I'm using PF6.

What does <f:facet> do and when should I use it?

I have been having trouble with the tag <f:facet>. I am working form other examples of code which use it, but I'm not sure exactly what purpose it serves.
I have written some code which in method is exactly the same as other code I have seen which works, except there's is wrapped in a <f:facet name=actions> tag. When I add this around my code the drop down box I am wrapping it around disappears when I deploy. Anyone able to suggest a reason for this or give me an insight into how and when to use facet?
Here is my code, I won't bother adding the bean code as they're just basic getters and setters and I don't think they're causing the trouble.
<f:facet name="actions">
<p:selectOneMenu id="SwitchWeekDrpDwnMenu"
value="#{depotWorkloadBean.selectView}"
partialSubmit="true">
<p:ajax update="mainForm"
listener="#{depotWorkloadBean.updateView}" />
<f:selectItem itemLabel="Day view" itemValue="Day"/>
<f:selectItem itemLabel="01/01/2014" itemValue="Week"/>
</p:selectOneMenu>
</f:facet>
If I remove the facet tag the dropdown box displays, but doesn't function as it should with the beans.
A facet represents a named section within a container component. For example, you can create a header and a footer facet for a dataTable component.
https://web.archive.org/web/20170828020413/http://www.jsftoolbox.com/documentation/help/12-TagReference/core/f_facet.html
It's useful when you want to create component that uses some code from user (let's say wrapper).
ie. when you want to create component that hides long text and shows short version of it. You can use just the element body, but then you will get only one value, if you want to get from user the short AND the long version then you can not do it in one value (without using some discriminant), just use facet and say which one is the long and which is the short version.
<textShortener>
<f:facet name="short">
This text is short.
</f:facet>
<f:facet name="long">
This text is too <b>long</b> to be showed when page loads. User have to click the button after the short text to show this.
</f:facet>
</textShortener>
Yes, this can (and should) be done with jsf templating, but I hope you got it.
To question: you defined facet just in the wild xml, nobody requested it so nobody processed it - that's why it did not throw error nor showed anything.

Delete entity of repeat in form and visualize result with update does not work

I have an List of Items, where I want to be able to add and remove items. For that, I add the whole List in a and everytime add or remove an item, I call update from primefaces. The code looks like this:
<h:panelGroup id="group">
<ui:repeat value="#{manager.values}" var="item">
<p:inputText value="#{item.name}"/>
<p:commandButton value="Remove" action="#{manager.remove(item)}" onsuccess="update_values();"/>
</ui:repeat>
</h:panelGroup>
<p:remoteCommand update="group" name="update_values"/>
<p:commandButton value="Add" action="#{manager.newValue()}" update="group"/>
Adding works fine, but everytime I call remove, the behaviour is strange. The item, which is the most right is deleted, and the name of the others remain unchanged, even if I remove the most left item.
After some debugging, I found out that this is because of the value="#{item.name}": The item is deleted correctly, but after the deletion, the value of the fields that exist are set for the values the fields had before. So all in all, the most right field does not exist anymore, because ui:repeat has one item less, but the others get the values they had before, so it is only possible to remove the most right field.
Has anybody an hint how to solve this? One solution maybe would be to clear every field with javascript, but I'd rather like the frameworks to solve the problem than to code something myself.
Try it like so:
<p:commandButton value="Remove" action="#{manager.remove(item)}" update=":directPath:group" process="#this" />
maybe the fact that there is no hard update on the button itself might be the cause.
PS
Is there an <h:form> around your element?

p:dataList inside of p:dataTable

I'm using <p:dataTable> to show the values of my files. Inside of each file is a list of metadates. I want to show each metadate as an own column beside the other columns of the file. (I excluded the other columns to make the code more readable).
So, my problem is, that with the <p:dataList> it does not show the columns. The name of the meta is the same in every metadata, if someone believes this to be the problem.
I already tried to use <p:dataTable> instead of <p:dataList>, but as my customer originally wanted to have the metadata shown as own column this would not be my preferred way, but on the other hand it is working.
<p:dataTable id="fileList" var="f" value="#{reader.files}" rendered="#{reader.showFileTable()}">
<p:dataList value="#{f.meta}" var="meta1">
<p:column>
#{meta1.value}
</p:column>
</p:dataList>
<p:column headerText="Metadaten">
<p:dataTable value="#{f.meta}" var="meta">
<p:column headerText="#{meta.name}">
#{meta.value}
</p:column>
</p:dataTable>
</p:column>
</p:dataTable>
I am really grateful for any help, how I could make the code work so that each metadate has it's own column in the fileList-dataTable.
P.S: I already tried c:forEach and ui:repeat which also didn't work.
P.P.S: I forgot to mention, that my customer sometimes don't want to see specific metadates, so it would be very nice when it is possible to do this with the suggested solution.
You can build columns dynamically in primefaces by using the <p:columns> tag see the vdl
check the primefaces showcase for an example
Suppose you have this code:
<p:dataList id="fileList" var="f" value="#{reader.files}">
<p:dataTable value="#{f.listItems}" var="meta1">
<p:column>#{meta1.value}</p:column>
<p:columns value="#{meta1.listItems}">...</p:columns>
</p:dataTable>
</p:dataList>
Dynamic columns in nested dataTable are not generated: it seems p:columns cannot refer var like "f" and "meta1".
I can understand "meta1" is not visible, because it's producing header's table, but I really can't understand why "f" is not visible at that time.
Any idea? Thanks.

<rich:datatable> and <rich:datascroller> problem

I am developing a Seam-Jsfv1.2-EJB3 web app.
I have a datatable and checkboxes in each row. Moreover, I have a datascroller at the bottom of my table as well.
My problem is when I click the next page number from the scroller, the selected checkboxes at the first page of the datatable is gone. I mean, even if they were selected, clicking the next page make them deselected. I see it by going back to the first page again by clicking the scroller.
Do you have any idea about that problem?
In order to clearify my case, I attached my code below:
<rich:dataTable
id="apiV2ProductList" rows="10" var="_apiV2Product"
value="#{apiV2ProductList.resultList}"
rendered="#{not empty apiV2ProductList.resultList}" reRender="ds">
<rich:column>
<f:facet name="header">
<h:selectBooleanCheckbox id="selectionCheckAll" onclick="selectAll()" />
</f:facet>
<h:selectBooleanCheckbox id="selectionCheck" onclick="increase(this)" value="#{_apiV2Product.selectValue}" >
</h:selectBooleanCheckbox>
</rich:column>
...
<f:facet name="footer">
<rich:datascroller id="ds" renderIfSinglePage="false">
</rich:datascroller>
</f:facet>
Many thanks in advance.
Baris
You can extend the org.richfaces.renderkit.html.DatascrollerTemplate
write your own DataScroller for your own styling by adding a component with the below configuration in faces-config.xml
<component>
<component-type>exCustHtmlDatascroller</component-type>
<component-lass>org.jsf.common.ui.EXCustHtmlDatascroller</component-class>
</component>
<render-kit>
<renderer>
<component-family>org.richfaces.Datascroller</component-family>
<renderer-type>exCustDataScrollerTemplate</renderer-type>
<renderer- class>org.jsf.common.ui.EXCustDataScrollerTemplate</renderer-class>
</renderer>
</render-kit>
Adding an a4j support tag between scroller has solved my problem:
<f:facet name="footer">
<rich:datascroller id="ds" renderIfSinglePage="false">
<a4j:support event="onpagechange"/>
</rich:datascroller>
</f:facet>
However the other thing is, I am using JQuery to style my table (ex. on mouse over and out), and this time, when I click the next page of my table, the style is gone.
Any help would be great, many thanks in advance.
**
PS: BTW the wierest thing to my mind is it comes me impossible to find a solution by yourself for this kind of problems. Your creation may not always be enough to solve (at least here in my example, adding a4j:support thing) I am asking experts, how can we handle that kind of things by ourselves...
**
You don't need jQuery for styling the datatable
<rich:dataTable id="dataTable" var="x"
onRowMouseOver="this.style.backgroundColor='#F1F1F1'"
onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'"
The problem you were seeing with the styles being removed is due to the nature of AJAX, and the way the table is reRendered.
Assuming you were firing the initial styling call based on some form of page onLoad, the first time the page is rendered, your styles will be applied. However, when you click the "next" button with the paginator, you are pulling a lot of new HTML down, and replacing the old HTML in the table with the newer, updated information. The proble you're seeing is that you saw styling because jQuery applied styles to the old nodes, upon reRender, those nodes are completely thrown away, along with their styling. You simply need to figure out the hook to call the "styling" method, and re-execute that call after the table is re-rendered.
Generally, I use an a4j:status tag, and set up the onstart or onstop to re-parse the table.

Resources