Merge pull request #870 from creative-commoners/pulls/5.3/reintroduce-conditional-form-steps

FIX Display rules for page breaks/editable form steps now works again
This commit is contained in:
Robbie Averill 2019-03-26 14:02:55 +13:00 committed by GitHub
commit ad9612c3e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 10 deletions

View File

@ -17,6 +17,7 @@ use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\ValidationException; use SilverStripe\ORM\ValidationException;
use SilverStripe\Security\Security; use SilverStripe\Security\Security;
use SilverStripe\UserForms\Form\UserForm; use SilverStripe\UserForms\Form\UserForm;
use SilverStripe\UserForms\Model\EditableFormField;
use SilverStripe\UserForms\Model\EditableFormField\EditableFileField; use SilverStripe\UserForms\Model\EditableFormField\EditableFileField;
use SilverStripe\UserForms\Model\Submission\SubmittedForm; use SilverStripe\UserForms\Model\Submission\SubmittedForm;
use SilverStripe\View\ArrayData; use SilverStripe\View\ArrayData;
@ -166,6 +167,9 @@ class UserDefinedFormController extends PageController
{ {
$rules = ''; $rules = '';
$form = $this->data(); $form = $this->data();
if (!$form) {
return;
}
$formFields = $form->Fields(); $formFields = $form->Fields();
$watch = []; $watch = [];
@ -499,6 +503,7 @@ JS
$conjunction = $rule['conjunction']; $conjunction = $rule['conjunction'];
$operations = implode(" {$conjunction} ", $rule['operations']); $operations = implode(" {$conjunction} ", $rule['operations']);
$target = $rule['targetFieldID']; $target = $rule['targetFieldID'];
$holder = $rule['holder'];
$result .= <<<EOS $result .= <<<EOS
\n \n
@ -507,8 +512,10 @@ JS
function (){ function (){
if ({$operations}) { if ({$operations}) {
$('{$target}').{$rule['view']}; $('{$target}').{$rule['view']};
{$holder}.{$rule['view']}.trigger('{$rule['holder_event']}');
} else { } else {
$('{$target}').{$rule['opposite']}; $('{$target}').{$rule['opposite']};
{$holder}.{$rule['opposite']}.trigger('{$rule['holder_event_opposite']}');
} }
}); });
$("{$target}").find('.hide').removeClass('hide'); $("{$target}").find('.hide').removeClass('hide');

View File

@ -7,14 +7,15 @@ use SilverStripe\CMS\Controllers\CMSMain;
use SilverStripe\Control\Controller; use SilverStripe\Control\Controller;
use SilverStripe\Core\Convert; use SilverStripe\Core\Convert;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use Silverstripe\Versioned\Versioned; use SilverStripe\Security\Member;
use SilverStripe\Versioned\Versioned;
/** /**
* A custom rule for showing / hiding an EditableFormField * A custom rule for showing / hiding an EditableFormField
* based the value of another EditableFormField. * based the value of another EditableFormField.
* *
* @method EditableFormField Parent() * @method EditableFormField Parent()
* @package userforms * @method EditableFormField ConditionField()
* *
* @property string Display * @property string Display
* @property string ConditionOption * @property string ConditionOption
@ -172,7 +173,7 @@ class EditableCustomRule extends DataObject
case 'IsNotBlank': case 'IsNotBlank':
case 'IsBlank': case 'IsBlank':
$expression = ($checkboxField || $radioField) ? "!{$target}.is(\":checked\")" : "{$target}.val() == ''"; $expression = ($checkboxField || $radioField) ? "!{$target}.is(\":checked\")" : "{$target}.val() == ''";
if ($this->ConditionOption == 'IsNotBlank') { if ((string) $this->ConditionOption === 'IsNotBlank') {
//Negate //Negate
$expression = "!({$expression})"; $expression = "!({$expression})";
} }
@ -200,7 +201,7 @@ class EditableCustomRule extends DataObject
$expression = sprintf('%s.val() == "%s"', $target, $fieldValue); $expression = sprintf('%s.val() == "%s"', $target, $fieldValue);
} }
if ($this->ConditionOption == 'ValueNot') { if ((string) $this->ConditionOption === 'ValueNot') {
//Negate //Negate
$expression = "!({$expression})"; $expression = "!({$expression})";
} }
@ -233,11 +234,33 @@ class EditableCustomRule extends DataObject
* Returns the opposite visibility function for the value of the initial visibility field, e.g. show/hide. This * Returns the opposite visibility function for the value of the initial visibility field, e.g. show/hide. This
* will toggle the "hide" class either way, which is handled by CSS. * will toggle the "hide" class either way, which is handled by CSS.
* *
* @param string $text * @param string $initialState
* @param boolean $invert
* @return string * @return string
*/ */
public function toggleDisplayText($text) public function toggleDisplayText($initialState, $invert = false)
{ {
return (strtolower($text) === 'hide') ? 'removeClass("hide")' : 'addClass("hide")'; $action = strtolower($initialState) === 'hide' ? 'removeClass' : 'addClass';
if ($invert) {
$action = $action === 'removeClass' ? 'addClass' : 'removeClass';
}
return sprintf('%s("hide")', $action);
}
/**
* Returns an event name to be dispatched when the field is changed. Matches up with the visibility classes
* added or removed in `toggleDisplayText()`.
*
* @param string $initialState
* @param bool $invert
* @return string
*/
public function toggleDisplayEvent($initialState, $invert = false)
{
$action = strtolower($initialState) === 'hide' ? 'show' : 'hide';
if ($invert) {
$action = $action === 'hide' ? 'show' : 'hide';
}
return sprintf('userform.field.%s', $action);
} }
} }

