Webflow's flow scope and making primefaces graphicImage work - primefaces

I am using a spring bean with flow scope which has a primesfaces's StreamedContent field and the image does not show up. Any ideas on how to make this work with flow scope? It works fine when it is a managed bean with request scope and also when it is a spring bean with session/prototype/singleton scope.
Below is some sample code:
flow:
<input name="springBean" required="false"/>
<view-state id="testFlow">
<transition on="post" to="testFlow" />
</view-state>
xhtml file:
<ui:define name="body">
<h:form>
<p:graphicImage value="#{springBean.barcode}" cache="false"/>
<br />
<h:outputText value="This is a test flow" />
<br />
Message From Spring = #{springBean.text}<br />
<h:inputText value="#{springBean.text}" style="width:200px" />
<h:commandButton action="post" value="Update" />
</h:form>
</ui:define>
application context:
<import resource="flowConfig.xml" />
<bean name="springBean" class="swfproject.MessageHolder" scope="flow">
<property name="text" value="This was defined in Spring" />
</bean>

The only way I have found so far is to extend GraphicImage component and make it store binary content in the Session. See How to make Primefaces graphicImage work with Spring Web Flow

Related

Why are comopnents of another form validated with JSF 2.3?

I just upgraded to JSF 2.3 & Wildfly 14 (from 2.0 and 13) and primefaces 6.2.5.
I noticed a strange behavior when i use a command button. I have 2 forms and when a push the button of the first form, the input of the second form is validated and the error (in this case required errors) are displayed in a p:message :
<h:form id="form1" prependId="false">
<p:commandButton id="save" value="Save" actionListener="#{myBean.save()}" update="#form">
<f:actionListener binding="#{myBean.reloadResults()}" />
</p:commandButton>
<p:messages id="msgs" severity="error,warn" escape="false">
<p:autoUpdate />
</p:messages>
...
</h:form>
<p:dialog >
<h:form id="form2" >
<p:messages severity="error,warn" escape="false">
<p:autoUpdate />
</p:messages>
<div>
<p:calendar id="myDate" value="#{myBean.myDate}" required="true" />
</div>
...
</h:form>
</p:dialog>
I was expecting only the content of the first form to be processed and validated. This was the case with wildfly 13 and jsf 2.0.
Any idea?
You have not specified attribute process in your command button. Default value of this is #all which will validate all Forms.
Please use process="#form" to avoid validation and process of other form.
Updated code is as below:
<p:commandButton id="save" value="Save" actionListener="#{myBean.save()}" update="#form" process="#form">
<f:actionListener binding="#{myBean.reloadResults()}" />
</p:commandButton>
I have to apologize for not posting the entire code but it would have been to big. I found out what the problem was. It's related to this bug:
https://github.com/primefaces/primefaces/issues/4122
I have a panelgrid of 4 columns but with 10 elements in it.
The whole ajax communication was then broken. Fix is coming in PF 6.3

ajax event not working

