После уточнения моего вопроса я нашел решение, которое сработало.
Я использую следующую форму, которая использует приведенные ниже классы падежей для хранения своих данных.Как вы можете видеть, внутри есть вложенное отображение, представляющее список ролей и их состояние с учетом ролей пользователя (истинное значение, что у пользователя есть роль, в противном случае - ложное):
def userForm(implicit messages: Messages): Form[UserFormData] = Form(
mapping(
"firstName" -> nonEmptyText(minLength = 2, maxLength = 30),
"lastName" -> nonEmptyText(minLength = 2, maxLength = 40),
"email" -> email,
"roleAssignments" -> seq(
mapping(
"roleIdStr" -> nonEmptyText,
"isAssigned" -> boolean
)(RoleAssignment.apply)(RoleAssignment.unapply)
)
)(UserFormData.apply)(UserFormData.unapply)
)
case class UserFormData(firstName: String, lastName: String, email: String, roleAssignments: Seq[RoleAssignment])
case class RoleAssignment(roleIdStr: String, isAssigned: Boolean)
Контроллер простозаполняет форму данными из db:
def user(id: Long) = Action.async { implicit request =>
managerService.retrieveByIdWithRoles(id, Some(request.identity), request.remoteAddress).map { case (user, roles) =>
Ok(views.html.admin.administration.show_user(
userForm.fill(UserFormData(user.firstName, user.lastName, user.email, roleAssignments(roles)))))
}
}
private def roleAssignments(roles: Seq[Role]) = {
val roleIds = roles.map(_.id)
Roles.all.map { case id =>
RoleAssignment(id.toString, roleIds.contains(id))
}
}
И в шаблоне представления я повторяю роль roleAssignments и использую индекс, предоставленный repeatWithIndex
, для доступа к элементам seq:
@repeatWithIndex(userForm("roleAssignments")) { (roleAssignment, index) =>
@b4.checkbox(userForm(s"roleAssignments[$index].isAssigned"), '_text -> userForm(s"roleAssignments[$index].roleIdStr").value, '_custom -> true, 'readonly -> true)
}
Спасибо, @cchantep, что подтолкнул меня к тому, чтобы я старался изо всех сил.