View File

@ -24,10 +24,12 @@ use SilverStripe\Forms\SegmentField;
use SilverStripe\Forms\TabSet; use SilverStripe\Forms\TabSet;
use SilverStripe\Forms\TextField; use SilverStripe\Forms\TextField;
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\FieldType\DBVarchar; use SilverStripe\ORM\FieldType\DBVarchar;
use SilverStripe\ORM\SS_List;
use SilverStripe\ORM\ValidationException; use SilverStripe\ORM\ValidationException;
use SilverStripe\UserForms\Extension\UserFormFieldEditorExtension; use SilverStripe\UserForms\Extension\UserFormFieldEditorExtension;
use SilverStripe\UserForms\Model\EditableFormField\EditableFieldGroup; use SilverStripe\UserForms\Model\EditableFormField\EditableFieldGroup;
@ -965,9 +967,10 @@ class EditableFormField extends DataObject
/** @var EditableFormField $formFieldWatch */ /** @var EditableFormField $formFieldWatch */
$formFieldWatch = DataObject::get_by_id(EditableFormField::class, $rule->ConditionFieldID); $formFieldWatch = DataObject::get_by_id(EditableFormField::class, $rule->ConditionFieldID);
// Skip deleted fields // Skip deleted fields
if (! $formFieldWatch) { if (!$formFieldWatch) {
continue; continue;
} }
$fieldToWatch = $formFieldWatch->getSelectorFieldOnly(); $fieldToWatch = $formFieldWatch->getSelectorFieldOnly();
$expression = $rule->buildExpression(); $expression = $rule->buildExpression();
@ -980,9 +983,11 @@ class EditableFormField extends DataObject
$result['operations'][] = $expression['operation']; $result['operations'][] = $expression['operation'];
// View/Show should read // View/Show should read
$opposite = ($result['initialState'] === 'hide') ? 'show' : 'hide';
$result['view'] = $rule->toggleDisplayText($result['initialState']); $result['view'] = $rule->toggleDisplayText($result['initialState']);
$result['opposite'] = $rule->toggleDisplayText($opposite); $result['opposite'] = $rule->toggleDisplayText($result['initialState'], true);
$result['holder'] = $this->getSelectorHolder();
$result['holder_event'] = $rule->toggleDisplayEvent($result['initialState']);
$result['holder_event_opposite'] = $rule->toggleDisplayEvent($result['initialState'], true);
} }
return (count($result['selectors'])) ? $result : null; return (count($result['selectors'])) ? $result : null;

View File

@ -43,8 +43,21 @@ class EditableCustomRuleTest extends SapphireTest
*/ */
public function testToggleDisplayText() public function testToggleDisplayText()
{ {
/** @var EditableCustomRule $rule1 */
$rule1 = $this->objFromFixture(EditableCustomRule::class, 'rule1'); $rule1 = $this->objFromFixture(EditableCustomRule::class, 'rule1');
$this->assertSame('addClass("hide")', $rule1->toggleDisplayText('show')); $this->assertSame('addClass("hide")', $rule1->toggleDisplayText('show'));
$this->assertSame('removeClass("hide")', $rule1->toggleDisplayText('hide')); $this->assertSame('removeClass("hide")', $rule1->toggleDisplayText('hide'));
$this->assertSame('removeClass("hide")', $rule1->toggleDisplayText('show', true));
$this->assertSame('addClass("hide")', $rule1->toggleDisplayText('hide', true));
}
public function testToggleDisplayEvent()
{
/** @var EditableCustomRule $rule1 */
$rule1 = $this->objFromFixture(EditableCustomRule::class, 'rule1');
$this->assertSame('userform.field.hide', $rule1->toggleDisplayEvent('show'));
$this->assertSame('userform.field.show', $rule1->toggleDisplayEvent('hide'));
$this->assertSame('userform.field.show', $rule1->toggleDisplayEvent('show', true));
$this->assertSame('userform.field.hide', $rule1->toggleDisplayEvent('hide', true));
} }
} }