问题
I would like to be able to trigger validation on my form prior to being allowed to select the files for upload when clicking on the "Choose" button of the fileUpload control in Primefaces. Is this possible? At present the user can click on "Choose" and "Upload" without validation kicking in. This is preventing my document from saving but the attachments are being created. I know I could hide the fileUpload control until the form is successfully validated and saved but I would prefer to invoke validation when you click the "Choose" button if possible. I've tried remoteCommand calls in the onStart but can't seem to get anything to force validation to occur.
回答1:
It is possible to trigger form validation when p:fileUpload
Choose button is clicked by combining Java Script and p:remoteCommand
.
BASIC CONCEPT
- intercept Choose button click event, prevent default outcome (opening of file chooser dialog) and run
p:remoteCommand
instead, - when
p:remoteCommand
completes, and if validation is OK, do not prevent Choose button clicks any more until some data on form input elements is changed again.
PROOF OF CONCEPT EXAMPLE CODE
Add this Java script in your page
<script>
var triggerValidation;
window.onload = function () {
//initially (after page is loaded) trigger validation on Choose btn click
triggerValidation = true;
//define button click listener
registerChooseBtnClick();
};
function registerChooseBtnClick() {
//var chooseBtn = document.getElementsByClassName("ui-fileupload-choose")[0];
// or if you define p:upload widgetVar you can use PF function
var chooseBtn = PF('fileUploadWidget').chooseButton[0];
chooseBtn.addEventListener('click', fnRef, false);
}
var fnRef = function (event) {
console.log("Button clicked");
if (triggerValidation) {
//prevent file browser to open
event.preventDefault();
//trigger validation via p:remoteCommand;
submitSelection();
} else {
//File browser will be opened at this point
}
};
function checkIfValidationFailed(xhr, status, args) {
if (args) {
if (args.validationFailed) {
console.log("Validation failed");
triggerValidation = true;
} else {
triggerValidation = false;
}
}
}
//call each time when form input elements (inputText, ...) change value
function forceValidation(){
triggerValidation = true;
}
</script>
and add p:remoteCommand
<p:remoteCommand
name="submitSelection" process="@form"
oncomplete="checkIfValidationFailed(xhr, status, args)" resetValues="true"/>
Also here is xhtml page for quick testing
<h:form id="form">
<p:messages autoUpdate="true"/>
<p:panelGrid columns="1">
<!--size is integer variable-->
<p:inputText id="size" maxlength="3"
value="#{yourBean.size}"
required="true" requiredMessage="Size is missing"
onchange="forceValidation();"/>
<p:fileUpload
id="upload"
widgetVar="fileUploadWidget"
fileUploadListener="#{yourBean.onUpload}"
multiple="true"
allowTypes="/(\.|\/)(jpg|png)$/" />
</p:panelGrid>
<p:remoteCommand
name="submitSelection" process="@form"
oncomplete="checkIfValidationFailed(xhr, status, args)" resetValues="true"/>
<p:commandButton
id="submitBtn" value="Sumbit" process="@form"
actionListener="#{yourBean.onSubmit()}"/>
</h:form>
来源:https://stackoverflow.com/questions/47460243/pfileupload-validate-form-prior-to-upload