I have a form that should appear when the checkbox is true. This won't work. weird thing is : I did exactly the same on another page and there it works. Also when using another boolean property in the backing bean itself it works.
<div class="field">
<p:outputLabel for="company" value="Company" />
<p:selectBooleanCheckbox id="company" value="#{participantDetailBean.participant.isCompany}">
<p:ajax event="change" update="companyFields"/>
</p:selectBooleanCheckbox>
</div>
<p:outputPanel id="companyFields">
<div class="field">
<p:outputLabel for="companyname" value="Company name" rendered="#{participantDetailBean.participant.isCompany}" />
<p:inputText id="companyname" value="#{participantDetailBean.participant.companyName}" rendered="#{participantDetailBean.participant.isCompany}" />
</div>
<div class="field">
<p:outputLabel for="companyform" value="Company form" rendered="#{participantDetailBean.participant.isCompany}" />
<p:inputText id="companyform" value="#{participantDetailBean.participant.companyForm}" rendered="#{participantDetailBean.participant.isCompany}" />
</div>
<div class="field">
<p:outputLabel for="companynumber" value="Company number" rendered="#{participantDetailBean.participant.isCompany}" />
<p:inputMask id="companynumber" value="#{participantDetailBean.participant.companyNumber}" mask="aa 9999.999.999" rendered="#{participantDetailBean.participant.isCompany}" />
</div>
</p:outputPanel>
Sometimes Primefaces has its moments when components that works on one page, simply refuses to work on another page. The code you've posted in your example is correct and most likely if you place a break point on the company getter, when the ajax event change is triggered, the value will update correctly. What's happening is that your component is not refreshing correctly via the ajax (or is not recognized).
A workaround solution that I found is to this scenario is to include JSF's PanelGroup inside the OutputPanel. I used the base of your code and made the below example (obviously replacing tags I have in my project with the objects as per your example.
<div class="field">
<p:selectBooleanCheckbox id="company"
value="# {participantDetailBean.participant.isCompany}">
<p:ajax event="change" update=":companyFields"/>
</p:selectBooleanCheckbox>
</div>
<p:outputPanel id="companyFields">
<h:panelGroup id="companyFields2" rendered="#{participantDetailBean.participant.isCompany}">
<div class="field">
<p:outputLabel value="DISPLAY THIS FIELD"/>
</div>
</h:panelGroup>
</p:outputPanel>
Whilst this is not the cleanest solution, it might help you get out of the rut you're currently stuck in, or guide you in obtaining the correct answer. Oh, and don't forget to include the JSF include tag when using PanelGroup
xmlns:h="http://xmlns.jcp.org/jsf/html"
Try to use the itemSelect event.

What happens when more than one AJAX event used for a component

I am using JSF 1.2, Richfaces 3.3.3 with Tomcat 6.
I have called two AJAX event methods for a single component and both event reRender the component.
My Sample code :
<h:outputLabel id="ct3lbl1" value="CT3 No " />
<rich:spacer width="1" height="1" />
<h:selectOneMenu id="ct3serial" value="#{PurchaseOrder.ct3SerialNo}" style="width:160px;">
<f:selectItems value="#{PurchaseOrder.ct3serialList}" />
<a4j:support event="onchange" action="#{PurchaseOrder.loadSupDetails}" ajaxSingle="true" reRender="ct3serial,tablepanel" />
<a4j:support event="onblur" action="#{PurchaseOrder.ct3validate}" ajaxSingle="true" reRender="valctserial,ct3serial" />
</h:selectOneMenu>
<h:outputText id="valctserial" value="#{PurchaseOrder.valct3serial}" style="color: red;" />
I stuck at an issue Duplicate Id Exception in auto generated client id.
My Question is using more than one AJAX request for a component and rendering the component is a reason for this exception.Suggest me to overcome this issue.

PrimeFaces + SWF : commandButton doesn't trigger any action/event within dataTable depending on objects source

