在模态表单中使用弹簧启动和百里香叶进行服务器端验证



我只是在学习弹簧启动和百里香叶,我知道的是在本地模态形式中进行验证,而不重定向它,只是在这一步感到困惑。

我的班级模型

public class Class {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @NotEmpty
    @NotBlank
    private String className;
    public Class(@NotEmpty @NotBlank String className) {
        this.className = className;
    }
}

Html 前面显示模态

<div class="modal fade" id="addModal" tabindex="-1" th:fragment="modal-add" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title" id="exampleModalLabel">Add Classroom</h5>
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                        <form th:action="@{/addclass}" th:object="${class}" method="post">
                        <div class="modal-body">
                            <div class="form-group">
                                <label for="className">Class Name</label>
                                <input type="text" class="form-control" id="className" th:field="*{className}" placeholder="Name of Class">
                                <div class="text text-danger" th:if="${#fields.hasErrors('className')}" th:errors="*{className}">
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                            <button type="submit" value="Save" class="btn btn-primary">Save</button>
                        </div>
                        </form>
                    </div>
                </div>
            </div>

类控制器

@PostMapping("/addclass")
    public String addClass(@Valid @ModelAttribute("class") Class kelas, BindingResult result) {
        if(result.hasErrors()) {
            //what to do here ? to show error validation without closing modal?
        }else{
            classService.addClass(kelas);
        }
        return "redirect:/classlist";
    }

在百里叶中使用开放模态进行表单验证有点棘手。这是我的解决方案:

在控制器函数中添加"重定向属性atts"。添加属性 hasErrors 的值为 true。

@PostMapping("/addclass")
public String addClass(@Valid @ModelAttribute("class") Class kelas, BindingResult result, RedirectAttributes atts) {
    if(result.hasErrors()) {
        atts.addAttribute("hasErrors", true);
        return "classlist";
    }else{
        classService.addClass(kelas);
    }
    return "redirect:/classlist";
}

在你的 html 文件中,你添加带有 th:inline 和 th:if 的条件 JS-Code。因此,如果任何字段有错误,JS代码将被执行。在JS代码中,您可以打开模态。

<div class="modal fade" id="addModal" tabindex="-1" th:fragment="modal-add" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
           <script th:inline="javascript" th:if="${#fields.hasErrors('*')}">$("#addModal").modal("show");</script>
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="exampleModalLabel">Add Classroom</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <form th:action="@{/addclass}" th:object="${class}" method="post">
                    <div class="modal-body">
                        <div class="form-group">
                            <label for="className">Class Name</label>
                            <input type="text" class="form-control" id="className" th:field="*{className}" placeholder="Name of Class">
                            <div class="text text-danger" th:if="${#fields.hasErrors('className')}" th:errors="*{className}">
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                        <button type="submit" value="Save" class="btn btn-primary">Save</button>
                    </div>
                    </form>
                </div>
            </div>
        </div>

目前尚不清楚您要实现的目标; 所以这是基于你的代码的通用答案。如果有任何错误,只需根据需要附加错误并仅返回到原始映射。它不会重定向到任何其他页面,并将在网页上显示错误。根据您的代码的示例代码是 -

@PostMapping("/addclass")
public String addClass(@ModelAttribute("class") @Valid Class kelas, BindingResult result) {
       if(result.hasErrors()) {
            return "addClass";    
        }
        //else is not required here. If there are errors, it is returned before reaching here anyways.
        classService.addClass(kelas);
        return "redirect:/classlist";
}

你的html应该像(只有错误部分)-

<div class="text text-danger" th:if="${#fields.hasErrors('className')}" th:errors="*{className}">
      <p>Incorrect Class Name</p>
</div>

您还可以在模态类本身或 application.properties 或最终静态类中指定错误消息,并将其与响应一起发送。

其他几点,因为您是新手 - 避免将名称用作类名。这会在以后的某个时间和时间点令人困惑,不是一个好的做法。使用一些正确的类名,即这个模态类应该表示什么。 其次,我相信构造函数也不需要@NotEmpty@NotBlank

在方法addClass中,您必须返回视图外观。

 if(result.hasErrors()) {
        return "login";
    }
登录

是您显示登录页面的页面。在登录页面中,您必须处理如下所示的错误:

<span th:if="${#fields.hasErrors('className')}" th:errors="*{className}">Class name Error</span>

最新更新