Skip to content

Commit

Permalink
feat(Form): add support for valid feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
neilime committed Jul 1, 2020
1 parent 36c7ac1 commit 832ac6b
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 23 deletions.
36 changes: 13 additions & 23 deletions src/TwbsHelper/Form/View/Helper/FormRow.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,6 @@ public function renderFormRow(\Laminas\Form\ElementInterface $oElement, $sElemen
$aRowClasses[] = 'has-error';
}

if ($oElement->getOption('feedback')) {
$aRowClasses[] = 'has-feedback';
}

// Column
$sColum = $oElement->getOption('column');
if ($sColum) {
Expand Down Expand Up @@ -211,18 +207,18 @@ protected function renderElement(\Laminas\Form\ElementInterface $oElement, strin
case null:
case \TwbsHelper\Form\View\Helper\Form::LAYOUT_INLINE:
$aRenderingOrder = [
'renderFeedback' => [],
'renderLabel' => [$sLabelPosition],
'renderHelpBlock' => [],
'renderErrors' => [],
'renderValidFeedback' => [],
'renderDedicatedContainer' => [],
];
break;
case \TwbsHelper\Form\View\Helper\Form::LAYOUT_HORIZONTAL:
$aRenderingOrder = [
'renderFeedback' => [],
'renderHelpBlock' => [],
'renderErrors' => [],
'renderValidFeedback' => [],
'renderDedicatedContainer' => [],
];
break;
Expand Down Expand Up @@ -381,35 +377,29 @@ protected function renderHelpBlock(\Laminas\Form\ElementInterface $oElement, str
* @param \Laminas\Form\ElementInterface $oElement
* @return string
*/
protected function renderErrors(\Laminas\Form\ElementInterface $oElement, string $sElementContent): string
protected function renderValidFeedback(\Laminas\Form\ElementInterface $oElement, string $sElementContent): string
{
if ($this->renderErrors) {
$sElementErrorsContent = $this->getElementErrorsHelper()->render($oElement);
if ($sElementErrorsContent) {
$sElementContent .= PHP_EOL . $sElementErrorsContent;
}
$sValidFeedback = $oElement->getOption('valid_feedback');
if ($sValidFeedback) {
$sValidFeedbackContent = $this->htmlElement('div',['class' => 'valid-feedback'], $sValidFeedback);
$sElementContent .= PHP_EOL . $sValidFeedbackContent;
}
return $sElementContent;
}

/**
* Render element's feedback
* Render element's errors
*
* @param \Laminas\Form\ElementInterface $oElement
* @param string $sElementContent
* @return string
*/
protected function renderFeedback(\Laminas\Form\ElementInterface $oElement, string $sElementContent): string
protected function renderErrors(\Laminas\Form\ElementInterface $oElement, string $sElementContent): string
{
$sFeedback = $oElement->getOption('feedback');
if ($sFeedback) {
if (!is_string($sFeedback)) {
throw new \InvalidArgumentException(sprintf(
'Argument "$sFeedbackElement" expects a string, "%s" given',
is_object($sFeedback) ? get_class($sFeedback) : gettype($sFeedback)
));
if ($this->renderErrors) {
$sElementErrorsContent = $this->getElementErrorsHelper()->render($oElement);
if ($sElementErrorsContent) {
$sElementContent .= PHP_EOL . $sElementErrorsContent;
}
$sElementContent .= '<i class="' . $sFeedback . ' form-control-feedback"></i>';
}
return $sElementContent;
}
Expand Down
1 change: 1 addition & 0 deletions tests/TestSuite/Documentation/Components/Forms.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
include __DIR__ . DIRECTORY_SEPARATOR . 'Forms/Layout.php',
include __DIR__ . DIRECTORY_SEPARATOR . 'Forms/HelpText.php',
include __DIR__ . DIRECTORY_SEPARATOR . 'Forms/DisabledForms.php',
include __DIR__ . DIRECTORY_SEPARATOR . 'Forms/Validation.php',
include __DIR__ . DIRECTORY_SEPARATOR . 'Forms/CustomForms.php',
],
];
191 changes: 191 additions & 0 deletions tests/TestSuite/Documentation/Components/Forms/Validation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
<?php

// Documentation test config file for "Components / Forms / Validation" part
return [
'title' => 'Validation',
'url' => '%bootstrap-url%/components/forms/#validation',
'tests' => [
[
'title' => 'Server side',
'url' => '%bootstrap-url%/components/forms/#server-side',
'rendering' => function (\Laminas\View\Renderer\PhpRenderer $oView) {
$oFactory = new \Laminas\Form\Factory();

$oForm = $oFactory->create([
'type' => 'form',
'options' => ['row_class' => 'form-row'],
'elements' => [
[
'spec' => [
'name' => 'firstName',
'options' => [
'column' => 'md-6',
'row_class' => 'mb-3',
'label' => 'First name',
'valid_feedback' => 'Looks good!',
'row_name' => 'firstRow',
],
'attributes' => [
'type' => 'text',
'value' => 'Mark',
'id' => 'validationServer01',
'required' => true,
],
],
],
[
'spec' => [
'name' => 'lastName',
'options' => [
'column' => 'md-6',
'row_class' => 'mb-3',
'label' => 'Last name',
'valid_feedback' => 'Looks good!',
'row_name' => 'firstRow',
],
'attributes' => [
'type' => 'text',
'value' => 'Otto',
'id' => 'validationServer02',
'required' => true,
],
],
],
[
'spec' => [
'name' => 'city',
'options' => [
'column' => 'md-6',
'row_class' => 'mb-3',
'label' => 'City',
'row_name' => 'secondRow',
],
'attributes' => [
'type' => 'text',
'id' => 'validationServer03',
'required' => true,
],
],
],
[
'spec' => [
'name' => 'state',
'type' => 'select',
'options' => [
'custom' => true,
'empty_option' => ['label' => 'Choose...', 'selected' => true, 'disabled' => true],
'value_options' => ['...'],
'column' => 'md-3',
'row_class' => 'mb-3',
'label' => 'State',
'row_name' => 'secondRow',
],
'attributes' => [
'id' => 'validationServer04',
'required' => true,
],
],
],
[
'spec' => [
'name' => 'zip',
'options' => [
'column' => 'md-3',
'row_class' => 'mb-3',
'label' => 'Zip',
'row_name' => 'secondRow',
],
'attributes' => [
'type' => 'text',
'id' => 'validationServer05',
'required' => true,
],
],
],
[
'spec' => [
'name' => 'termsAndConditions',
'type' => 'checkbox',
'options' => [
'label' => 'Agree to terms and conditions',
'use_hidden_element' => false,
'row_name' => 'thirdRow',
],
'attributes' => [
'id' => 'invalidCheck3',
'required' => true,
],
],
],
[
'spec' => [
'type' => 'submit',
'options' => [
'label' => 'Submit', 'variant' => 'primary',
'row_name' => 'lastRow',
'form_group' => false,
],
],
],
],
]);

// Set error messages
$oForm->get('city')->setMessages(['Please provide a valid city.']);
$oForm->get('state')->setMessages(['Please select a valid state.']);
$oForm->get('zip')->setMessages(['Please provide a valid zip.']);
$oForm->get('termsAndConditions')->setMessages(['You must agree before submitting.']);


// Render form
echo $oView->form($oForm);
},
'expected' => '<form method="POST" name="form" role="form" id="form">' . PHP_EOL .
' <div class="form-row">' . PHP_EOL .
' <div class="col-md-6&#x20;mb-3">' . PHP_EOL .
' <label for="validationServer01">First name</label>' . PHP_EOL .
' <input name="firstName" type="text" id="validationServer01" required="required" class="form-control" value="Mark">' . PHP_EOL .
' <div class="valid-feedback">' . PHP_EOL .
' Looks good!' . PHP_EOL .
' </div>' . PHP_EOL .
' </div>' . PHP_EOL .
' <div class="col-md-6&#x20;mb-3">' . PHP_EOL .
' <label for="validationServer02">Last name</label>' . PHP_EOL .
' <input name="lastName" type="text" id="validationServer02" required="required" class="form-control" value="Otto">' . PHP_EOL .
' <div class="valid-feedback">' . PHP_EOL .
' Looks good!' . PHP_EOL .
' </div>' . PHP_EOL .
' </div>' . PHP_EOL .
' </div>' . PHP_EOL .
' <div class="form-row">' . PHP_EOL .
' <div class="col-md-6&#x20;has-error&#x20;mb-3">' . PHP_EOL .
' <label class="col-form-label" for="validationServer03">City</label>' . PHP_EOL .
' <input name="city" type="text" id="validationServer03" required="required" class="form-control&#x20;is-invalid" value="">' . PHP_EOL .
' <div class="invalid-feedback">Please provide a valid city.</div>' . PHP_EOL .
' </div>' . PHP_EOL .
' <div class="col-md-3&#x20;has-error&#x20;mb-3">' . PHP_EOL .
' <label class="col-form-label" for="validationServer04">State</label>' . PHP_EOL .
' <select name="state" id="validationServer04" required="required" class="custom-select&#x20;is-invalid">'.PHP_EOL .
' <option value="" selected="selected" disabled="disabled">Choose...</option>' .PHP_EOL .
' <option value="0">...</option>' .PHP_EOL .
' </select>' . PHP_EOL .
' <div class="invalid-feedback">Please select a valid state.</div>' . PHP_EOL .
' </div>' . PHP_EOL .
' <div class="col-md-3&#x20;has-error&#x20;mb-3">' . PHP_EOL .
' <label class="col-form-label" for="validationServer05">Zip</label>' . PHP_EOL .
' <input name="zip" type="text" id="validationServer05" required="required" class="form-control&#x20;is-invalid" value="">' . PHP_EOL .
' <div class="invalid-feedback">Please provide a valid zip.</div>' . PHP_EOL .
' </div>' . PHP_EOL .
' </div>' . PHP_EOL .
' <div class="form-group&#x20;has-error">' . PHP_EOL .
' <div class="form-check">' . PHP_EOL .
' <input type="checkbox" name="termsAndConditions" id="invalidCheck3" required="required" class="form-check-input&#x20;is-invalid" value="1">' . PHP_EOL .
' <label class="form-check-label" for="invalidCheck3">Agree to terms and conditions</label>' . PHP_EOL .
' <div class="invalid-feedback">You must agree before submitting.</div>' . PHP_EOL .
' </div>' . PHP_EOL .
' </div>' . PHP_EOL .
' <button type="submit" name="submit" class="btn&#x20;btn-primary" value="">Submit</button>' . PHP_EOL .
'</form>',
],
],
];

0 comments on commit 832ac6b

Please sign in to comment.