From 68465b2a38f3b4314c76273a9634e55ae48f3343 Mon Sep 17 00:00:00 2001 From: Rasmus Schultz Date: Mon, 5 Mar 2018 10:40:29 +0100 Subject: [PATCH 1/4] add basic error-summary renderer --- README.md | 2 ++ examples/demo.php | 12 +++------- src/InputRenderer.php | 40 ++++++++++++++++++++++++++++++++ tests/unit/InputRendererCest.php | 18 ++++++++++++++ 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ff5bcf1..8fbc703 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,8 @@ This library has other expected and useful features, including: * Default error messages can be localized/customized. + * A basic error-summary can be generated with `InputRenderer::errorSummary()`. + It deliberately does not implement any of the following: * Trivial elements: things like `
`, `
` and `` - you don't diff --git a/examples/demo.php b/examples/demo.php index 2b581c1..9ed7d51 100644 --- a/examples/demo.php +++ b/examples/demo.php @@ -95,6 +95,8 @@ public function __construct(TokenServiceInterface $token_service) $form = new InputRenderer($model, 'form'); +$form->error_summary_class = "alert alert-danger"; // this example uses a basic bootstrap alert for the error-summary + ?> @@ -131,15 +133,7 @@ public function __construct(TokenServiceInterface $token_service) - hasErrors()): ?> -
-
    - getErrors() as $error): ?> -
  • - -
-
- + errorSummary() ?> diff --git a/src/InputRenderer.php b/src/InputRenderer.php index 43361cd..eb94b97 100644 --- a/src/InputRenderer.php +++ b/src/InputRenderer.php @@ -102,6 +102,13 @@ class InputRenderer */ public $group_attrs = ['class' => 'form-group']; + /** + * @var string error summary CSS class-name + * + * @see errorSummary() + */ + public $error_summary_class = "error-summary"; + /** * @var string[] map where Field name => label override */ @@ -708,4 +715,37 @@ public function labelFor(FieldInterface $field, $label = null, array $attr = []) return $this->label($id, $label); } + + /** + * Build an HTML error summary, if there are any errors. (otherwise, returns an empty string.) + * + * Typically this is used at the end of a form (above the submit button) to call + * attention to the fact that some inputs failed validation - this is meaningful + * on long forms with many inputs, where the user might not immediately notice + * a single input that has been highlighted with an error state. + * + * @return string error summary (or an empty string, if the current model contains no errors) + */ + public function errorSummary() + { + if (! $this->model->hasErrors()) { + return ""; + } + + $errors = implode( + "", + array_map( + function ($str) { + return "
  • " . $this->escape($str) . "
  • "; + }, + $this->model->getErrors() + ) + ); + + return $this->tag( + "div", + ["class" => $this->error_summary_class], + "
      {$errors}
    " + ); + } } diff --git a/tests/unit/InputRendererCest.php b/tests/unit/InputRendererCest.php index fdc481d..14b0c04 100644 --- a/tests/unit/InputRendererCest.php +++ b/tests/unit/InputRendererCest.php @@ -248,4 +248,22 @@ public function buildInput(UnitTester $I) $I->assertSame('', $form->input("hidden", "foo", "bar", ["data-bat" => "baz"])); } + + public function buildErrorSummary(UnitTester $I) + { + $form = new InputRenderer(); + + $field = new TextField("test"); + + $field->setLabel("Something"); + + $expected_error_message = "Unacceptable, Sir!"; + + $form->model->setError($field, $expected_error_message); + + $I->assertSame( + "
    • {$expected_error_message}
    ", + $form->errorSummary() + ); + } } From 1a1c1495098bb5b2e84e6ae2ed1132814a4004a1 Mon Sep 17 00:00:00 2001 From: Rasmus Schultz Date: Wed, 7 Mar 2018 11:16:13 +0100 Subject: [PATCH 2/4] accessible error-summary --- src/InputRenderer.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/InputRenderer.php b/src/InputRenderer.php index eb94b97..9bfb0e0 100644 --- a/src/InputRenderer.php +++ b/src/InputRenderer.php @@ -744,7 +744,10 @@ function ($str) { return $this->tag( "div", - ["class" => $this->error_summary_class], + [ + "role" => "alert", + "class" => $this->error_summary_class + ], "
      {$errors}
    " ); } From d4c8e78bd7e35a01e3895b75f43f2a5edde4bb70 Mon Sep 17 00:00:00 2001 From: Rasmus Schultz Date: Wed, 7 Mar 2018 11:17:49 +0100 Subject: [PATCH 3/4] fix test --- tests/unit/InputRendererCest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/InputRendererCest.php b/tests/unit/InputRendererCest.php index 14b0c04..fc2cf01 100644 --- a/tests/unit/InputRendererCest.php +++ b/tests/unit/InputRendererCest.php @@ -262,7 +262,7 @@ public function buildErrorSummary(UnitTester $I) $form->model->setError($field, $expected_error_message); $I->assertSame( - "
    • {$expected_error_message}
    ", + "
    • {$expected_error_message}
    ", $form->errorSummary() ); } From 990a48aa0dc1131ad571da5f491669ea5f8b80ae Mon Sep 17 00:00:00 2001 From: Rasmus Schultz Date: Wed, 7 Mar 2018 11:30:29 +0100 Subject: [PATCH 4/4] bugfix --- tests/unit/InputRendererCest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/InputRendererCest.php b/tests/unit/InputRendererCest.php index fc2cf01..eef9013 100644 --- a/tests/unit/InputRendererCest.php +++ b/tests/unit/InputRendererCest.php @@ -262,7 +262,7 @@ public function buildErrorSummary(UnitTester $I) $form->model->setError($field, $expected_error_message); $I->assertSame( - "
    • {$expected_error_message}
    ", + "
    • {$expected_error_message}
    ", $form->errorSummary() ); }