重新渲染上一页以验证表单时

huangapple go评论92阅读模式
英文:

How to re-render previous page when validating form

问题

I have a controller that renders a chores.html page with various sorts of chores.

@GetMapping("/chores")
public String getDueChores(Model model)
{
var tomorrow = LocalDate.now().plusDays(1);
var chores = choreRepository.findByDueBefore(tomorrow);
model.addAttribute("choresDue", chores);
model.addAttribute("allChores", choreRepository.findAll());
model.addAttribute("chore", new Chore());
model.addAttribute("chores", new ArrayList());
return "chores";
}

The same page also has a form for adding a new chore. Here's the controller method:

@PostMapping("/chores")
public String addNewChore(@ModelAttribute @Valid Chore chore)
{
chore.setDue(LocalDate.now().plusDays(chore.getDaysBetween()));
choreRepository.save(chore);
return "redirect:/chores";
}

Now I want to display the errors if the new chore is invalid.

Attempt 1:

@PostMapping("/chores")
public String addNewChore(@ModelAttribute @Valid Chore chore,
Errors errors)
{
if (errors.hasErrors())
{
return "chores";
}

chore.setDue(LocalDate.now().plusDays(chore.getDaysBetween()));
choreRepository.save(chore);
return "redirect:/chores";

}

This shows the error message, but since it's not going through the logic in the GET controller method, all the other chores on the page don't get populated.

Attempt 2:

@PostMapping("/chores")
public String addNewChore(@ModelAttribute @Valid Chore chore,
Errors errors)
{
if (errors.hasErrors())
{
return "redirect:/chores";
}

chore.setDue(LocalDate.now().plusDays(chore.getDaysBetween()));
choreRepository.save(chore);
return "redirect:/chores";

}

This doesn't work because the error information is lost on the redirect, and the errors aren't displayed.

Could anyone point me in the right direction, please?

Here's chores.html, if it's relevant:

Due today...




Chore name is invalid

<input type="text" th:field="*{daysBetween}" placeholder="Do chore every # days">
<span class="validationError"
      th:if="${#fields.hasErrors('daysBetween')}"
      th:errors="*{daysBetween}">Chore name is invalid</span>
<br>
<input type="submit" value="Add chore">

All Chores



英文:

I have a controller that renders a chores.html page with various sorts of chores.

@GetMapping(&quot;/chores&quot;)
public String getDueChores(Model model)
{
    var tomorrow = LocalDate.now().plusDays(1);
    var chores = choreRepository.findByDueBefore(tomorrow);
    model.addAttribute(&quot;choresDue&quot;, chores);
    model.addAttribute(&quot;allChores&quot;, choreRepository.findAll());
    model.addAttribute(&quot;chore&quot;, new Chore());
    model.addAttribute(&quot;chores&quot;, new ArrayList&lt;Chore&gt;());
    return &quot;chores&quot;;
}

The same page also has a form for adding a new chore. Here's the controller method:

@PostMapping(&quot;/chores&quot;)
public String addNewChore(@ModelAttribute @Valid Chore chore)                  
{       
    chore.setDue(LocalDate.now().plusDays(chore.getDaysBetween()));
    choreRepository.save(chore);
    return &quot;redirect:/chores&quot;;
}

Now I want to display the errors if the new chore is invalid.

Attempt 1:

@PostMapping(&quot;/chores&quot;)
public String addNewChore(@ModelAttribute @Valid Chore chore,
                                             Errors errors)
{
    if (errors.hasErrors())
    {
        return &quot;chores&quot;;
    }

    chore.setDue(LocalDate.now().plusDays(chore.getDaysBetween()));
    choreRepository.save(chore);
    return &quot;redirect:/chores&quot;;
}

This shows the error message, but sense it's not going through the logic in the GET controller method, all the other chores on the page don't get populated.

Attempt 2:

@PostMapping(&quot;/chores&quot;)
public String addNewChore(@ModelAttribute @Valid Chore chore,
                          Errors errors)
{
    if (errors.hasErrors())
    {
        return &quot;redirect:/chores&quot;;
    }

    chore.setDue(LocalDate.now().plusDays(chore.getDaysBetween()));
    choreRepository.save(chore);
    return &quot;redirect:/chores&quot;;
}

This doesn't work because the error information is lost on the redirect, and the errors aren't displayed.

Could anyone point me in the right direction, please?

Here's chores.html, if it's relevant:

