简体   繁体   中英

Thymeleaf checkbox not passing value

two problems.

  1. I have User and Note classes. User can have many notes. How to show by Thymeleaf every id of notes which belong to user ? th:text="${u.notes.id}" doesn't work
  2. I have table(see picture) with checkboxes for every user with boolean isUserChecked value, below is button to delete checked user. Thymeleaf correct shows state of isUserChecked values. Delete button doesn't work when i check checkbox by hand but works when i set isUserChecked values in code. So problem is in my Thymeleaf syntax of this checkbox.

Screenshot:

在此处输入图片说明

html

<div class="container">
<div class="row">
        <div class="col-sm-6">
              <table class="table table-hover">
                <thead>
                  <tr>
                    <th>Id</th>
                    <th>Username</th>
                    <th>First name</th>
                    <th>Last name</th>
                    <th>Password (Hash)</th>
                    <th>Role</th>
                    <th>Notes</th>
                    <th>Select</th>
                  </tr>
                </thead>
                <tbody>
                  <tr th:each="u : ${listOfUsers}">
                    <td th:text="${u.id}"></td>
                    <td th:text="${u.username}"></td>
                    <td th:text="${u.firstName}"></td>
                    <td th:text="${u.lastName}"></td>
                    <td th:text="${#strings.substring(u.password,0,5) +'...'}"></td>
                    <td th:text="${u.role}"></td>
                    <td th:text="${u.notes}"></td>     
                    <td><input type="checkbox" name="mycheckbox" 
                     th:value="*{u.isUserChecked()}" th:checked="${u.isUserChecked()}"  /></td>
                  </tr>
                </tbody>
              </table>

            <form th:action="@{/users}" method="post">
                <button class="buttonLogin" type="submit">Submit</button>
            </form>
        </div>
  </div>

UPDATE 1

as @Metroids mentioned first problem can fix by:

<td><span th:each="note, i: ${u.notes}" th:text="${(i.index > 0 ? ', ' : '') + note.id}" /></td>

Second problem. For using this in my html:

<tr th:each="u, i : ${userWrapper}">
<!-- other rows removed for readability -->
<td><input type="checkbox" th:field="*{listOfUsers[__${i.index}__].userChecked}" /></td>

i need UserWrapper class with property List<User> listOUsers . But how to do this ? I created something like this:

@Component
public class UserWrapper {

@Autowired
UserService userService;

List<User> listOfUsers = userService.findAll();

public List<User> getListOfUsers() {
    return listOfUsers;
}

public void setListOfUsers(List<User> listOfUsers) {
    this.listOfUsers = listOfUsers;
}
}

Here is my controller for this page:

@Controller
public class UserController {

@Autowired
UserService userService;

@Autowired 
UserWrapper userWrapper;

@RequestMapping("/users")
public String home(Model model){
    List<User> listOfUsers = userService.findAll();
    model.addAttribute("listOfUsers", listOfUsers);
    return "users";
}

@RequestMapping(value = "users", method = RequestMethod.POST)
public String deleteUser(User user, Model model){
    userService.deleteCheckedUser(user);

    return "redirect:/users";
}
}

after this i have error:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'userWrapper'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userWrapper' defined in file [C:\Users\luk89\Desktop\Java\STS Projects\StickyNotes\target\classes\com\twistezo\models\UserWrapper.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.twistezo.models.UserWrapper]: Constructor threw exception; nested exception is java.lang.NullPointerException

UPDATE 2

User controller:

@Controller
public class UserController {

@Autowired
UserService userService;

@Autowired
UserWrapper userWrapper;

@RequestMapping("/users")
public String home(Model model){
    List<User> listOfUsers = userService.findAll();
    userWrapper.setListOfUsers(listOfUsers);

    for(User u : userWrapper.getListOfUsers()){
        System.out.println("username: " +u.getUsername()+ ", checked?: " +u.isUserChecked());
    }

    model.addAttribute("listOfUsers", listOfUsers);
    model.addAttribute("userWrapper", userWrapper);

    return "users";
}

@RequestMapping(value = "/users", method = RequestMethod.POST)
public String deleteUser(@ModelAttribute UserWrapper userWrapper, Model model){

    for(User u : userWrapper.getListOfUsers()){
        System.out.println("username: " +u.getUsername()+ ", checked?: " +u.isUserChecked());
    }

    userService.deleteCheckedUser(userWrapper);

    return "redirect:/users";
    }
}

Delete method from my service class:

@Override
public void deleteCheckedUser(UserWrapper userWrapper) {

    for(User u : userWrapper.getListOfUsers()){
        if(u.isUserChecked() == true){
            this.userDAO.delete(u.getId());
        }
    }
}

Result:

username: user1, checked?: false
username: user2, checked?: false
username: user3, checked?: false
username: user4, checked?: false
username: user5, checked?: false
username: asd, checked?: false
username: qwe, checked?: false
username: xcv, checked?: false
username: ghj, checked?: false
username: dfh, checked?: false
username: n, checked?: false
username: ed, checked?: false

username: null, checked?: true
username: null, checked?: false
username: null, checked?: false
username: null, checked?: false
username: null, checked?: false
username: null, checked?: false
username: null, checked?: false
username: null, checked?: false
username: null, checked?: false
username: null, checked?: false
username: null, checked?: false
username: null, checked?: true

Thymeleaf part wokrs great now, but my list from userWrap doesn't have values when i call POST method in controller. I was trying copy

List<User> listOfUsers = userService.findAll(); userWrapper.setListOfUsers(listOfUsers);

to POST method but there was situation: usernames: OK, checked?: doesn't listen mouse clicking to checkbox (all values are false).

For the listing the id of every note you need to add another loop. For example, instead of

<td th:text="${u.notes}"></td>

You need something like.

<td><span th:each="note, i: ${u.notes}" th:text="${(i.index > 0 ? ', ' : '') + note.id}" /></td>

--

For the checkbox. You have a lot of changes you need to make...

  • All the checkboxes need to be within the <form></form> tags.
  • You need a command object that has a list of users as a property... I don't think you can use a java List as the command object. That needs to be specified as the th:object on the <form> tag.
  • The html for the actual checkbox should look something like this:

HTML

<form th:action="@{/users}" th:object="${userWrapper}" method="post">
    <!-- other html removed for readability -->
    <tr th:each="u, i : ${listOfUsers}">
        <!-- other rows removed for readability -->
        <td><input type="checkbox" th:field="*{users[__${i.index}__].userChecked}" /></td>
    </tr>
</form>

Controller

@Controller
public class UserController {

    @Autowired UserService userService;

    @RequestMapping("/users")
    public String home(Model model){
        List<User> listOfUsers = userService.findAll();
        UserWrapper userWrapper = new UserWrapper();
        userWrapper.setListOfUsers(listOfUsers);
        model.addAttribute("listOfUsers", listOfUsers);
        model.addAttribute("userWrapper", userWrapper);
        return "users";
    }

    @RequestMapping(value = "users", method = RequestMethod.POST)
    public String deleteUser(@ModelAttribute UserWrapper userWrapper, Model model){
        userService.deleteCheckedUser(userWrapper.getListOfUsers());
        return "redirect:/users";
    }
}

Java

public class UserWrapper {
    List<User> listOfUsers = new ArrayList<>();

    public List<User> getListOfUsers() {
        return listOfUsers;
    }

    public void setListOfUsers(List<User> listOfUsers) {
        this.listOfUsers = listOfUsers;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM