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

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?

Related

How do I make sure that update is called after action?

I want to update the inputText with the new value that is set by the remoteCommnad. I think the update is called by the time the value is not yet set on the server-side. Therefore my inputText remains empty/unchanged after the command went through.
<p:remoteCommand name="sendUrl"
action="#{myBean.sendImgUrlToBean}"
update="image-url"/>
<p:inputText id="image-url"
value="#{myBean.image.imageUrl}"/>
Along the way I tested with a <p:commandButton value="update me" update="image-url"/> below the inputText field to see if it would update. That worked out.

Adding command button in p:schedule header

How do i add a "custom" button in p:schedule? I tried doing it with the help of a header facet like in the p:dataTable component, but to no avail.
Sorry for being unclear initially, it also probably didnt help that someone butchered my question by editting it's title, here are more details with snippets of code.
I want to do somthing similar to this:
<p:tab title="#{bean.name}" value="bean" >
<f:facet name="title">
<h:outputText value="#{bean.name}"/>
<p:selectBooleanButton styleClass="...">
<p:ajax converter="... />
</p:selectBooleanButton>
</f:facet>
</p:tab>
The code is creating a tab (for an accordionpanel) with a text+button in it instead of the default text only.
I am looking for the same behaviour in a p:schedule component.
<p:schedule value="#{scheduleView.lazyEventModel}" leftHeaderTemplate="today" centerHeaderTemplate="prev, title, next" rightHeaderTemplate="month, agendaWeek" >
<f:facet name="header">
<h:outputText value="#{bean.name}"/>
<p:commandButton styleClass="..."/>
</f:facet>
</p:schedule>
The same add a button to the header principle, except this time on schedule. And of course since schedule does not have any facets available for overwriting this approach does not work.
Finally, my question is: How do I add a button in the p:schedule header like in the picture above?
P.S: Forgive me for confusing you people with datatable, used it because it supports multiple facets (header, footer).
Client side it is all html that can be manipulated with javascript (jquery if you like).
So if you create your schedule and button like this:
<h:panelGroup id="mySchedule">
<p:schedule value="#{scheduleView.lazyEventModel}" leftHeaderTemplate="today" centerHeaderTemplate="prev, title, next" rightHeaderTemplate="month, agendaWeek"/>
<h:outputText value="#{bean.name}" id="scheduleOutputText"/>
<p:commandButton styleClass="..." id="scheduleCommandButton"/>
</h:panelGroup>
You can move the h:outputText and p:commandButton into the schedule with jquery dom manipulation.
$("#scheduleCommandButton").insertBefore(".fc-left");
$("#scheduleOutputText").insertBefore("#scheduleCommandButton");
If you put this script inside the panelGroup and update the panelGroup each time you'd normally update the schedule via ajax, the button and text should be added moved again in an update.
<h:panelGroup id="mySchedule">
<p:schedule value="#{scheduleView.lazyEventModel}" leftHeaderTemplate="today" centerHeaderTemplate="prev, title, next" rightHeaderTemplate="month, agendaWeek"/>
<h:outputText value="#{bean.name}" id="scheduleOutputText"/>
<p:commandButton styleClass="..." id="scheduleCommandButton"/>
$("#scheduleCommandButton").insertBefore(".fc-left");
$("#scheduleOutputText").insertBefore("#scheduleCommandButton");
</h:panelGroup>
You could also put the text and button in a panelgroup and move that by dom manipulation. Just make sure you use the right selectors (I did not prepended the form id to the selectors above). You can also use class selectors instead of id's. That is up to you.
But make sure you use this with care. As #JasperDeVries mentioned in a comment, it is easy to break things. Use it just sparsely, carefully and only as a last resort

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.

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

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>

filtering <rich:column> in composition component

Hopefully someone can help, because I am quite stuck on this issue. I cannot find much help elsewhere...
The high-level goal: creating a custom tag that will aid in the reuse of an extendedDataTable in Richfaces. I have a custom tag that I would like to be similar to:
<mytag:customTable bean="#{myBean}"/>
The (simplified) file that contains code for the table is as follows (table.xhtml)
<!--...header stuff -->
<ui:component>
<a4j:outputPanel>
<h:form>
<rich:extendedDataTable
value="#{bean.theData}"
var="entity"
id="table">
<rich:column filterMethod="#{...}">
<f:facet name="header">
<h:inputText value="#{bean.filterValue}">
<a4j:support event="onkeyup" reRender="table"/>
</h:inputText>
</f:facet>
<h:outputText value="#{entity.item}"/>
</rich:column>
</rich:extendedDataTable>
</h:form>
</a4j:outputPanel>
</ui:component>
Due to the constraints of the application, using the filterBy="#{...}" attribute inside the <rich:column> tag does not give me what I need.
Accordingly, I have to use the filterMethod attribute. When I hardcode the table with,
<rich:column filterMethod="#{bean.filterFunction}">
then everything works fine. However, I would like to keep the tag more general and NOT hardcode this. Instead, I would like
to also pass the name of the filtering function (e.g. <mytag:customTable bean="#{myBean}" flFcn="#{myBean.filterFunction}"> ). The problem is that
I cannot get any version of this to work properly.
From searching other threads, I see that the way to pass a method to an 'action' attribute has a syntax like: action="#{bean[fcnName]}" where fcnName is just a String (see http://digitaljoel.nerd-herders.com/2009/08/25/passing-action-methods-in-facelets-using-array-notation/).
I have confirmed that this way works correctly when it's an action . However,
this does not seem to help me in this case with filterMethod (perhaps b/c the function signature is different?). Based on those solutions, I would need something like:
<mytag:customTable bean="#{myBean}" flFcn="filterFunction"> with <rich:column filterMethod="#{bean[flFcn]}">
I have not found anything among the many permutations of EL syntax that works. Everytime, this approach throws an exception saying that 'bean' resolved to null.
To check that the bean was actually recognized, I had it print a String via <h:outputText value="#{bean.someString}"/>
(removing the offending filterMethod=...)and there is NO problem. Therefore the problem seems to lay entirely on whatever filterMethod receives. I found what I believe to be a very similar issue here, but that does not seem to be answered.
Thanks in advance!
I'm facing the same problem using RichFaces 3.3.3 and JSF 1.2 without having a usable solution.
Found a JIRA-entry at RichFaces which is still open and thus probably will not be fixed anymore.

Resources