You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何验证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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 06:37:07