Skip to content

Commit 74c9eda

Browse files
committed
Add imperial weight input with unit switching
1 parent 4de6fa8 commit 74c9eda

File tree

7 files changed

+133
-8
lines changed

7 files changed

+133
-8
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{% from 'nhsuk/components/input/macro.jinja' import input %}
2+
{% from 'nhsuk/components/error-message/macro.jinja' import errorMessage %}
3+
4+
{% if field.errors | length > 0 %}
5+
{% set error_message = field.errors | first %}
6+
{% endif %}
7+
{% set unbound_field = field.field %}
8+
{% set hint = unbound_field.hint %}
9+
{% set form_group_error_classes = ' nhsuk-form-group--error' if error_message else '' %}
10+
{% set field_error_classes = ' nhsuk-input--error' if error_message else '' %}
11+
12+
<div id="{{ field.html_name }}" class="multi-field-input nhsuk-form-group{{ form_group_error_classes }}">
13+
{% if error_message %}
14+
{{ errorMessage({
15+
"id": field.auto_id,
16+
"text": error_message
17+
}) }}
18+
{% endif %}
19+
20+
<div class="multi-field-input__item">
21+
{{ input({
22+
"label": {
23+
"text": "Stone",
24+
"classes": "nhsuk-fieldset__legend--m",
25+
"isPageHeading": false
26+
},
27+
"hint": {
28+
"text": unbound_field.hint
29+
} if unbound_field.hint,
30+
"id": field.auto_id + "_0",
31+
"name": field.html_name + "_0",
32+
"value": field.subwidgets.0.data.value,
33+
"classes": "nhsuk-input--width-2" + field_error_classes,
34+
"type": "number"
35+
}) }}
36+
</div>
37+
38+
<div class="multi-field-input__item">
39+
{{ input({
40+
"label": {
41+
"text": "Pounds",
42+
"classes": "nhsuk-fieldset__legend--m",
43+
"isPageHeading": false
44+
},
45+
"id": field.auto_id + "_1",
46+
"name": field.html_name + "_1",
47+
"value": field.subwidgets.1.data.value,
48+
"classes": "nhsuk-input--width-2" + field_error_classes,
49+
"type": "number"
50+
}) }}
51+
</div>
52+
</div>

lung_cancer_screening/core/tests/acceptance/test_questionnaire.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ def test_full_questionnaire_user_journey(self):
7979
page.click("text=Back")
8080
page.get_by_role("link", name="Switch to stone and pounds").click()
8181
fill_in_and_submit_weight_imperial(page, weight_stone, weight_pound)
82+
expect(page).to_have_url(f"{self.live_server_url}/responses")
8283
responses = page.locator(".responses")
8384
expect(responses).to_contain_text("Have you ever smoked? Yes, I used to smoke regularly")
8485
expect(responses).to_contain_text(
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from django import forms
2+
3+
from lung_cancer_screening.core.form_fields import ImperialWeightField
4+
from ..models.response_set import ResponseSet
5+
6+
class ImperialWeightForm(forms.ModelForm):
7+
8+
def __init__(self, *args, **kwargs):
9+
self.participant = kwargs.pop('participant')
10+
super().__init__(*args, **kwargs)
11+
self.instance.participant = self.participant
12+
13+
self.fields["weight_imperial"] = ImperialWeightField(
14+
label="Weight",
15+
required=True,
16+
require_all_fields=False,
17+
error_messages={
18+
'required': 'Enter your weight.',
19+
'incomplete': 'Enter your weight.'
20+
}
21+
)
22+
23+
def clean_weight_metric(self):
24+
return None
25+
26+
class Meta:
27+
model = ResponseSet
28+
fields = ['weight_imperial', 'weight_metric']

lung_cancer_screening/questions/jinja2/weight.jinja

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@
2020
{% block page_content %}
2121
<div class="nhsuk-grid-row">
2222
<div class="nhsuk-grid-column-two-thirds">
23-
<form action="{{request.path}}" method="POST" novalidate>
23+
{% if unit %}
24+
{% set action_url = request.path + '?unit=' + unit %}
25+
{% else %}
26+
{% set action_url = request.path %}
27+
{% endif %}
28+
<form action="{{ action_url }}" method="POST" novalidate>
2429
{{ csrf_input }}
2530
<h1 class="nhsuk-heading-l">Enter your weight</h1>
2631

@@ -35,7 +40,12 @@
3540
}
3641
}) %}
3742

