Skip to content

Commit

Permalink
Updated rendering & Correct BEM
Browse files Browse the repository at this point in the history
  • Loading branch information
bajb committed Aug 23, 2020
1 parent decdd83 commit 3a6861b
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 44 deletions.
26 changes: 15 additions & 11 deletions assets/form.css
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
.p-form-field {
.p-form__field {
padding: 5px;
}

.p-form--label {
.p-form__label {
padding: 2px 4px;
}

.p-form--submit input,
.p-form--submit button,
.p-form--input input,
.p-form--input select {
.p-form__submit input,
.p-form__submit button,
.p-form__input input,
.p-form__input select {
line-height: 16px;
font-size: 16px;
padding: 10px 10px;
Expand All @@ -26,21 +26,25 @@
background-color: white;
}

.p-form--submit input,
.p-form--submit button {
.p-form__submit input,
.p-form__submit button {
background-color: #c3c3c3;
color: #313131;
border: 1px solid #8c8c8c;
}

.p-form--submit input:active,
.p-form--submit button:active {
.p-form__submit input:active,
.p-form__submit button:active {
background-color: #c3c3c3;
color: #313131;
border: 1px solid #8c8c8c;
box-shadow: inset 0px 0px 3px #313131;
}

.p-form--input .p-form--checkbox input {
.p-form__input .p-form__checkbox input {
height: 16px;
}

.p-form__errors--hidden {
display: none;
}
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"php": ">=7.1",
"packaged/glimpse": "^2.6",
"packaged/ui": "^1.0",
"packaged-ui/bem-component": "~1.2",
"packaged/validate": "^2.1"
},
"require-dev": {
Expand Down
13 changes: 2 additions & 11 deletions src/Csrf/CsrfDataHandler.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
<?php
namespace Packaged\Form\Csrf;

use Packaged\Form\DataHandlers\AbstractDataHandler;
use Packaged\Form\Decorators\HiddenInputDecorator;
use Packaged\Form\Decorators\Interfaces\DataHandlerDecorator;
use Packaged\Form\DataHandlers\HiddenDataHandler;

class CsrfDataHandler extends AbstractDataHandler
class CsrfDataHandler extends HiddenDataHandler
{
const ERR_INVALID = 'Invalid or missing CSRF token';
protected $_sessionSecret;
Expand Down Expand Up @@ -89,11 +87,4 @@ protected function _setupValidator()
{
$this->addValidator(new CsrfValidator($this->_generatePassword(), $this->_expiryMins));
}

protected function _defaultDecorator(): DataHandlerDecorator
{
$decorator = new HiddenInputDecorator();
$decorator->setHandler($this);
return $decorator;
}
}
20 changes: 14 additions & 6 deletions src/DataHandlers/AbstractDataHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
use Packaged\Form\DataHandlers\Interfaces\DataHandler;
use Packaged\Form\Decorators\AbstractDataHandlerDecorator;
use Packaged\Form\Decorators\Interfaces\DataHandlerDecorator;
use Packaged\Helpers\Strings;
use Packaged\SafeHtml\ISafeHtmlProducer;
use Packaged\Validate\IValidator;
use Packaged\Validate\ValidationException;
use function array_merge;
Expand Down Expand Up @@ -251,30 +253,30 @@ public function setDecorator(DataHandlerDecorator $decorator)
abstract protected function _defaultDecorator(): DataHandlerDecorator;

/**
* @return mixed
* @return string|null
*/
public function getId()
public function getId(): ?string
{
return $this->_id;
}

/**
* @param mixed $id
* @param string $id
*
* @return AbstractDataHandler
*/
public function setId($id)
public function setId(string $id)
{
$this->_id = $id;
return $this;
}

/**
* @return mixed
* @return string
*/
public function getLabel()
{
return $this->_label;
return $this->_label ?? Strings::titleize(Strings::splitOnCamelCase($this->getName()));
}

/**
Expand Down Expand Up @@ -357,4 +359,10 @@ public function __toString()
return $this->render();
}

public function getInput(): ?ISafeHtmlProducer
{
$dec = $this->getDecorator();
$dec->render();
return $dec->getInput();
}
}
10 changes: 6 additions & 4 deletions src/DataHandlers/Interfaces/DataHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
namespace Packaged\Form\DataHandlers\Interfaces;

use Exception;
use Packaged\Form\Decorators\Interfaces\DataHandlerDecorator;
use Packaged\SafeHtml\ISafeHtmlProducer;
use Packaged\Validate\IValidatable;
use Packaged\Validate\ValidationException;

interface DataHandler extends IValidatable
{
public function getId(): ?string;

public function setId(string $id);

/**
* Validate the data, return true if valid, false if invalid
*
Expand Down Expand Up @@ -62,8 +66,6 @@ public function getValue();
*/
public function setValue($value);

public function getDecorator(): DataHandlerDecorator;

public function getDefaultValue();

/**
Expand Down Expand Up @@ -98,5 +100,5 @@ public function addError(ValidationException ...$errors);
*/
public function clearErrors();

public function render(): string;
public function getInput(): ?ISafeHtmlProducer;
}
1 change: 1 addition & 0 deletions src/Decorators/AbstractDataHandlerDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ protected function _configureInputElement(HtmlElement $input)

if(!empty($id))
{
$this->_handler->setId($id);
$input->setId($id);
}

Expand Down
75 changes: 74 additions & 1 deletion src/Decorators/DefaultFormDecorator.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
<?php
namespace Packaged\Form\Decorators;

use Packaged\Form\DataHandlers\HiddenDataHandler;
use Packaged\Form\DataHandlers\Interfaces\DataHandler;
use Packaged\Form\Form\Form;
use Packaged\Form\Form\Interfaces\FormDecorator;
use Packaged\Glimpse\Tags\Div;
use Packaged\Glimpse\Tags\Form\Label;
use Packaged\Glimpse\Tags\Lists\ListItem;
use Packaged\Glimpse\Tags\Lists\UnorderedList;
use Packaged\Helpers\Objects;
use Packaged\SafeHtml\ISafeHtmlProducer;
use Packaged\Ui\Html\HtmlElement;
use PackagedUi\BemComponent\Bem;

class DefaultFormDecorator extends AbstractDecorator implements FormDecorator
{
Expand All @@ -12,10 +21,17 @@ class DefaultFormDecorator extends AbstractDecorator implements FormDecorator
* @var Form
*/
protected $_form;
protected $_bem;

public function __construct()
{
$this->addClass('p-form');
$this->_bem = Bem::block('p-form');
$this->addClass($this->_bem->asString());
}

public function bem(): Bem
{
return $this->_bem;
}

protected function _prepareForProduce(): HtmlElement
Expand Down Expand Up @@ -50,4 +66,61 @@ protected function _getTemplatedPhtmlClassList()
{
return array_unique([get_class($this->getForm()), $this->_getTemplatedPhtmlClass(), self::class]);
}

public function renderHandler(DataHandler $handler): ISafeHtmlProducer
{
if($handler instanceof HiddenDataHandler)
{
return $handler->getInput();
}

//Pre render input, as the ID may be generated in this stage
$input = $this->_renderInput($handler)->produceSafeHTML();

return Div::create(
$this->_renderLabel($handler),
$this->_renderErrors($handler),
$input
)->addClass($this->bem()->getElementName('field'))
->addClass(empty($handler->getErrors()) ? null : $this->bem()->getModifier('error', 'field'));
}

protected function _renderLabel(DataHandler $handler): ?ISafeHtmlProducer
{
$label = $handler->getLabel();
if($label === null || $label === '')
{
return null;
}

return Div::create(
Label::create($label)->setAttribute('for', $handler->getId())
)->addClass($this->bem()->getElementName('label'));
}

protected function _renderErrors(DataHandler $handler): ?ISafeHtmlProducer
{
$errors = $handler->getErrors();
if(empty($errors))
{
return null;
}

return Div::create(
empty($errors) ? null :
UnorderedList::create()->setContent(ListItem::collection(Objects::mpull($errors, 'getMessage')))
)->addClass($this->bem()->getElementName('errors'))
->addClass(empty($errors) ? $this->bem()->getModifier('hidden', 'errors') : null); //Hide when no errors
}

protected function _renderInput(DataHandler $handler): ?ISafeHtmlProducer
{
$input = $handler->getInput();
if($input === null)
{
return null;
}

return Div::create($input)->addClass($this->bem()->getElementName('input'));
}
}
5 changes: 4 additions & 1 deletion src/Decorators/DefaultFormDecorator.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@

use Packaged\Form\Decorators\DefaultFormDecorator;

?><?php foreach($this->getForm()->getDataHandlers() as $handler): ?><?= $handler->getDecorator(); ?><?php endforeach;
?>
<?php foreach($this->getForm()->getDataHandlers() as $handler):
?><?= $this->renderHandler($handler)->produceSafeHTML();
?><?php endforeach;
?><?= $this->getForm()->getSubmitDecorator(); ?>
4 changes: 2 additions & 2 deletions src/Form/FormSubmitDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class FormSubmitDecorator extends AbstractDecorator

public function __construct()
{
$this->addClass('p-form-field');
$this->addClass('p-form__field');
}

public function setValue(string $value)
Expand All @@ -29,7 +29,7 @@ protected function _getValue()

protected function _getContentForRender()
{
return Div::create($this->_input())->addClass('p-form--submit');
return Div::create($this->_input())->addClass('p-form__submit');
}

protected function _input()
Expand Down
2 changes: 1 addition & 1 deletion tests/Csrf/CsrfFormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function testRender()
$form = new CsrfForm($secret);
$html = $form->render();
$this->assertRegExp(
'/<form class="p-form" method="post"><input type="hidden" name="csrfToken" value=".*" \/><div class="p-form-field"><div class="p-form--submit"><input type="submit" value="Submit" \/><\/div><\/div><\/form>/',
'/<form class="p-form" method="post"><input type="hidden" name="csrfToken" value=".*" \/><div class="p-form__field"><div class="p-form__submit"><input type="submit" value="Submit" \/><\/div><\/div><\/form>/',
$html
);
}
Expand Down
10 changes: 8 additions & 2 deletions tests/Decorators/FormSubmitDecoratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ class FormSubmitDecoratorTest extends TestCase
public function testSubmitDecorator()
{
$dec = new FormSubmitDecorator();
$this->assertEquals('<div class="p-form-field"><div class="p-form--submit"><input type="submit" value="Submit" /></div></div>', $dec->render());
$this->assertEquals(
'<div class="p-form__field"><div class="p-form__submit"><input type="submit" value="Submit" /></div></div>',
$dec->render()
);
$dec->setValue('Press Here');
$this->assertEquals('<div class="p-form-field"><div class="p-form--submit"><input type="submit" value="Press Here" /></div></div>', $dec->render());
$this->assertEquals(
'<div class="p-form__field"><div class="p-form__submit"><input type="submit" value="Press Here" /></div></div>',
$dec->render()
);
}
}
10 changes: 5 additions & 5 deletions tests/FormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,28 +83,28 @@ public function testRender()
$form = new TestForm();
$form->getDecorator()->setId('vbn');
$this->assertRegExp(
'~<form class="p-form" id="vbn" action="/test" method="post"><div class="p-form-field"><div class="p-form--label"><label for="text-(...)">Text</label></div><div class="p-form--input"><input type="text" id="text-\1" name="text" placeholder="Text" /></div></div><div class="p-form-field"><div class="p-form--label"><label for="number-(...)">Number</label></div><div class="p-form--input"><input type="number" id="number-\2" name="number" placeholder="Number" /></div></div><div class="p-form-field"><div class="p-form--label"><label for="read-only-(...)">Read Only</label></div><div class="p-form--input"><span id="read-only-\3"></span></div></div><div class="p-form-field"><div class="p-form--submit"><input type="submit" value="Submit" /></div></div></form>~',
'~<form class="p-form" id="vbn" action="/test" method="post"><div class="p-form__field"><div class="p-form__label"><label for="text-(...)">Text</label></div><div class="p-form__input"><input type="text" id="text-\1" name="text" placeholder="Text" /></div></div><div class="p-form__field"><div class="p-form__label"><label for="number-(...)">Number</label></div><div class="p-form__input"><input type="number" id="number-\2" name="number" placeholder="Number" /></div></div><div class="p-form__field"><div class="p-form__label"><label for="read-only-(...)">Read Only</label></div><div class="p-form__input"><span id="read-only-\3"></span></div></div><div class="p-form__field"><div class="p-form__submit"><input type="submit" value="Submit" /></div></div></form>~',
$form->render()
);

$form->number = 4;
$form->text = 'abc';
$this->assertRegExp(
'~<form class="p-form" id="vbn" action="/test" method="post"><div class="p-form-field"><div class="p-form--label"><label for="text-(...)">Text</label></div><div class="p-form--input"><input type="text" id="text-\1" name="text" placeholder="Text" value="abc" /></div></div><div class="p-form-field"><div class="p-form--label"><label for="number-(...)">Number</label></div><div class="p-form--input"><input type="number" id="number-\2" name="number" placeholder="Number" value="4" /></div></div><div class="p-form-field"><div class="p-form--label"><label for="read-only-(...)">Read Only</label></div><div class="p-form--input"><span id="read-only-\3"></span></div></div><div class="p-form-field"><div class="p-form--submit"><input type="submit" value="Submit" /></div></div></form>~',
'~<form class="p-form" id="vbn" action="/test" method="post"><div class="p-form__field"><div class="p-form__label"><label for="text-(...)">Text</label></div><div class="p-form__input"><input type="text" id="text-\1" name="text" placeholder="Text" value="abc" /></div></div><div class="p-form__field"><div class="p-form__label"><label for="number-(...)">Number</label></div><div class="p-form__input"><input type="number" id="number-\2" name="number" placeholder="Number" value="4" /></div></div><div class="p-form__field"><div class="p-form__label"><label for="read-only-(...)">Read Only</label></div><div class="p-form__input"><span id="read-only-\3"></span></div></div><div class="p-form__field"><div class="p-form__submit"><input type="submit" value="Submit" /></div></div></form>~',
$form->render()
);

$form->text->getDecorator()->getInput()->setId('myInput');
$form->getDecorator()->setId('abc')->setAttribute('data-test', true);
$this->assertRegExp(
'~<form class="p-form" id="abc" action="/test" method="post" data-test><div class="p-form-field"><div class="p-form--label"><label for="myInput">Text</label></div><div class="p-form--input"><input type="text" id="myInput" name="text" placeholder="Text" value="abc" /></div></div><div class="p-form-field"><div class="p-form--label"><label for="number-(...)">Number</label></div><div class="p-form--input"><input type="number" id="number-\1" name="number" placeholder="Number" value="4" /></div></div><div class="p-form-field"><div class="p-form--label"><label for="read-only-(...)">Read Only</label></div><div class="p-form--input"><span id="read-only-\2"></span></div></div><div class="p-form-field"><div class="p-form--submit"><input type="submit" value="Submit" /></div></div></form>~',
'~<form class="p-form" id="abc" action="/test" method="post" data-test><div class="p-form__field"><div class="p-form__label"><label for="myInput">Text</label></div><div class="p-form__input"><input type="text" id="myInput" name="text" placeholder="Text" value="abc" /></div></div><div class="p-form__field"><div class="p-form__label"><label for="number-(...)">Number</label></div><div class="p-form__input"><input type="number" id="number-\1" name="number" placeholder="Number" value="4" /></div></div><div class="p-form__field"><div class="p-form__label"><label for="read-only-(...)">Read Only</label></div><div class="p-form__input"><span id="read-only-\2"></span></div></div><div class="p-form__field"><div class="p-form__submit"><input type="submit" value="Submit" /></div></div></form>~',
$form->render()
);
$this->assertTrue($form->getDecorator()->hasAttribute('data-test'));

$form->getDecorator()->setId('abc')->removeAttribute('data-test');
$this->assertRegExp(
'~<form class="p-form" id="abc" action="/test" method="post"><div class="p-form-field"><div class="p-form--label"><label for="myInput">Text</label></div><div class="p-form--input"><input type="text" id="myInput" name="text" placeholder="Text" value="abc" /></div></div><div class="p-form-field"><div class="p-form--label"><label for="number-(...)">Number</label></div><div class="p-form--input"><input type="number" id="number-\1" name="number" placeholder="Number" value="4" /></div></div><div class="p-form-field"><div class="p-form--label"><label for="read-only-(...)">Read Only</label></div><div class="p-form--input"><span id="read-only-\2"></span></div></div><div class="p-form-field"><div class="p-form--submit"><input type="submit" value="Submit" /></div></div></form>~',
'~<form class="p-form" id="abc" action="/test" method="post"><div class="p-form__field"><div class="p-form__label"><label for="myInput">Text</label></div><div class="p-form__input"><input type="text" id="myInput" name="text" placeholder="Text" value="abc" /></div></div><div class="p-form__field"><div class="p-form__label"><label for="number-(...)">Number</label></div><div class="p-form__input"><input type="number" id="number-\1" name="number" placeholder="Number" value="4" /></div></div><div class="p-form__field"><div class="p-form__label"><label for="read-only-(...)">Read Only</label></div><div class="p-form__input"><span id="read-only-\2"></span></div></div><div class="p-form__field"><div class="p-form__submit"><input type="submit" value="Submit" /></div></div></form>~',
$form->render()
);
$this->assertfalse($form->getDecorator()->hasAttribute('data-test'));
Expand All @@ -118,7 +118,7 @@ public function testRender()
$decorator->getInput()->setId('myNum');
$form->validate();
$this->assertEquals(
'<form class="p-form" id="abc" action="/test" method="post"><div class="p-form-field"><div class="p-form--label"><label for="myInput">Text</label></div><div class="p-form--input"><input type="text" id="myInput" name="text" placeholder="Text" value="abc" /></div></div><div class="p-form-field p-form-field--error"><div class="p-form--label"><label for="myNum">Number</label></div><div class="p-form--errors"><ul><li>must be a number</li></ul></div><div class="p-form--input"><input type="number" id="myNum" name="number" placeholder="Number" value="abc" /></div></div><div class="p-form-field"><div class="p-form--label"><label for="ro">Read Only</label></div><div class="p-form--input"><span id="ro"></span></div></div><div class="p-form-field"><div class="p-form--submit"><input type="submit" value="Submit" /></div></div></form>',
'<form class="p-form" id="abc" action="/test" method="post"><div class="p-form__field"><div class="p-form__label"><label for="myInput">Text</label></div><div class="p-form__input"><input type="text" id="myInput" name="text" placeholder="Text" value="abc" /></div></div><div class="p-form__field p-form__field--error"><div class="p-form__label"><label for="myNum">Number</label></div><div class="p-form__errors"><ul><li>must be a number</li></ul></div><div class="p-form__input"><input type="number" id="myNum" name="number" placeholder="Number" value="abc" /></div></div><div class="p-form__field"><div class="p-form__label"><label for="ro">Read Only</label></div><div class="p-form__input"><span id="ro"></span></div></div><div class="p-form__field"><div class="p-form__submit"><input type="submit" value="Submit" /></div></div></form>',
$form->render()
);
}
Expand Down

0 comments on commit 3a6861b

Please sign in to comment.