Списки флажков в Play with Scala - PullRequest
0 голосов
/ 21 марта 2019

у меня есть ...

  • a Seq[RoleId] определение всех ролей, которые может быть предоставлен пользователю
  • a User со свойством roles: Seq[RoleId], где роли - это те роли, которые пользователь получил
  • Контроллер Play, подготавливающий форму и предоставляющий пользователю (включая его роли) и Seq доступных RoleIds на html-страницу как часть данных формы (включая отображение)
  • шаблон Twirl, показывающий флажок для каждой доступной роли

Чего я хотел бы добиться, так это списка флажков, в котором отмечены все флажки, значение которых является частью ролей пользователя. Таким образом, список должен показать, какая из доступных ролей предоставлена ​​пользователю, как показано в этом очень усовершенствованном прототипе:

Name:  [Doe, John]
Roles: [ ] Admin
       [x] Manager
       [x] Service Desk
       [ ] Jack of all trades

если имя пользователя John Doe с ролями Manager и Service Desk.

Это кажется довольно простым, но я не могу найти способ достичь этого без некоторых хаков (например, обойти форму и перенести дату роли в шаблон Twirl в качестве обычного параметра; написать собственный преобразователь в коде обработки формы). так далее.). Разве нет способа сделать это в режиме Play без всего этого шаблонного?

Я сильно погуглил, но не смог найти ни одного примера, который, казалось бы, делал это правильно. И документы по обработке форм в Play тоже не помогли.

Есть идеи?

1 Ответ

0 голосов
/ 22 марта 2019

После уточнения моего вопроса я нашел решение, которое сработало.

Я использую следующую форму, которая использует приведенные ниже классы падежей для хранения своих данных.Как вы можете видеть, внутри есть вложенное отображение, представляющее список ролей и их состояние с учетом ролей пользователя (истинное значение, что у пользователя есть роль, в противном случае - ложное):

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, что подтолкнул меня к тому, чтобы я старался изо всех сил.

...