I have run into a strange problem/bug and couldn't find a working solution anywhere...
The situation is : I have a Spring Web Flow calling a view state which contains a dataTable showing a list of object with an "Edit" button next to each of them.
Here is what the SWF looks like:
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
parent="parent-flow" start-state="home">
<persistence-context />
<var name="myObject" class="com.domain.MyObject" />
<view-state id="home">
<on-render>
<evaluate expression="myObjectService.findAll()"
result="viewScope.myObjectList" result-type="dataModel" />
</on-render>
<transition on="edit" to="editMO" />
<transition on="search" to="home" />
</view-state>
<subflow-state id="editMO" subflow="myObject/addEdit">
<input name="myObject" required="true" />
<transition to="end" />
</subflow-state>
<end-state id="end"
view="externalRedirect:servletRelative:/home" />
</flow>
Some explanation :
1) the "MyObject" class is a simple pojo with some attributes and an entity annotation for persistence.
2) the "myObjectService.findAll()" gives me back the list of all the stored "MyObject".
Now here is the view code (which use a template standard.xhtml) :
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"
template="/WEB-INF/layouts/standard.xhtml">
<ui:define name="title"></ui:define>
<ui:define name="content">
<h:form>
<div>
<p:dataTable id="tbl" value="#{myObjectList}" var="item">
<f:facet name="header">Result list</f:facet>
<p:column>
<f:facet name="header">Name</f:facet>#{item.name}
</p:column>
<p:column>
<f:facet name="header">Description</f:facet>#{item.description}
</p:column>
<p:column>
<f:facet name="header">Whatever</f:facet>#{item.whatever}
</p:column>
<p:column>
<f:facet name="header">Actions</f:facet>
<p:commandButton value="Edit" action="edit" icon="ui-icon-edit">
<f:setPropertyActionListener value="#{item}"
target="#{myObject}" />
</p:commandButton>
</p:column>
</p:dataTable>
</div>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
When I click on one of the "Edit" button, the trace the tells me the view is re-rendering but the action/event "edit" is never ever triggered, detected nor catched anywhere (that I know of at least).
Funny thing is : if I move the call to the service (to load the object list) from the Flow to the dataTable "value" attribute inside the view like this :
<p:dataTable id="tbl" value="#{myObjectService.findAll()}"
Everything works perfectly fine! but then I get way to many calls on every render event (seen up to eleven...) which I obviously don't want.
I saw many posts on subjects close to my problem but none could solve it (tried to change the flow redirection attribute "redirect-in-same-state" to false, force lazy to off, change the scope of components and variables, force the scope of the service or backing bean, and so on...)
So since I'm running out of ideas anyway I thought i would give this a shot in here. Anybody has an idea?
Well, the question was asked a long time ago, but I'm facing the same problem now. So here is what I found out.
The last SWF Booking-faces (Web Flow: 2.4.0.M1) sample has the same problem.
At the "main-flow.xml" it defines:
<view-state id="enterSearchCriteria">
<on-render>
<evaluate expression="bookingService.findBookings(currentUser?.name)" **result="viewScope.bookings"** result-type="dataModel" />
</on-render>
<transition on="search" to="reviewHotels"/>
<transition on="cancelBooking">
<evaluate expression="bookingService.cancelBooking(bookings.selectedRow)" />
</transition>
</view-state>
And at "enterSearchCriteria.xhtml" it declares a <p:dataTable> that iterates over the bookings.
The dataTable has this column definition:
<p:column>
<f:facet name="header">Action</f:facet>
<p:commandButton id="cancel" value="Cancel" action="cancelBooking" update=":bookings"/>
</p:column>
When you click the Cancel button nothing happens. I can see by looking at the trace that the view is re-rendering but the method "bookingService.cancelBooking(bookings.selectedRow)" is never called.
But if I change the scope of the "bookings" variable to "conversationScope" it works:
<view-state id="enterSearchCriteria">
<on-render>
<evaluate expression="bookingService.findBookings(currentUser?.name)" **result="conversationScope.bookings"** result-type="dataModel" />
</on-render>
<transition on="search" to="reviewHotels"/>
<transition on="cancelBooking">
<evaluate expression="bookingService.cancelBooking(bookings.selectedRow)" />
</transition>
</view-state>
Is this a bug with viewScope/flowScope?
Try adding the immediate="true" attribute to the commandButton.
This gives the button priority over the validation and the action should be processed.

An error occurred during conversion seam text to html

I am using the following rich:editor control to create a new message. I choose Heading 1 under Format drop down and entered some text and persist the entry. But when I try to edit the message it fails with the following error on load. How should I fix this issue?
An error occurred during conversion seam text to html
<s:decorate template="/layout/edit.xhtml">
<ui:define name="label">Message</ui:define>
<rich:editor required="true" id="messageField" theme="advanced" useSeamText="true" viewMode="visual" autoResize="true" value="#{newsHome.instance.message}">
<f:param name="theme_advanced_buttons1" value="newdocument,separator,cut,copy,paste,separator,bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,hr,removeformat,visualaid,separator,sub,sup"/>
<f:param name="theme_advanced_buttons2" value="bullist,numlist,separator,outdent,indent,blockquote,separator,undo,redo,separator,link,unlink,anchor,separator,image,cleanup,help,code,separator,forecolor,backcolor"/>
<f:param name="theme_advanced_buttons3" value="fontselect,fontsizeselect,formatselect,styleselect,separator,charmap"/>
<f:param name="theme_advanced_resizing" value="true"/>
<f:param name="theme_advanced_toolbar_location" value="top" />
<f:param name="theme_advanced_toolbar_align" value="left" />
</rich:editor>
</s:decorate>
That sounds like a problem we had with rich:editor whenever someone entered content with an odd number of underscores. It was caused by a bug in RichFaces, and we fixed it by upgrading RichFaces to 3.3.3.