FIX Hide and show form fields by toggling the "hide" class instead of jQuery methods

This commit is contained in:
Robbie Averill 2017-05-22 15:54:28 +12:00
parent 2ef5643f39
commit 7c3edd4d51
5 changed files with 50 additions and 29 deletions

View File

@ -189,15 +189,21 @@ class EditableCustomRule extends DataObject
case 'ValueNot': case 'ValueNot':
if ($checkboxField) { if ($checkboxField) {
if ($formFieldWatch->isCheckBoxGroupField()) { if ($formFieldWatch->isCheckBoxGroupField()) {
$expression = sprintf("$.inArray('%s', %s.filter(':checked').map(function(){ return $(this).val();}).get()) > -1", $expression = sprintf(
$fieldValue, $target); "$.inArray('%s', %s.filter(':checked').map(function(){ return $(this).val();}).get()) > -1",
$fieldValue,
$target
);
} else { } else {
$expression = "{$target}.prop('checked')"; $expression = "{$target}.prop('checked')";
} }
} elseif ($radioField) { } elseif ($radioField) {
// We cannot simply get the value of the radio group, we need to find the checked option first. // We cannot simply get the value of the radio group, we need to find the checked option first.
$expression = sprintf('%s.closest(".field, .control-group").find("input:checked").val() == "%s"', $expression = sprintf(
$target, $fieldValue); '%s.closest(".field, .control-group").find("input:checked").val() == "%s"',
$target,
$fieldValue
);
} else { } else {
$expression = sprintf('%s.val() == "%s"', $target, $fieldValue); $expression = sprintf('%s.val() == "%s"', $target, $fieldValue);
} }
@ -211,8 +217,12 @@ class EditableCustomRule extends DataObject
case 'ValueLessThanEqual': case 'ValueLessThanEqual':
case 'ValueGreaterThan': case 'ValueGreaterThan':
case 'ValueGreaterThanEqual': case 'ValueGreaterThanEqual':
$expression = sprintf('%s.val() %s parseFloat("%s")', $target, $expression = sprintf(
$conditionOptions[$this->ConditionOption], $fieldValue); '%s.val() %s parseFloat("%s")',
$target,
$conditionOptions[$this->ConditionOption],
$fieldValue
);
break; break;
default: default:
throw new LogicException("Unhandled rule {$this->ConditionOption}"); throw new LogicException("Unhandled rule {$this->ConditionOption}");
@ -228,14 +238,14 @@ class EditableCustomRule extends DataObject
} }
/** /**
* Returns the opposite of the show/hide pairs of strings * 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.
* *
* @param string $text * @param string $text
*
* @return string * @return string
*/ */
public function toggleDisplayText($text) public function toggleDisplayText($text)
{ {
return (strtolower($text) === 'show') ? 'hide' : 'show'; return (strtolower($text) === 'hide') ? 'removeClass("hide")' : 'addClass("hide")';
} }
} }

View File

@ -760,26 +760,21 @@ JS
$conjunction = $rule['conjunction']; $conjunction = $rule['conjunction'];
$operations = implode(" {$conjunction} ", $rule['operations']); $operations = implode(" {$conjunction} ", $rule['operations']);
$target = $rule['targetFieldID']; $target = $rule['targetFieldID'];
$initialState = $rule['initialState'];
$view = $rule['view'];
$opposite = $rule['opposite'];
$result .= <<<EOS $result .= <<<EOS
\n \n
$('.userform').on('{$events}', $('.userform').on('{$events}',
"{$selectors}", "{$selectors}",
function (){ function (){
if({$operations}) { if ({$operations}) {
$('{$target}').{$view}(); $('{$target}').{$rule['view']};
} else { } else {
$('{$target}').{$opposite}(); $('{$target}').{$rule['opposite']};
} }
}); });
EOS; EOS;
} }
return $result; return $result;
} }
} }

View File

@ -1095,9 +1095,10 @@ 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($result['view']); $result['opposite'] = $rule->toggleDisplayText($opposite);
} }
return (count($result['selectors'])) ? $result : null; return (count($result['selectors'])) ? $result : null;

View File

@ -28,4 +28,15 @@ class EditableCustomRuleTest extends SapphireTest
//Check for greater than sign //Check for greater than sign
$this->assertContains('>', $result2['operation']); $this->assertContains('>', $result2['operation']);
} }
}
/**
* Test that methods are returned for manipulating the presence of the "hide" CSS class depending
* on whether the field should be hidden or shown
*/
public function testToggleDisplayText()
{
$rule1 = $this->objFromFixture('EditableCustomRule', 'rule1');
$this->assertSame('addClass("hide")', $rule1->toggleDisplayText('show'));
$this->assertSame('removeClass("hide")', $rule1->toggleDisplayText('hide'));
}
}

View File

@ -205,12 +205,16 @@ class EditableFormFieldTest extends FunctionalTest
$this->assertEquals(20, $attributes['data-rule-maxlength']); $this->assertEquals(20, $attributes['data-rule-maxlength']);
} }
public function testFormatDisplayRules() public function testFormatDisplayRules()
{ {
/** @var EditableCheckbox $checkbox */ $field = $this->objFromFixture('EditableFormField', 'irdNumberField');
$checkbox = $this->objFromFixture('EditableFormField', 'irdNumberField'); $displayRules = $field->formatDisplayRules();
$displayRules = $checkbox->formatDisplayRules(); $this->assertNotNull($displayRules);
$this->assertNotNull($displayRules); $this->assertCount(1, $displayRules['operations']);
$this->assertCount(1, $displayRules['operations']);
} // Field is initially visible, so the "view" method should be to hide it
$this->assertSame('addClass("hide")', $displayRules['view']);
// The opposite method should be to return it to its original state, i.e. show it again
$this->assertSame('removeClass("hide")', $displayRules['opposite']);
}
} }