Skip to content

Commit f4bcc85

Browse files
authored
Merge pull request #18 from TechnologyEnhancedLearning/Develop/Fixes/TD-1855
TD-1855: Optional radio and checkbox item css
2 parents f0e62bd + 669090b commit f4bcc85

File tree

6 files changed

+129
-54
lines changed

6 files changed

+129
-54
lines changed

NHSUKViewComponents.Web/ViewComponents/CheckboxesViewComponent.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ public IViewComponentResult Invoke(
1313
bool populateWithCurrentValues,
1414
string? errormessage,
1515
string? hintText,
16-
bool required
16+
bool required,
17+
string cssClass = default
1718
)
1819
{
1920
var checkboxList = checkboxes.Select(
@@ -32,7 +33,8 @@ bool required
3233
string.IsNullOrEmpty(hintText) ? null : hintText,
3334
errormessage,
3435
checkboxList,
35-
required
36+
required,
37+
string.IsNullOrEmpty(cssClass) ? null : cssClass
3638
);
3739

3840
return View(viewModel);

NHSUKViewComponents.Web/ViewComponents/RadioListViewComponent.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,15 @@ public IViewComponentResult Invoke(
1515
bool populateWithCurrentValues,
1616
string hintText,
1717
bool required,
18-
string? requiredClientSideErrorMessage = default
18+
string? requiredClientSideErrorMessage = default,
19+
string cssClass = default
1920
)
2021
{
22+
var model = ViewData.Model;
23+
var property = model.GetType().GetProperty(aspFor);
24+
var errorMessages = ViewData.ModelState[property?.Name]?.Errors.Select(e => e.ErrorMessage) ??
25+
new string[] { };
26+
2127
var radiosList = radios.Select(
2228
r => new RadiosItemViewModel(
2329
r.Value,
@@ -32,8 +38,10 @@ public IViewComponentResult Invoke(
3238
label,
3339
string.IsNullOrEmpty(hintText) ? null : hintText,
3440
radiosList,
41+
errorMessages,
3542
required,
36-
string.IsNullOrEmpty(requiredClientSideErrorMessage) ? null : requiredClientSideErrorMessage
43+
string.IsNullOrEmpty(requiredClientSideErrorMessage) ? null : requiredClientSideErrorMessage,
44+
string.IsNullOrEmpty(cssClass) ? null : cssClass
3745
);
3846

3947
return View(viewModel);

NHSUKViewComponents.Web/ViewModels/CheckboxesViewModel.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,24 @@ public CheckboxesViewModel(
99
string? hintText,
1010
string? errormessage,
1111
IEnumerable<CheckboxItemViewModel> checkboxes,
12-
bool required = false
12+
bool required = false,
13+
string? cssClass = default
1314
)
1415
{
1516
Label = label;
1617
HintText = hintText;
1718
Checkboxes = checkboxes;
1819
ErrorMessage = errormessage;
1920
Required = required;
21+
Class = cssClass;
2022
}
2123

2224
public string Label { get; set; }
2325

2426
public string? HintText { get; set; }
2527

28+
public string? Class { get; set; }
29+
2630
public string? ErrorMessage { get; set; }
2731

2832
public IEnumerable<CheckboxItemViewModel> Checkboxes { get; set; }

NHSUKViewComponents.Web/ViewModels/RadiosViewModel.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace NHSUKViewComponents.Web.ViewModels
22
{
33
using System.Collections.Generic;
4+
using System.Linq;
45

56
public class RadiosViewModel
67
{
@@ -9,23 +10,32 @@ public RadiosViewModel(
910
string label,
1011
string hintText,
1112
IEnumerable<RadiosItemViewModel> radios,
13+
IEnumerable<string> errorMessages,
1214
bool required,
13-
string? requiredClientSideErrorMessage = default
15+
string? requiredClientSideErrorMessage = default,
16+
string? cssClass = default
1417
)
1518
{
19+
var errorMessageList = errorMessages.ToList();
1620
AspFor = aspFor;
1721
Label = !required && !label.EndsWith("(optional)") ? label + " (optional)" : label;
1822
HintText = hintText;
1923
Radios = radios;
24+
ErrorMessages = errorMessageList;
25+
HasError = errorMessageList.Any();
2026
Required = required;
2127
RequiredClientSideErrorMessage = requiredClientSideErrorMessage;
28+
Class = cssClass;
2229
}
2330

2431
public string AspFor { get; set; }
2532

2633
public string Label { get; set; }
2734

2835
public string HintText { get; set; }
36+
public string? Class { get; set; }
37+
public IEnumerable<string> ErrorMessages { get; set; }
38+
public readonly bool HasError;
2939

3040
public IEnumerable<RadiosItemViewModel> Radios { get; set; }
3141
public bool Required { get; set; }

NHSUKViewComponents.Web/Views/Shared/Components/Checkboxes/Default.cshtml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,17 @@
3131
<div class="nhsuk-checkboxes">
3232
@foreach (var checkbox in Model.Checkboxes)
3333
{
34-
<partial name="_CheckboxItem" model="checkbox" />
34+
if (!string.IsNullOrWhiteSpace(Model.Class))
35+
{
36+
<div class="@Model.Class">
37+
<partial name="_CheckboxItem" model="checkbox" />
38+
</div>
39+
}
40+
else
41+
{
42+
<partial name="_CheckboxItem" model="checkbox" />
43+
}
44+
3545
}
3646
</div>
3747
</fieldset>

NHSUKViewComponents.Web/Views/Shared/Components/RadioList/Default.cshtml

Lines changed: 88 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3,55 +3,96 @@
33

44
@model RadiosViewModel
55

6-
<div class="nhsuk-form-group">
7-
8-
<fieldset class="nhsuk-fieldset" aria-describedby="@Model.Label.RemoveWhitespace()-hint">
9-
<legend class="nhsuk-fieldset__legend nhsuk-fieldset__legend--m">
10-
<label class="nhsuk-fieldset__heading">
11-
@Model.Label
12-
</label>
13-
</legend>
14-
15-
@if (Model.HintText != null)
16-
{
17-
<div class="nhsuk-hint" id="@Model.Label.RemoveWhitespace()-hint">
18-
@Html.Raw(Model.HintText)
19-
</div>
20-
}
21-
22-
@if (Model.Required)
23-
{
6+
<div class="nhsuk-form-group @(Model.HasError ? "nhsuk-form-group--error" : "")">
7+
8+
<fieldset class="nhsuk-fieldset" aria-describedby="@Model.Label.RemoveWhitespace()-hint">
9+
<legend class="nhsuk-fieldset__legend nhsuk-fieldset__legend--m">
10+
<label class="nhsuk-fieldset__heading">
11+
@Model.Label
12+
</label>
13+
</legend>
14+
15+
@if (Model.HintText != null)
16+
{
17+
<div class="nhsuk-hint" id="@Model.Label.RemoveWhitespace()-hint">
18+
@Html.Raw(Model.HintText)
19+
</div>
20+
}
21+
22+
@if (Model.HasError)
23+
{
24+
<div id="@Model.AspFor-error" class="nhsuk-u-padding-top-1 nhsuk-u-padding-bottom-3">
25+
@foreach (var errorMessage in Model.ErrorMessages)
26+
{
27+
<span class="error-message--margin-bottom-1 nhsuk-error-message">
28+
<span class="nhsuk-u-visually-hidden">Error:</span> @errorMessage
29+
</span>
30+
}
31+
</div>
32+
}
33+
34+
@if (Model.Required && !Model.HasError)
35+
{
2436
<div data-valmsg-for="@Model.AspFor" data-valmsg-replace="true" class="nhsuk-error-message field-validation-valid nhsuk-u-padding-top-1 nhsuk-u-padding-bottom-3">
25-
</div>
26-
}
27-
28-
<div class="nhsuk-radios" aria-required="@(Model.Required ? "true" : "false" )">
29-
@foreach (var (radio, index) in Model.Radios.Select((r, i) => (r, i)))
30-
{
31-
var radioId = $"{radio.Value}-{index}";
32-
<div class="nhsuk-radios__item">
33-
<input class="nhsuk-radios__input"
34-
id="@radioId"
35-
name="@Model.AspFor"
36-
type="radio"
37-
value="@radio.Value"
38-
aria-describedby="@radio.Value-item-hint"
39-
data-val-required="@(Model.Required ? Model.RequiredClientSideErrorMessage : "" )"
40-
data-val="@(Model.Required ? "true" : "false" )"
41-
@(radio.Selected ? "checked" : string.Empty) />
42-
<label class="nhsuk-label nhsuk-radios__label" for="@radioId">
43-
@radio.Label
44-
</label>
45-
@if (radio.HintText != null)
46-
{
47-
<div class="nhsuk-hint nhsuk-radios__hint" id="@radio.Value-item-hint">
48-
@radio.HintText
4937
</div>
50-
}
51-
</div>
52-
}
38+
}
39+
40+
<div class="nhsuk-radios" aria-required="@(Model.Required ? "true" : "false" )">
41+
@foreach (var (radio, index) in Model.Radios.Select((r, i) => (r, i)))
42+
{
43+
var radioId = $"{radio.Value}-{index}";
44+
if (!string.IsNullOrWhiteSpace(Model.Class))
45+
{
46+
<div class="@Model.Class">
47+
<div class="nhsuk-radios__item">
48+
<input class="nhsuk-radios__input"
49+
id="@radioId"
50+
name="@Model.AspFor"
51+
type="radio"
52+
value="@radio.Value"
53+
aria-describedby="@radio.Value-item-hint"
54+
data-val-required="@(Model.Required ? Model.RequiredClientSideErrorMessage : "" )"
55+
data-val="@(Model.Required ? "true" : "false" )"
56+
@(radio.Selected ? "checked" : string.Empty) />
57+
<label class="nhsuk-label nhsuk-radios__label" for="@radioId">
58+
@radio.Label
59+
</label>
60+
@if (radio.HintText != null)
61+
{
62+
<div class="nhsuk-hint nhsuk-radios__hint" id="@radio.Value-item-hint">
63+
@radio.HintText
64+
</div>
65+
}
66+
</div>
67+
</div>
68+
}
69+
else
70+
{
71+
<div class="nhsuk-radios__item">
72+
<input class="nhsuk-radios__input"
73+
id="@radioId"
74+
name="@Model.AspFor"
75+
type="radio"
76+
value="@radio.Value"
77+
aria-describedby="@radio.Value-item-hint"
78+
data-val-required="@(Model.Required ? Model.RequiredClientSideErrorMessage : "" )"
79+
data-val="@(Model.Required ? "true" : "false" )"
80+
@(radio.Selected ? "checked" : string.Empty) />
81+
<label class="nhsuk-label nhsuk-radios__label" for="@radioId">
82+
@radio.Label
83+
</label>
84+
@if (radio.HintText != null)
85+
{
86+
<div class="nhsuk-hint nhsuk-radios__hint" id="@radio.Value-item-hint">
87+
@radio.HintText
88+
</div>
89+
}
90+
</div>
91+
}
5392

54-
</div>
55-
</fieldset>
93+
}
94+
95+
</div>
96+
</fieldset>
5697

5798
</div>

0 commit comments

Comments
 (0)