I'm using SpringBoot 2.7.5 with Primefaces 12.0.0
I'm having some trouble with uploading a file to the server because if I put enctype="multipart/form-data", and I click on the button, the function specified on action attribute isn't called at all
The .xhtml
<!DOCTYPE html>
<ui:composition template="./template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">
<ui:define name="component">
<h:form id="form" enctype="multipart/form-data">
<p:fileUpload value="#{uploadFilesController.file}" mode="simple" skinSimple="true"/>
<p:commandButton value="Submit" ajax="false" action="#{uploadFilesController.parseFile}" skinSimple="true"/>
</h:form>
</ui:define>
</ui:composition>
The Bean
#Component
#ViewScoped
public class UploadFilesController implements Serializable {
private static final long serialVersionUID = 1L;
public UploadedFile file;
public UploadedFile getFile() {
System.out.println("getFile");
return file;
}
public void setFile(UploadedFile file) {
this.file = file;
System.out.println("SET!");
}
public void parseFile() {
System.out.println(file.getFileName());
if (file != null) {
FacesMessage message = new FacesMessage("Successful", file.getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, message);
}
}
#PostConstruct
public void init() {
}
}
When I click the button, after selecting some file the page updates but nothing happens on the backend.
If I remove the enctype="multipart/form-data", I get an error about the file is null.
Actually you can try my following example in order to create an automatic fileUpload.
web.xml (not sure if necessary)
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-lass>
</filter>
.xhtml
<h:form enctype="multipart/form-data">
<p:fileUpload id="uploadFile" mode="simple" skinSimple="true"
value="#{backing.file}" label="Select new file"
auto="true" listener="#{backing.handleFileUpload}"/>
</h:form>
backing.java
public void handleFileUpload(FileUploadEvent event) {
UploadedFile newfile = event.getFile();
//do some checks on newly added file
}
Related
I got stuck with a problem which seems to have been solved here.
I want to use order list as it's in an example here.
But it doesn't work at all. I have nested <p:ajax> in order list like in an example.
Namely, I have got an error:
javax.servlet.ServletException: /resources/abc/rankingAnswer.xhtml #21,85<p:ajax> Unable to attach behavior to non-ClientBehaviorHolder parent
My Primefaces config in pom.xml is
<!-- prime faces -->
<primefaces.version>5.1</primefaces.version>
<primefaces.themes.version>1.0.10</primefaces.themes.version>
My view is
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<composite:interface>
<composite:attribute name="question" />
</composite:interface>
<composite:implementation>
<ui:decorate template="answerDecorator.xhtml">
<ui:define name="component">
<p:orderList value="#{cc.attrs.question.possibleAnswers}" var="answer" itemLabel="#{answer.text}" itemValue="#{answer}" controlsLocation="left" editable="true" >
<f:facet name="caption">#{msg['survey.default.makeOrder']}</f:facet>
<p:ajax event="reorder" listener="#{cc.attrs.question.onReorder}" />
<p:column>
<h:outputText value="#{answer.text}" />
</p:column>
</p:orderList>
</ui:define>
</ui:decorate>
</composite:implementation>
</html>
My model is
public class RankingQuestionDTO extends AbstractQuestionDTO implements Serializable {
private ArrayList<RankingAnswerDTO> possibleAnswers;
private boolean randomizeAnswers;
private String text;
public RankingQuestionDTO() {
super(QuestionType.RANKING);
this.text = MessageUtils.getBundle("survey.default.text");
this.possibleAnswers = new ArrayList<>();
this.possibleAnswers.add(new RankingAnswerDTO(MessageUtils.getBundle("survey.default.text")));
this.possibleAnswers.add(new RankingAnswerDTO(MessageUtils.getBundle("survey.default.text")));
this.randomizeAnswers = true;
}
public void onSelect(SelectEvent event) {
System.out.print(event.getObject().toString());
}
public void onUnselect(UnselectEvent event) {
System.out.print(event.getObject().toString());
}
public void onReorder() {
}
public void addEmptyPossibleAnswer()
{
this.possibleAnswers.add(new RankingAnswerDTO(MessageUtils.getBundle("survey.default.text")));
}
public ArrayList<RankingAnswerDTO> getPossibleAnswers() {
return possibleAnswers;
}
public String getText() {
return text;
}
public void setPossibleAnswers(ArrayList<RankingAnswerDTO> possibleAnswers) {
this.possibleAnswers = possibleAnswers;
}
public void setRandomizeAnswers(boolean randomizeAnswers) {
this.randomizeAnswers = randomizeAnswers;
}
public boolean getRandomizeAnswers() {
return randomizeAnswers;
}
public void setText(String text) {
this.text = text;
}
}
The PrimeFaces Showcase has the answer (emphasis mine):
Pojo Support with Clip Effect, Captions, Custom Content, Reorder Controls and Events (since v5.1.5)
As does issue 4501 (emphasis mine):
Added
select
unselect
reorder
Target is 5.1.5 Elite and 5.2 Community.
Have used setInterval to call ajax method which will render the value on page or probably keep updating the page. But in debug the control does not comes to ajax method in bean. please advise the issue in below code
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:body>
<script>
setInterval(function() {
document.getElementById("changeme").click();
}, 3000);
</script>
<h3>JSF 2.0 + Ajax Hello World Example</h3>
<h:form>
<h:inputText id="name" value="#{helloBean.name}"></h:inputText>
<h:commandButton value="Welcome Me">
<f:ajax execute="name" render="output" />
</h:commandButton>
<h2><h:outputText id="output" value="#{helloBean.sayWelcome}" /></h2>
<h2><h:outputText id="countsee" value="#{helloBean.name}" /></h2>
<h:commandButton id="changeme" style="display:none">
<f:ajax execute="#this" listener="#{helloBean.updates}" render="countsee" ></f:ajax>
</h:commandButton>
</h:form>
</h:body>
</html>
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.AjaxBehaviorEvent;
import java.io.Serializable;
#ManagedBean
#SessionScoped
public class HelloBean implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private static int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSayWelcome(){
//check if null?
if("".equals(name) || name ==null){
return "";
}else{
return "Ajax message : Welcome " + name;
}
}
public void getUpdates(ActionBehaviorEvent event){
System.out.println("Printing"+count);
this.name=name+"agdam";
}
}
Try giving the below:
public void updates(ActionBehaviorEvent event)
The method name and name given in the listener should be same.
I am learning JavaEE and I am playing around with ajax call with jsf and managedbean. I am trying to display the text as soon as i change the value from the drop down list. I see many people have the same problem on stackoverflow and i try to follow answers that are marked as accepted but I still can't make it work. Can someone please tell me where my error is?
Here is the jsf code:
<h:form>
<h:selectOneMenu id="productlist" value="#{productRepoMB.selectedProduct}">
<f:selectItems value="#{productRepoMB.productList}" var="product" itemValue="#{product.productID}" />
<f:ajax event="valueChange"
render="result"
listener="#{productRepoMB.selectMenuListener}" />
</h:selectOneMenu>
text changed: <h:outputText id="result" value="#{productRepoMB.text}" />
</h:form>
Here is managed bean code, Products list is populated from a database:
#Named
#RequestScoped
public class ProductRepoMB implements Serializable {
#EJB
private ProductsRepo productRepo;
private Products selectedProduct;
private List<Products> productList;
private String text="init text"; //use for testing ajax call
public ProductRepoMB() {
}
public Products getSelectedProduct() {
return selectedProduct;
}
public List<Products> getProductList() {
productList = productRepo.findAll();
return productList;
}
//The following code are used to testing ajax only!
public void selectMenuListener(AjaxBehaviorEvent e) {
setText("changed!");
}
public String getText() {
return text;
}
public void setText(String text){
this.text = text;
}
}
I have a few questions, I'm trying to find a tutorial of how to save a image onto a mediumblob column in my database using JSF, PrimeFaces (or if there is another way to do it) and Managed Bean, I know to do do it without JSF and Managed Bean, but since I'm new on these I stuck on a few things... I really have no idea of how to get the image from my JSF page, transform to a byte array and save it.
Please someone give a light.
Here is what I did, I'm sorry but I'm really new, so please help me.
JSF page:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:body>
<h:form>
<!-- <p:growl id="growl" showDetail="true" sticky="true" /> -->
<p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" />
<h:panelGrid columns="3">
<h:outputText value="ID : "/>
<h:inputText id="txtId" name="txtId" value="${produtoMB.prodAtual.id}" readonly="true"/>
<p:message id="a" for="txtId"/>
<h:outputText value="Foto:"/>
<p:fileUpload id="txtFoto" name="txtFoto" value="${produtoMB.prodAtual.foto}" />
<p:message id="i" for="txtFoto" showSummary="true" showDetail="false"/>
<h:panelGroup>
<h:commandButton name="cmd" value="Insert" action="${produtoMB.insert()}"/>
</h:panelGroup>
</h:panelGrid>
</h:form>
</h:body>
</html>
My Entity
#Entity
public class Produto implements Serializable {
private static final long serialVersionUID = -8914597399554711634L;
private long id;
private Byte[] foto;
#Id
#GeneratedValue
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
#Lob
#Column(columnDefinition="mediumblob")
public Byte[] getFoto() {
return foto;
}
public void setFoto(Byte[] foto) {
this.foto = foto;
}
}
Managed Bean
#ManagedBean
#SessionScoped
public class ProdutoMB implements Serializable {
private static final long serialVersionUID = -3304202810037758438L;
private Produto prodAtual;
public ProdutoMB() {
prodAtual = new Produto();
prodDAO = new ProdutoDAOImpl();
}
public String insert() {
try {
prodDAO.insert( prodAtual );
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
}
Thank you!
byte[] photo is not accessible in JSF page. Use UploadedFile in ManagedBean for primefaces.
<p:fileUpload id="txtFoto" name="txtFoto" value="${produtoMB.file}" />
UploadedFile should be property of managed bean.
#ManagedBean
#SessionScoped
public class ProdutoMB implements Serializable {
private UploadedFile file;
// To save use InputStrem and byte[] from file.
}
Also define fileupload filter in web.xml
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
I'm doing a multiple record editing in primefaces datatable, in the record editing there is file upload, which resets when the user presses the "add" button
The jsf code:
<!DOCTYPE html 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:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
<h:form enctype="multipart/form-data">
<p:dataTable var="file" value="#{fileUpload.files}" id="uploadTable">
<p:column>
<p:inputText value="#{file.id}"/>
<p:inputText value="#{file.name}"/>
<p:fileUpload value="#{file.file}" mode="simple"/>
</p:column>
</p:dataTable>
<p:commandButton value="Add" action="#{fileUpload.add}" update="uploadTable" />
<p:commandButton action="#{fileUpload.submit}" value="Submit" ajax="false" />
</h:form>
</h:body>
</ui:composition>
Here's the controller:
#ManagedBean(name = "fileUpload")
#ViewScoped
public class DummyFileUpload implements Serializable {
private static final long serialVersionUID = 1L;
private List<File> files;
#PostConstruct
public void init() {
files = new ArrayList<DummyFileUpload.File>();
}
public void submit() {
// submit
}
public void add() {
files.add(new File());
}
public List<File> getFiles() {
return files;
}
public void setFiles(List<File> files) {
this.files = files;
}
public class File implements Serializable{
private static final long serialVersionUID = 2685385696849425824L;
private String id;
private String name;
private UploadedFile file;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public UploadedFile getFile() {
return file;
}
public void setFile(UploadedFile file) {
this.file = file;
}
}
}
The file upload control is reset when I do ajax call, I know it's a normal behavior but I'm asking if there's a known workaround for this situation and what could be the best practices for a complex business like this ?
This can be avoided by changing the file upload tag to the following:
<p:fileUpload fileUploadListener="#{fileUpload.add}" mode="advanced" />
This way the Add and Submit buttons as well as the AJAX update are not needed as the advanced version of the file upload will provide the same functionality.
In addition, in your DummyFileUpload bean you wall have to change the add function:
public void add(FileUploadEvent event) {
files.add(event.getFile());
}