&lt;body&gt;
&lt;h1&gt;Due today...&lt;/h1&gt;
&lt;form method=&quot;post&quot; th:action=&quot;@{/chore}&quot; th:object=&quot;${chore}&quot;&gt;
    &lt;ul&gt;
        &lt;li th:each=&quot;chore: ${choresDue}&quot;&gt;
            &lt;input type=&quot;checkbox&quot; name=&quot;choreIds&quot; th:value=&quot;${chore.id}&quot;/&gt;
            &lt;label th:text=&quot;${chore.name}&quot;&gt;&lt;/label&gt;
        &lt;/li&gt;
    &lt;/ul&gt;
    &lt;input type=&quot;submit&quot; value=&quot;Mark Chores Complete&quot;&gt;
&lt;/form&gt;

&lt;form method=&quot;post&quot; action=&quot;#&quot; th:action=&quot;@{/chores}&quot; th:object=&quot;${chore}&quot;&gt;
    &lt;input type=&quot;text&quot; th:field=&quot;*{name}&quot; placeholder=&quot;Chore name&quot;&gt;
    &lt;span class=&quot;validationError&quot;
          th:if=&quot;${#fields.hasErrors(&#39;name&#39;)}&quot;
          th:errors=&quot;*{name}&quot;&gt;Chore name is invalid&lt;/span&gt;
    &lt;br&gt;

    &lt;input type=&quot;text&quot; th:field=&quot;*{daysBetween}&quot; placeholder=&quot;Do chore every # days&quot;&gt;
    &lt;span class=&quot;validationError&quot;
          th:if=&quot;${#fields.hasErrors(&#39;daysBetween&#39;)}&quot;
          th:errors=&quot;*{daysBetween}&quot;&gt;Chore name is invalid&lt;/span&gt;
    &lt;br&gt;
    &lt;input type=&quot;submit&quot; value=&quot;Add chore&quot;&gt;
&lt;/form&gt;

&lt;hr&gt;
&lt;h1&gt;All Chores&lt;/h1&gt;
&lt;form th:method=&quot;delete&quot; th:action=&quot;@{/deleteChore}&quot; th:object=&quot;${chore}&quot;&gt;
&lt;ul&gt;
    &lt;li th:each=&quot;chore: ${allChores}&quot;&gt;
        &lt;input type=&quot;checkbox&quot; name=&quot;choreIds&quot; th:value=&quot;${chore.id}&quot;/&gt;
        &lt;label th:text=&quot;${chore.name} + &#39; every &#39; + ${chore.daysBetween} + &#39; days&#39;&quot;&gt;&lt;/label&gt;
    &lt;/li&gt;
&lt;/ul&gt;
    &lt;input type=&quot;submit&quot; value=&quot;Delete selected chores&quot;&gt;
&lt;/form&gt;

&lt;/body&gt;

答案1

得分: 0

解决方法是将 Errors 添加到 Model 中。

@PostMapping("/chores")
public String addNewChore(@ModelAttribute @Valid Chore chore,
                          Errors errors,
                          Model model)
{
    if (errors.hasErrors())
    {
        model.addAttribute("error", errors);
        var tomorrow = LocalDate.now().plusDays(1);
        var chores = choreRepository.findByDueBefore(tomorrow);
        model.addAttribute("choresDue", chores);
        model.addAttribute("allChores", choreRepository.findAll());
        return "chores";
    }

    chore.setDue(LocalDate.now().plusDays(chore.getDaysBetween()));
    choreRepository.save(chore);
    return "redirect:/chores";
}
英文:

Solution is to add Errors to the Model.

@PostMapping(&quot;/chores&quot;)
public String addNewChore(@ModelAttribute @Valid Chore chore,
                          Errors errors,
                          Model model)
{
    if (errors.hasErrors())
    {
        model.addAttribute(&quot;error&quot;, errors);
        var tomorrow = LocalDate.now().plusDays(1);
        var chores = choreRepository.findByDueBefore(tomorrow);
        model.addAttribute(&quot;choresDue&quot;, chores);
        model.addAttribute(&quot;allChores&quot;, choreRepository.findAll());
        return &quot;chores&quot;;
    }

    chore.setDue(LocalDate.now().plusDays(chore.getDaysBetween()));
    choreRepository.save(chore);
    return &quot;redirect:/chores&quot;;
}

huangapple
  • 本文由 发表于 2020年7月30日 08:02:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/63164240.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定