i am using the ace:fileEntry component to upload files
and after successful upload i get the message that:
'File Entry' uploaded successfully 'filename'.
and i want to override this message and display other message (some kind of a summary for parsing that uploaded file), any ideas how ?
here's my code:
<h:form>
<ace:fileEntry id="fileEntryComp"
label="File Entry"
relativePath="uploaded"
fileEntryListener="#{mybean.uploadFile}"/>
<h:commandButton value="Upload Excel File" />
<h:message for="fileEntryComp" />
</h:form>
The fileEntry.getResults().getFiles() gives you an ArrayList of FileInfo objects.
If you upload only one file, you can get the FileInfo the following way:
FileInfo fileInfo = fileEntry.getResults().getFiles().get(0);
You should call the updateStatus method of the FileInfo the following way to override the default message:
fileInfo.updateStatus(new FileEntryStatus() {
#Override
public boolean isSuccess() {
return true;
}
#Override
public FacesMessage getFacesMessage(FacesContext facesContext,
UIComponent fileEntry, FileEntryResults.FileInfo fi) {
return new FacesMessage(FacesMessage.SEVERITY_INFO,
"My success message: " + fi.getFileName(),
"My success message: " + fi.getFileName());
}
}, true, true);
You have to create your own message and send it. It will overwrite the default message. Its a strange behavior but it will work.
public void uploadFile(FileEntryEvent e) {
FileEntry fe = (FileEntry)e.getComponent();
FacesContext ctx = FacesContext.getCurrentInstance();
FacesMessage msg = new FacesMessage();
msg.setServity(FacesMessage.SERVITY_INFO);
msg.setSummary("mysummary");
msg.setDetail("mydetail");
ctx.addMessage(fe.getClientId(),msg);
}
You can check the showcase: http://comp-suite.icefaces.org/comp-suite/showcase.jsf?grp=aceMenu&exp=fileEntry
You can override icefaces messages.
Default message bundle (just to know which message to ovverride) can be found in icefaces source package:
icefaces3/ace/component/src/org/icefaces/ace/resources/messages.properties
where:
org.icefaces.ace.component.fileEntry.SUCCESS = ''{0}'' has successfully uploaded ''{1}''
org.icefaces.ace.component.fileEntry.SUCCESS_detail = ''{0}'' has successfully uploaded ''{1}''
and these are lines I put in my application.properties file:
org.icefaces.ace.component.fileEntry.SUCCESS = File ''{1}'' caricato correttamente
org.icefaces.ace.component.fileEntry.SUCCESS_detail = File ''{1}'' caricato correttamente
be sure to have application.properties defined in faces-config.xml and visible by you application:
<application>
<message-bundle>application</message-bundle>
<locale-config>
<default-locale>en</default-locale>
</locale-config>
</application>
This can be done with all Icefaces default messages ...
Related
Is it possible to somehow handle error on loading a PDF?
<p:media value="/resources/media/myDoc.pdf" width="100%" height="800px" zoom="100" player="pdf" cache="false"<>/p:media>
Let's say the PDF document it's not there and won't find it, If that happens my web app crash. Possible to handle it? So I show an error message instead in growl for example?
Thanks
You can check the #Jasper de Vries comment, otherwise you can verify if the file is present using a bean method like this:
MyBean.java
public String findFileURL() {
String fileName = "myDoc.pdf";
String relativeWebPath = "/resources/media/" + fileName;
FacesContext facesContext = FacesContext.getCurrentInstance();
String absoluteDiskPath = ((ServletContext) facesContext.getExternalContext().getContext())
.getRealPath(relativeWebPath);
File file = new File(absoluteDiskPath);
if (file.isFile()) {
return relativeWebPath;
} else {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "File: " + fileName + " not found.", "");
facesContext.addMessage(null, message);
return "";
}
}
MyPage.xhtml
<p:media value="#{myBean.findFileURL()}" width="100%" height="800px" zoom="100" player="pdf" cache="false"/>
I have an application with a file uploader and I would like to display some information from the selected files before the user uploads them.
E.g. The user selects a file to upload, the application, client side, then grabs that file and reads some information from it to display to the view. Then if it is what the user expects to see they can hit upload.
Is there a way to call a method in the backing bean when a file is selected and pass it that file, or does PrimeFaces not let this happen?
index.xhtml
<h:form id="uploadform" prependId="false" enctype="multipart/form-data">
<p:outputPanel id="container">
<center>
<p:fileUpload fileUploadListener="#{uploadBean.handleFileUpload}" mode="advanced"
dragDropSupport="false" allowTypes="/(\.|\/)(csv|xlsx)$/" update="messages"/>
<p:growl id="messages" showDetail="true" />
</center>
</p:outputPanel>
</h:form>
UploadBean.java
import org.apache.poi.util.IOUtils;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
#ViewScoped
#ManagedBean(name = "uploadBean")
public class NetezzaUploadBean implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private UploadedFile file = null;
#PostConstruct
public void init() {
}
public void getFileBeforeSubmit() {
//Where I want to do some work with the file
}
public void handleFileUpload(FileUploadEvent event){
FacesMessage message = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, message);
}
public UploadedFile getFile() {
return file;
}
public void setFile(UploadedFile uploadedFile) {
this.file = uploadedFile;
}
}
PrimeFaces p:fileUpload seems to have a great undocumented feature where you can make use of the native file input 'onAdd' event (or sort of). I found this in the source (which is open ;-)) of the 2-fileUpload.js file
if($this.cfg.onAdd) {
$this.cfg.onAdd.call($this, file, function(processedFile) {
file = processedFile;
data.files[0] = processedFile;
this.addFileToRow(file, data);
});
}
The cfg property from $this can be accessed via
PF('myWidgetId').cfg
And if you declare a function upfront like
function myOnAddHandler(file) {
console.log(file);
}
And add it to the widget with
PF('myWidgetId').cfg.myOnAddHandler;
You can select a file and before uploading see it logged in the console
File { name: "myImage.PNG", lastModified: 1533756086560, webkitRelativePath: "", size: 38344, type: "image/png" }
You can then extend this to use the HTML5 File API and read it
function myOnAddHandler(file) {
var reader = new FileReader();
reader.onload = function(readerEvt) {
var binaryString = readerEvt.target.result;
console.log(btoa(binaryString));
};
reader.readAsBinaryString(file);
}
PrimeFaces itself uses this sort of too in the related addFileToRow to show the preview
After looking in more of the java code of PrimeFaces, it might even be that instead of doing PF('myWidgetId').cfg.myOnAddHandler;, you could do <p:fileUpload onAdd="myOnAddHandler" .... /> I unfortunately do not have the time to test this right now but it might work.
I use a method like this for sending error messages to my facelet:
public static void addErrorMessage(String msg) {
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
FacesContext.getCurrentInstance().addMessage(null, facesMsg);
}
Then I show them inside a dialog with:
<p:messages id="messagesFattura" autoUpdate="true" />
And that works well. Now, my question is:
how can I "check" for messages existence?
I mean, there's another portion of code (a primefaces ) which I want to show/hide conditionally, via the rendered attribute.
I already tried the #{empty facesContext.messageList} EL variable, without success (empty list)
I am making multi-language website where I am using Validator for one field.
After validation, I receive response as err002, err003 and based on this error I would be showing the respective error in message format. So what I was planning is something like below.
What I have is <h:message for="password">
What I wanted to do is as below.
if (message is err002) {
show message of err002 from the properties file.
#{msg['err002']}
}
if (message is err003) {
show message of err003 from the properties file.
#{msg['err003']}
}
Any idea how to get this done?
Actually what I want to do is display error message in both language. What I have is language code in session bean, but I can't check language code in validators.
Any idea/ suggestion how this can be done would be greatful.
Edit 1
faces-config.xml
<application>
<locale-config>
<default-locale>zh_CN</default-locale>
</locale-config>
<resource-bundle>
<base-name>resources.welcome</base-name>
<var>msg</var>
</resource-bundle>
</application>
LanguageBean.java
#ManagedBean(name = "language")
#SessionScoped
public class LanguageBean implements Serializable {
Properties files that I have are
welcome.properties and welcome_zh_CN.properties
You can easily achive it in a validator method. Use it like
#FacesValidator("passwordValidator")
public class PasswordValidator implements Validator {
String err1, err2, err3;
public PasswordValidator() {
ResourceBundle bundle = ResourceBundle.getBundle("msg", FacesContext.getCurrentInstance().getViewRoot().getLocale());
err1 = bundle.getString("err1");
err2 = bundle.getString("err2");
err3 = bundle.getString("err3");
}
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
String pass = (String) value;
FacesMessage msg;
if(/*some condition*/) {
msg = new FacesMessage(err1);
} else if(/*other condition*/) {
msg = new FacesMessage(err2);
} else {
msg = new FacesMessage(err3);
}
if(msg != null) {
throw new ValidatorException(msg);
}
}
}
And use it in view with
<h:inputText id="password" validator="passwordValidator" .../>
<h:message for=password .../>
Along with couples inputText, one of a mandatory component that I have on the page is a p:fileUpload. So when I click submit, <p:message> show up on component that have require=true, but the user did not type/select
I want the red box Required also appear next to the upload component. Here is what I have tried.
1 . when I set required="true" in p:fileUpload, nothing really happen (not sure if this is a bug).
2 . I put validator in p:fileUpload, below is my validator sources
public void validateFileUpload(FacesContext context, UIComponent component,
Object value) throws ValidatorException {
if(value == null){
FacesMessage message = new FacesMessage();
message.setSeverity(FacesMessage.SEVERITY_ERROR);
message.setSummary("Error");
message.setDetail("Required");
throw new ValidatorException(message);
}
}
nothing really happen when I click submit, not even when I go through the upload, validateFileUpload did not get called at all (not sure if this is a bug)
3 . When I click submit, if everything else pass, and I get into my action method, I am able to check if the file is null or not, then return a FacesMessage and let p:growl pick it up. However, I dont like it that way since it give the user a feeling of multiple layer of validation.
Is there a way to do better validation on p:fileUpload?
For those with the same problem, I ran into this problem while creating a wizard. The workaround I used was to store the uploaded file in a field of my viewscoped bean and check this field when trying to navigate to the next step.
Wizard tag:
<p:wizard id="importBankAccountLogWizard"
widgetVar="importBankAccountLogWizard"
flowListener="#{bankAccountLogImportBean.onFlowProcess}">
File upload tag (I have the rendered and the update attribute set up so that a message will be shown and the uploaded will be hidden after the first upload):
<p:fileUpload id="bankAccountLogFileInput"
fileUploadListener="#{bankAccountLogImportBean.setBankAccountLogFile}"
rendered="#{bankAccountLogImportBean.renderFileUploadInput}"
mode="advanced"
update="importBankAccountLogWizard"
auto="true"
sizeLimit="1000000" />
Bean:
public void setBankAccountLogFile(FileUploadEvent event)
{
importFile = event.getFile();
FacesMessage msg = new FacesMessage(Localization.g("FILE_HAS_BEEN_UPLOADED", event.getFile().getFileName()));
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public String onFlowProcess(FlowEvent event)
{
if("bankAccountLogImportInputTab".equals(event.getOldStep()) &&
importFile == null)
{
FacesMessage msg = new FacesMessage(Localization.g("UPLOAD_A_FILE_TO_CONTINUE"));
FacesContext.getCurrentInstance().addMessage(null, msg);
return event.getOldStep();
}
return event.getNewStep();
}