-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #31 from ministryofjustice/story/CCMSPUI-468-creat…
…e-date-picker CCMSPUI-468: Create MOJ date picker component
- Loading branch information
Showing
8 changed files
with
303 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
...-govuk-dialect/src/main/java/uk/gov/laa/ccms/springboot/dialect/DatePickerAttributes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package uk.gov.laa.ccms.springboot.dialect; | ||
|
||
/** | ||
* DatePickerAttributes. | ||
*/ | ||
public record DatePickerAttributes( | ||
String id, | ||
String name, | ||
String label, | ||
String hint, | ||
String errorMessage, | ||
String value, | ||
String minDate, | ||
String maxDate) { | ||
|
||
public boolean hasError() { | ||
return errorMessage != null && !errorMessage.isBlank(); | ||
} | ||
} |
110 changes: 110 additions & 0 deletions
110
...alect/src/main/java/uk/gov/laa/ccms/springboot/dialect/DatePickerElementTagProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package uk.gov.laa.ccms.springboot.dialect; | ||
|
||
import static org.springframework.util.StringUtils.hasText; | ||
|
||
import java.util.Map; | ||
import org.thymeleaf.context.ITemplateContext; | ||
import org.thymeleaf.model.IModel; | ||
import org.thymeleaf.model.IModelFactory; | ||
import org.thymeleaf.model.IProcessableElementTag; | ||
import org.thymeleaf.processor.element.AbstractElementTagProcessor; | ||
import org.thymeleaf.processor.element.IElementTagStructureHandler; | ||
import org.thymeleaf.templatemode.TemplateMode; | ||
|
||
/** | ||
* Transforms <moj:datepicker/> elements into standard HTML button elements. | ||
*/ | ||
public class DatePickerElementTagProcessor extends AbstractElementTagProcessor { | ||
|
||
private static final String TAG_NAME = "datepicker"; | ||
private static final int PRECEDENCE = 900; | ||
|
||
public DatePickerElementTagProcessor() { | ||
super(TemplateMode.HTML, "moj", TAG_NAME, true, null, false, PRECEDENCE); | ||
} | ||
|
||
@Override | ||
protected void doProcess(ITemplateContext context, IProcessableElementTag tag, | ||
IElementTagStructureHandler structureHandler) { | ||
|
||
Map<String, String> attributes = ProcessorUtils.parseAttributes(context, tag); | ||
DatePickerAttributes datePickerAttributes = new DatePickerAttributes( | ||
attributes.getOrDefault("id", "date"), | ||
attributes.getOrDefault("name", "date"), | ||
attributes.getOrDefault("label", "Date"), | ||
attributes.get("hint"), | ||
attributes.get("errorMessage"), | ||
attributes.get("value"), | ||
attributes.get("minDate"), | ||
attributes.get("maxDate") | ||
); | ||
|
||
String datePickerHtml = buildDatePickerHtml(datePickerAttributes); | ||
final IModelFactory modelFactory = context.getModelFactory(); | ||
final IModel model = modelFactory.parse(context.getTemplateData(), datePickerHtml); | ||
structureHandler.replaceWith(model, false); | ||
|
||
} | ||
|
||
private String buildDatePickerHtml(DatePickerAttributes datePickerAttributes) { | ||
StringBuilder html = new StringBuilder(); | ||
html.append("<div class=\"moj-datepicker\" data-module=\"moj-date-picker\""); | ||
|
||
if (hasText(datePickerAttributes.minDate())) { | ||
html.append(" data-min-date=\"").append(datePickerAttributes.minDate()).append("\""); | ||
} | ||
if (hasText(datePickerAttributes.maxDate())) { | ||
html.append(" data-max-date=\"").append(datePickerAttributes.maxDate()).append("\""); | ||
} | ||
|
||
html.append(">") | ||
.append("<div class=\"govuk-form-group"); | ||
|
||
if (datePickerAttributes.hasError()) { | ||
html.append(" govuk-form-group--error"); | ||
} | ||
|
||
html.append("\">") | ||
.append("<label class=\"govuk-label\" for=\"").append(datePickerAttributes.id()) | ||
.append("\">") | ||
.append(datePickerAttributes.label()) | ||
.append("</label>") | ||
.append("<div id=\"").append(datePickerAttributes.id()) | ||
.append("-hint\" class=\"govuk-hint\">") | ||
.append(datePickerAttributes.hint()) | ||
.append("</div>"); | ||
|
||
if (datePickerAttributes.hasError()) { | ||
html.append("<p id=\"").append(datePickerAttributes.id()) | ||
.append("-error\" class=\"govuk-error-message\">") | ||
.append("<span class=\"govuk-visually-hidden\">Error:</span> ") | ||
.append(datePickerAttributes.errorMessage()) | ||
.append("</p>"); | ||
} | ||
|
||
html.append("<input class=\"govuk-input moj-js-datepicker-input"); | ||
|
||
if (datePickerAttributes.hasError()) { | ||
html.append(" govuk-input--error"); | ||
} | ||
|
||
html.append("\" id=\"").append(datePickerAttributes.id()) | ||
.append("\" name=\"").append(datePickerAttributes.name()) | ||
.append("\" type=\"text\" aria-describedby=\"").append(datePickerAttributes.id()) | ||
.append("-hint"); | ||
|
||
if (datePickerAttributes.hasError()) { | ||
html.append(" ").append(datePickerAttributes.id()).append("-error"); | ||
} | ||
|
||
if (hasText(datePickerAttributes.value())) { | ||
html.append("\" value=\"").append(datePickerAttributes.value()); | ||
} | ||
|
||
html.append("\" autocomplete=\"off\">") | ||
.append("</div>") | ||
.append("</div>"); | ||
|
||
return html.toString(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
...rter-govuk-dialect/src/main/java/uk/gov/laa/ccms/springboot/dialect/MojCustomDialect.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package uk.gov.laa.ccms.springboot.dialect; | ||
|
||
import java.util.Set; | ||
import org.thymeleaf.dialect.AbstractProcessorDialect; | ||
import org.thymeleaf.processor.IProcessor; | ||
import org.thymeleaf.standard.StandardDialect; | ||
|
||
/** | ||
* Develops a custom MoJ dialect. | ||
*/ | ||
public class MojCustomDialect extends AbstractProcessorDialect { | ||
|
||
public MojCustomDialect() { | ||
super("MOJ Custom Dialect", "moj", StandardDialect.PROCESSOR_PRECEDENCE); | ||
} | ||
|
||
@Override | ||
public Set<IProcessor> getProcessors(String dialectPrefix) { | ||
return Set.of(new DatePickerElementTagProcessor()); | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
...rc/test/java/uk/gov/laa/ccms/springboot/dialect/MoJDatePickerElementTagProcessorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package uk.gov.laa.ccms.springboot.dialect; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.thymeleaf.context.Context; | ||
import org.thymeleaf.spring6.SpringTemplateEngine; | ||
|
||
@SpringBootTest(classes = ThymeleafTestConfig.class) | ||
class MoJDatePickerElementTagProcessorTest { | ||
|
||
@Autowired | ||
private SpringTemplateEngine templateEngine; | ||
|
||
@Test | ||
void shouldRenderGovukButton() { | ||
|
||
Context context = new Context(); | ||
String renderedHtml = templateEngine.process("test-datepicker", context); | ||
assertThat(renderedHtml) | ||
.contains( | ||
"<div class=\"moj-datepicker\" data-module=\"moj-date-picker\" data-min-date=\"2000-01-01\" " + | ||
"data-max-date=\"2025-12-31\"><div class=\"govuk-form-group govuk-form-group--error\">" + | ||
"<label class=\"govuk-label\" for=\"dob\">Date of Birth</label><div id=\"dob-hint\" " + | ||
"class=\"govuk-hint\">For example, 01/01/2000.</div><p id=\"dob-error\" " + | ||
"class=\"govuk-error-message\"><span class=\"govuk-visually-hidden\">Error:</span> " + | ||
"Please enter a valid date of birth.</p><input class=\"govuk-input moj-js-datepicker-input " + | ||
"govuk-input--error\" id=\"dob\" name=\"dateOfBirth\" type=\"text\" " + | ||
"aria-describedby=\"dob-hint dob-error\" value=\"2024-01-01\" autocomplete=\"off\">" + | ||
"</div></div>") | ||
.contains( | ||
"<div class=\"moj-datepicker\" data-module=\"moj-date-picker\" " + | ||
"data-min-date=\"2000-01-01\" data-max-date=\"2025-12-31\">" + | ||
"<div class=\"govuk-form-group\"><label class=\"govuk-label\" " + | ||
"for=\"dob\">Date of Birth</label><div id=\"dob-hint\" " + | ||
"class=\"govuk-hint\">For example, 01/01/2000.</div><input " + | ||
"class=\"govuk-input moj-js-datepicker-input\" id=\"dob\" name=\"dateOfBirth\" " + | ||
"type=\"text\" aria-describedby=\"dob-hint\" value=\"2024-01-01\" " + | ||
"autocomplete=\"off\"></div></div>"); | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
...-ccms-spring-boot-starter-govuk-dialect/src/test/resources/templates/test-datepicker.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<!DOCTYPE html> | ||
<html xmlns:moj="http://www.thymeleaf.org" lang="EN"> | ||
<head> | ||
<title>Datepicker Test</title> | ||
</head> | ||
<body> | ||
|
||
<moj:datepicker | ||
id="dob" | ||
name="dateOfBirth" | ||
label="Date of Birth" | ||
hint="For example, 01/01/2000." | ||
errorMessage="Please enter a valid date of birth." | ||
minDate="2000-01-01" | ||
maxDate="2025-12-31" | ||
value="2024-01-01"> | ||
</moj:datepicker> | ||
|
||
<moj:datepicker | ||
id="dob" | ||
name="dateOfBirth" | ||
label="Date of Birth" | ||
hint="For example, 01/01/2000." | ||
minDate="2000-01-01" | ||
maxDate="2025-12-31" | ||
value="2024-01-01"> | ||
</moj:datepicker> | ||
|
||
</body> | ||
</html> |