38-
{{form.weight_metric.as_field_group()}}
43+
{% if unit == "imperial" %}
44+
{{ form.weight_imperial.as_field_group() }}
45+
{% else %}
46+
{{ form.weight_metric.as_field_group() }}
47+
{% endif %}
48+
3949
<p><a href="?unit={{ switch_to_unit }}">Switch to {{ WEIGHT_UNIT[switch_to_unit] }}</a></p>
4050
{% endcall %}
4151

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Generated by Django 5.2.7 on 2025-10-27 12:36
2+
3+
import django.core.validators
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('questions', '0011_responseset_weight_metric_and_more'),
11+
]
12+
13+
operations = [
14+
migrations.AddField(
15+
model_name='responseset',
16+
name='weight_imperial',
17+
field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(56, message='Weight must be between 4 stone and 50 stone'), django.core.validators.MaxValueValidator(700, message='Weight must be between 4 stone and 50 stone')]),
18+
),
19+
migrations.AlterField(
20+
model_name='responseset',
21+
name='weight_metric',
22+
field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(254, message='Weight must be between 25.4kg and 317.5kg'), django.core.validators.MaxValueValidator(3175, message='Weight must be between 25.4kg and 317.5kg')]),
23+
),
24+
]

lung_cancer_screening/questions/models/response_set.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,19 @@ class ResponseSet(BaseModel):
4141

4242
MIN_WEIGHT_METRIC = 254
4343
MAX_WEIGHT_METRIC = 3175
44+
MAX_WEIGHT_IMPERIAL = 700
45+
MIN_WEIGHT_IMPERIAL = 56
4446

4547
weight_metric = models.PositiveIntegerField(null=True, blank=True, validators=[
4648
MinValueValidator(MIN_WEIGHT_METRIC, message="Weight must be between 25.4kg and 317.5kg"),
4749
MaxValueValidator(MAX_WEIGHT_METRIC, message="Weight must be between 25.4kg and 317.5kg"),
4850
])
49-
51+
weight_imperial = models.PositiveIntegerField(null=True, blank=True, validators=[
52+
MinValueValidator(
53+
MIN_WEIGHT_IMPERIAL, message="Weight must be between 4 stone and 50 stone"),
54+
MaxValueValidator(
55+
MAX_WEIGHT_IMPERIAL, message="Weight must be between 4 stone and 50 stone"),
56+
])
5057
submitted_at = models.DateTimeField(null=True, blank=True)
5158

5259
class Meta:
@@ -82,8 +89,8 @@ def formatted_height(self):
8289
def formatted_weight(self):
8390
if self.weight_metric:
8491
return f"{Decimal(self.weight_metric) / 10}kg"
85-
# elif self.height_imperial:
86-
# value = Decimal(self.weight_imperial)
87-
# return f"{value // 12} feet {value % 12} inches"
92+
elif self.weight_imperial:
93+
value = Decimal(self.weight_imperial)
94+
return f"{value // 14} stone {value % 14} pounds"
8895

8996

lung_cancer_screening/questions/views/weight.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
from django.shortcuts import render, redirect
22

33
from lung_cancer_screening.questions.forms.metric_weight_form import MetricWeightForm
4+
from lung_cancer_screening.questions.forms.imperial_weight_form import ImperialWeightForm
45
from .decorators.participant_decorators import require_participant
56

67
@require_participant
78
def weight(request):
89
unit = request.GET.get('unit')
10+
form_klass = ImperialWeightForm if unit == "imperial" else MetricWeightForm
11+
912
if request.method == "POST":
10-
form=MetricWeightForm(
13+
form = form_klass(
1114
instance=request.participant.responseset_set.last(),
1215
data=request.POST,
1316
participant=request.participant
@@ -30,7 +33,7 @@ def weight(request):
3033
request,
3134
"weight.jinja",
3235
{
33-
"form": MetricWeightForm(participant=request.participant),
36+
"form": form_klass(participant=request.participant),
3437
"unit": unit,
3538
"switch_to_unit": "metric" if unit == "imperial" else "imperial"
3639
}

0 commit comments

Comments
 (0)