Merge pull request #988 from creative-commoners/pulls/5/checkbox-radio-messages

FIX Show custom validation message for checkbox and radio groups
This commit is contained in:
Garion Herman 2020-07-22 11:49:17 +12:00 committed by GitHub
commit 677b3dadea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 106 additions and 6 deletions

View File

@ -3,6 +3,7 @@
namespace SilverStripe\UserForms\FormField; namespace SilverStripe\UserForms\FormField;
use SilverStripe\Forms\CheckboxSetField; use SilverStripe\Forms\CheckboxSetField;
use SilverStripe\UserForms\Model\EditableFormField;
/** /**
* @package userforms * @package userforms
@ -10,6 +11,25 @@ use SilverStripe\Forms\CheckboxSetField;
class UserFormsCheckboxSetField extends CheckboxSetField class UserFormsCheckboxSetField extends CheckboxSetField
{ {
/**
* If your project uses a custom UserFormsCheckboxSetField.ss, ensure that it includes
* `$Top.getValidationAttributesHTML().RAW` so that custom validation messages work
* For further details see
* templates/SilverStripe/UserForms/FormField/UserFormsCheckboxSetField.ss
*
* Use on a template with .RAW - single and double quoted strings will be safely escaped
*
* @return string
* @see EditableFormField::updateFormField()
*/
public function getValidationAttributesHTML()
{
$attrs = array_filter(array_keys($this->getAttributes()), function ($attr) {
return !in_array($attr, ['data-rule-required', 'data-msg-required']);
});
return $this->getAttributesHTML(...$attrs);
}
/** /**
* jQuery validate requires that the value of the option does not contain * jQuery validate requires that the value of the option does not contain
* the actual value of the input. * the actual value of the input.

View File

@ -0,0 +1,32 @@
<?php
namespace SilverStripe\UserForms\FormField;
use SilverStripe\Forms\OptionsetField;
use SilverStripe\UserForms\Model\EditableFormField;
/**
* @package userforms
*/
class UserFormsOptionSetField extends OptionsetField
{
/**
* If your project uses a custom UserFormsCheckboxSetField.ss, ensure that it includes
* `$Top.getValidationAttributesHTML().RAW` so that custom validation messages work
* For further details see
* templates/SilverStripe/UserForms/FormField/UserFormsCheckboxSetField.ss
*
* Use on a template with .RAW - single and double quoted strings will be safely escaped
*
* @return string
* @see EditableFormField::updateFormField()
*/
public function getValidationAttributesHTML()
{
$attrs = array_filter(array_keys($this->getAttributes()), function ($attr) {
return !in_array($attr, ['data-rule-required', 'data-msg-required']);
});
return $this->getAttributesHTML(...$attrs);
}
}

View File

