如何验证PrimeFaces中必填的<p:cellEditor>输入面板并自定义提示?
实现JSF可编辑数据表格的必填验证与自定义提示
步骤1:清理无用的required属性
你给<h:outputText>添加的required="true"完全没必要——输出组件仅用于展示数据,不需要验证规则。直接删除所有output facet里的required="true"配置。
步骤2:给输入组件配置自定义必填提示
给编辑状态下的输入组件添加required="true",并通过requiredMessage属性设置自定义提示文本:
文本输入框示例(Keterangan、Jumlah)
<f:facet name="input"> <h:inputText value="#{struk.keterangan}" required="true" requiredMessage="请填写备注信息"/> </f:facet>
日期选择器示例(Tanggal Kuitansi)
<f:facet name="input"> <p:datePicker value="#{struk.tanggalKuitansi}" monthNavigator="true" pattern="dd/MM/yyyy" required="true" requiredMessage="请选择凭证日期"/> </f:facet>
文件上传组件示例(Upload Tanda Tangan)
p:fileUpload(simple模式)需要绑定后端属性,同时配置必填规则和提示:
<f:facet name="input"> <p:fileUpload id="uploader2" mode="simple" skinSimple="true" styleClass="block mb-5" title="my custom title" accept=".jpg,.jpeg,.png" value="#{struk.tandaTangan}" required="true" requiredMessage="请上传签名文件"/> </f:facet>
注意:后端StrukPembayaran类需添加UploadedFile tandaTangan属性及对应的getter/setter方法。
步骤3:确保行编辑事件触发验证
给p:dataTable添加validateClient="true",确保前端验证在点击行编辑的保存按钮时自动触发:
<p:dataTable value="#{dtStrukView.strukPembayaranList}" var="struk" editable="true" validateClient="true">
你的<p:ajax event="rowEdit">已配置update=":form:msgs",验证失败时消息会自动显示在p:growl中。
步骤4:后端补充验证(可选但推荐)
为避免前端验证被绕过,在onRowEdit方法中添加后端校验逻辑,手动检查必填项并抛出异常:
public void onRowEdit(RowEditEvent event) { StrukPembayaran struk = (StrukPembayaran) event.getObject(); List<String> errors = new ArrayList<>(); if (struk.getKeterangan() == null || struk.getKeterangan().trim().isEmpty()) { errors.add("备注信息不能为空"); } if (struk.getTanggalKuitansi() == null) { errors.add("凭证日期不能为空"); } if (struk.getJumlah() == null || struk.getJumlah().trim().isEmpty()) { errors.add("金额不能为空"); } if (struk.getTandaTangan() == null) { errors.add("签名文件不能为空"); } if (!errors.isEmpty()) { FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "验证失败", String.join(";", errors)); FacesContext.getCurrentInstance().addMessage(null, message); throw new ValidatorException(message); } // 执行正常的行数据保存逻辑 }
修改后的核心代码片段
<p:dataTable value="#{dtStrukView.strukPembayaranList}" var="struk" editable="true" validateClient="true"> <p:ajax event="rowEdit" listener="#{dtStrukView.onRowEdit}" update=":form:msgs"/> <p:ajax event="rowEditCancel" listener="#{dtStrukView.onRowCancel}" update=":form:msgs"/> <p:column headerText="Keterangan"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{struk.keterangan}" /> </f:facet> <f:facet name="input"> <h:inputText value="#{struk.keterangan}" required="true" requiredMessage="请填写备注信息"/> </f:facet> </p:cellEditor> </p:column> <p:column headerText="Tanggal Kuitansi"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{struk.tanggalKuitansi}" /> </f:facet> <f:facet name="input"> <p:datePicker value="#{struk.tanggalKuitansi}" monthNavigator="true" pattern="dd/MM/yyyy" required="true" requiredMessage="请选择凭证日期"/> </f:facet> </p:cellEditor> </p:column> <p:column headerText="Jumlah"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{struk.jumlah}" /> </f:facet> <f:facet name="input"> <h:inputText value="#{struk.jumlah}" required="true" requiredMessage="请填写金额"/> </f:facet> </p:cellEditor> </p:column> <p:column headerText="Upload Tanda Tangan"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{struk.tandaTangan != null ? struk.tandaTangan.getFileName() : '未上传'}" /> </f:facet> <f:facet name="input"> <p:fileUpload id="uploader2" mode="simple" skinSimple="true" styleClass="block mb-5" title="my custom title" accept=".jpg,.jpeg,.png" value="#{struk.tandaTangan}" required="true" requiredMessage="请上传签名文件"/> </f:facet> </p:cellEditor> </p:column> <p:column style="width:6rem"> <p:rowEditor editTitle="Edit Row" cancelTitle="Cancel Edit" saveTitle="Save Row"/> </p:column> </p:dataTable>
最终效果
用户点击行编辑的保存按钮时,若有必填项未填写,p:growl会弹出对应的自定义提示;前端验证会阻止无效数据提交,后端验证作为双重保障避免非法数据流入。
内容的提问来源于stack exchange,提问作者Diti Merita
相关产品推荐
相关产品推荐

