-
Notifications
You must be signed in to change notification settings - Fork 9
/
GovukCheckboxes.scala.html
123 lines (105 loc) · 5.55 KB
/
GovukCheckboxes.scala.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
@*
* Copyright 2023 HM Revenue & Customs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*@
@import scala.collection.compat.immutable.LazyList
@import uk.gov.hmrc.govukfrontend.views.html.components._
@import uk.gov.hmrc.govukfrontend.views.html.helpers._
@this(govukFieldset: GovukFieldset, govukHint: GovukHint, govukLabel: GovukLabel, govukFormGroup: GovukFormGroup, govukHintAndErrorMessage: GovukHintAndErrorMessage)
@(params: Checkboxes)
@import params._
@require(name.nonEmpty, "parameter 'name' should not be empty")
@require(values.isEmpty || !items.exists(_.checked) || values == items.filter(_.checked).map(_.value).toSet, "checked item(s) conflict with passed value(s)")
@defining(fieldset.fold(params.describedBy)(fieldset => fieldset.describedBy.filter(_.nonEmpty).orElse(params.describedBy))) { maybeDescribedBy =>
@defining(govukHintAndErrorMessage(idPrefixStr, describedBy, hint, errorMessage)(divSnippet)) { innerHtml =>
@govukFormGroup(formGroup, errorMessage) {
@fieldset.fold(innerHtml) { fieldset =>
@govukFieldset(Fieldset(
describedBy = fieldSetDescribedBy(maybeDescribedBy.getOrElse("")),
legend = fieldset.legend,
classes = fieldset.classes,
attributes = fieldset.attributes,
html = innerHtml
))
}
}
}
}
@fieldSetDescribedBy(describedBy: String) = @{
val describedByWithHintId = hint.fold(describedBy)(_ => s"$describedBy $idPrefixStr-hint".ltrim)
val describedByWithErrorId = errorMessage.fold(describedByWithHintId)(_ => s"$describedByWithHintId $idPrefixStr-error".ltrim)
describedByWithErrorId.toOption
}
@* if name is not provided defaults to javascript undefined: https://github.com/alphagov/govuk-frontend/blob/main/src/govuk/components/checkboxes/template.njk#L8 *@
@idPrefixStr = @{idPrefix.getNonEmptyOrElse(name)}
@isConditional = @{items.exists(_.conditionalHtml.exists(_.body.nonEmpty))}
@hasFieldset = @{fieldset.isDefined}
@divSnippet(describedBy: String) = {
<div class="@toClasses("govuk-checkboxes", classes)"@toAttributes(attributes) data-module="govuk-checkboxes">
@{formGroup.beforeInput.map(_.asHtml)}
@for((item, index) <- items.zip(LazyList from 1)) {
@if(item.divider.exists(_.nonEmpty)) {
<div class="govuk-checkboxes__divider">@item.divider</div>
} else {
@defining((values.nonEmpty && values.contains(item.value)) || item.checked) { isChecked =>
<div class="govuk-checkboxes__item">
<input class="govuk-checkboxes__input" id="@itemId(item, index)" name="@itemName(item)" type="checkbox" value="@item.value"@inputAttrs(item, index, describedBy, isChecked)@toAttributes(item.attributes)>
@govukLabel(Label(
forAttr = Some(itemId(item, index)),
classes = toClasses("govuk-checkboxes__label", item.label.map(_.classes).getOrElse("")),
attributes = item.label.map(_.attributes).getOrElse(Map.empty),
content = item.content
))
@if(hasHint(item)) {
@govukHint(Hint(
id = Some(itemHintId(item, index)),
classes = toClasses("govuk-checkboxes__hint", item.hint.map(_.classes).getOrElse("")),
attributes = item.hint.map(_.attributes).getOrElse(Map.empty),
content = item.hint.map(_.content).getOrElse(Empty)
))
}
</div>
@item.conditionalHtml.map { conditionalHtml =>
@if(conditionalHtml.body.nonEmpty) {
<div class="@toClasses("govuk-checkboxes__conditional", "govuk-checkboxes__conditional--hidden".when(!isChecked))" id="@conditionalId(item, index)">
@conditionalHtml
</div>
}
}
}
}
}
@{formGroup.afterInput.map(_.asHtml)}
</div>
}
@* The following reusable snippets compile to `def`s so less efficient than using @defining but a lot more readable *@
@itemId(item: CheckboxItem, index: Int) = @{
(item.id, index) match {
case (Some(NonEmptyString(id)), _) => id
case (Some(_) | None, 1) => idPrefixStr
case _ => s"$idPrefixStr-$index"
}
}
@conditionalId(item: CheckboxItem, index: Int) = @{s"conditional-${itemId(item, index)}"}
@hasHint(item: CheckboxItem) = @{item.hint.exists(_.content.nonEmpty)}
@itemHintId(item: CheckboxItem, index: Int) = @{s"${itemId(item, index)}-item-hint".when(hasHint(item))}
@inputAttrs(item: CheckboxItem, index: Int, describedBy: String, isChecked: Boolean) = {
@if(isChecked) { checked}
@if(item.disabled) { disabled}
@item.conditionalHtml.map { conditionalHtml => @if(conditionalHtml.body.nonEmpty) {data-aria-controls="@conditionalId(item, index)"}}
@item.behaviour.map { behaviour => data-behaviour="@behaviour"}
@itemDescribedBy(item, index, describedBy).toOption.map { ariaDescribedBy => aria-describedby="@ariaDescribedBy"}
}
@itemName(item: CheckboxItem) = @{item.name.getNonEmptyOrElse(name)}
@itemDescribedBy(item: CheckboxItem, index: Int, describedBy: String) = @{s"${describedBy.when(!hasFieldset)} ${itemHintId(item, index)}".trim}