@ -2,7 +2,7 @@
namespace SilverStripe\UserForms\Model\EditableFormField; namespace SilverStripe\UserForms\Model\EditableFormField;
use SilverStripe\Forms\OptionsetField; use SilverStripe\UserForms\FormField\UserFormsOptionSetField;
use SilverStripe\UserForms\Model\EditableCustomRule; use SilverStripe\UserForms\Model\EditableCustomRule;
/** /**
@ -35,9 +35,9 @@ class EditableRadioField extends EditableMultipleOptionField
public function getFormField() public function getFormField()
{ {
$field = OptionsetField::create($this->Name, $this->Title ?: false, $this->getOptionsMap()) $field = UserFormsOptionSetField::create($this->Name, $this->Title ?: false, $this->getOptionsMap())
->setFieldHolderTemplate(EditableMultipleOptionField::class . '_holder') ->setFieldHolderTemplate(EditableMultipleOptionField::class . '_holder')
->setTemplate('SilverStripe\\UserForms\\FormField\\UserFormsOptionSetField'); ->setTemplate(UserFormsOptionSetField::class);
// Set default item // Set default item
$defaultOption = $this->getDefaultOptions()->first(); $defaultOption = $this->getDefaultOptions()->first();

View File

@ -7,6 +7,12 @@ Check the below if you have any issues during installation or use
After installation make sure you have done a `dev/build` you may also need to flush the admin view by appending After installation make sure you have done a `dev/build` you may also need to flush the admin view by appending
`?flush=1` to the URL, e.g. `http://yoursite.com/admin?flush=1` `?flush=1` to the URL, e.g. `http://yoursite.com/admin?flush=1`
## Checkbox or Radio group custom messages not showing
If your project has a custom template for `UserFormsCheckboxSetField.ss` or `UserFormsOptionSetField.ss`, then you will need to ensure they include `$Top.getValidationAttributesHTML().RAW`. See
* [UserFormsCheckboxSetField.ss](../../templates/SilverStripe/UserForms/FormField/UserFormsCheckboxSetField.ss)
* [UserFormsOptionSetField.ss](../../templates/SilverStripe/UserForms/FormField/UserFormsOptionSetField.ss)
## UserForms EditableFormField Column Clean task ## UserForms EditableFormField Column Clean task
This task is used to clear unused columns from EditableFormField database tables. This task is used to clear unused columns from EditableFormField database tables.

View File

@ -2,7 +2,8 @@
<% loop $Options %> <% loop $Options %>
<div class="$Class"> <div class="$Class">
<input id="$ID" class="checkbox" name="$Name" type="checkbox" value="$Value.ATT"<% if $isChecked %> <input id="$ID" class="checkbox" name="$Name" type="checkbox" value="$Value.ATT"<% if $isChecked %>
checked="checked"<% end_if %><% if $isDisabled %> disabled="disabled"<% end_if %> /> checked="checked"<% end_if %><% if $isDisabled %> disabled="disabled"<% end_if %>
$Top.getValidationAttributesHTML().RAW />
<label for="$ID">$Title.XML</label> <label for="$ID">$Title.XML</label>
</div> </div>
<% end_loop %> <% end_loop %>

View File

@ -1,7 +1,8 @@
<% loop $Options %> <% loop $Options %>
<div class="$Class"> <div class="$Class">
<input id="$ID" class="radio" name="$Name" type="radio" value="$Value.ATT"<% if $isChecked %> <input id="$ID" class="radio" name="$Name" type="radio" value="$Value.ATT"<% if $isChecked %>
checked<% end_if %><% if $isDisabled %> disabled<% end_if %> <% if $Up.Required %>required<% end_if %> /> checked<% end_if %><% if $isDisabled %> disabled<% end_if %> <% if $Up.Required %>required<% end_if %>
$Top.getValidationAttributesHTML().RAW />
<label for="$ID">$Title</label> <label for="$ID">$Title</label>
</div> </div>
<% end_loop %> <% end_loop %>

View File

@ -5,9 +5,12 @@ namespace SilverStripe\UserForms\Tests\FormField;
use SilverStripe\Dev\SapphireTest; use SilverStripe\Dev\SapphireTest;
use SilverStripe\UserForms\Form\UserFormsRequiredFields; use SilverStripe\UserForms\Form\UserFormsRequiredFields;
use SilverStripe\UserForms\FormField\UserFormsCheckboxSetField; use SilverStripe\UserForms\FormField\UserFormsCheckboxSetField;
use SilverStripe\UserForms\Model\EditableFormField\EditableCheckboxGroupField;
class UserFormsCheckboxSetFieldTest extends SapphireTest class UserFormsCheckboxSetFieldTest extends SapphireTest
{ {
protected static $fixture_file = '../UserFormsTest.yml';
public function testValidate() public function testValidate()
{ {
$field = new UserFormsCheckboxSetField('Field', 'My field', ['One' => 'One', 'Two' => 'Two']); $field = new UserFormsCheckboxSetField('Field', 'My field', ['One' => 'One', 'Two' => 'Two']);
@ -33,4 +36,16 @@ class UserFormsCheckboxSetFieldTest extends SapphireTest
$field->setValue(array('Three', 'Four')); $field->setValue(array('Three', 'Four'));
$this->assertFalse($field->validate($validator)); $this->assertFalse($field->validate($validator));
} }
public function testCustomErrorMessageValidationAttributesHTML()
{
/** @var EditableCheckboxGroupField $editableCheckboxGroupField */
$editableCheckboxGroupField = $this->objFromFixture(EditableCheckboxGroupField::class, 'checkbox-group');
$editableCheckboxGroupField->Required = true;
$editableCheckboxGroupField->CustomErrorMessage = 'My custom error message with \'single\' and "double" quotes';
$userFormsCheckboxSetField = $editableCheckboxGroupField->getFormField();
$html = $userFormsCheckboxSetField->renderWith(UserFormsCheckboxSetField::class)->getValue();
$attributesHTML = 'data-rule-required="true" data-msg-required="My custom error message with &amp;#039;single&amp;#039; and &amp;quot;double&amp;quot; quotes"';
$this->assertTrue(strpos($html, $attributesHTML) > 0);
}
} }

View File

@ -0,0 +1,24 @@
<?php
namespace SilverStripe\UserForms\Tests\FormField;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\UserForms\FormField\UserFormsOptionSetField;
use SilverStripe\UserForms\Model\EditableFormField\EditableRadioField;
class UserFormsOptionSetFieldTest extends SapphireTest
{
protected static $fixture_file = '../UserFormsTest.yml';
public function testCustomErrorMessageValidationAttributesHTML()
{
/** @var UserFormsOptionSetField $userFormsOptionSetField */
$radio = $this->objFromFixture(EditableRadioField::class, 'radio-field');
$radio->Required = true;
$radio->CustomErrorMessage = 'My custom error message with \'single\' and "double" quotes';
$userFormsOptionSetField = $radio->getFormField();
$html = $userFormsOptionSetField->renderWith(UserFormsOptionSetField::class)->getValue();
$attributesHTML = 'data-rule-required="true" data-msg-required="My custom error message with &amp;#039;single&amp;#039; and &amp;quot;double&amp;quot; quotes"';
$this->assertTrue(strpos($html, $attributesHTML) > 0);
}
}

View File

@ -3,6 +3,7 @@
namespace SilverStripe\UserForms\Tests\Model\EditableFormField; namespace SilverStripe\UserForms\Tests\Model\EditableFormField;
use SilverStripe\Dev\SapphireTest; use SilverStripe\Dev\SapphireTest;
use SilverStripe\UserForms\FormField\UserFormsOptionSetField;
use SilverStripe\UserForms\Model\EditableFormField\EditableRadioField; use SilverStripe\UserForms\Model\EditableFormField\EditableRadioField;
class EditableRadioFieldTest extends SapphireTest class EditableRadioFieldTest extends SapphireTest
@ -16,7 +17,7 @@ class EditableRadioFieldTest extends SapphireTest
{ {
$radio = $this->objFromFixture(EditableRadioField::class, 'radio-field'); $radio = $this->objFromFixture(EditableRadioField::class, 'radio-field');
$this->assertSame( $this->assertSame(
'SilverStripe\\UserForms\\FormField\\UserFormsOptionSetField', UserFormsOptionSetField::class,
$radio->getFormField()->getTemplate() $radio->getFormField()->getTemplate()
); );
} }