Skip to content

Commit

Permalink
Merge pull request #104 from Icinga/PrefixSubmitButtonTrait
Browse files Browse the repository at this point in the history
CompatForm: Insert duplicate submit button when more than one is present
  • Loading branch information
nilmerg authored Feb 23, 2023
2 parents 705a51b + 811318c commit e0b4e25
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 1 deletion.
16 changes: 16 additions & 0 deletions asset/css/primary-submit-btn-duplicate.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
Automatically set CSS class for duplicated submit buttons
used for implicit form submission that should be invisible
and not take up any space. `display: none` is not an option,
because at least Safari will then ignore the element completely
when submitting a form.
*/
.primary-submit-btn-duplicate {
border: 0;
height: 0;
margin: 0;
padding: 0;
visibility: hidden;
width: 0;
position: absolute;
}
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
},
"autoload-dev": {
"psr-4": {
"ipl\\Tests\\Web\\": "tests"
"ipl\\Tests\\Web\\": "tests",
"ipl\\Tests\\Html\\": "vendor/ipl/html/tests"
}
},
"require": {
Expand Down
41 changes: 41 additions & 0 deletions src/Compat/CompatForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

namespace ipl\Web\Compat;

use ipl\Html\Contract\FormSubmitElement;
use ipl\Html\Form;
use ipl\Html\FormElement\SubmitElement;
use ipl\Html\HtmlDocument;
use ipl\Html\HtmlString;
use ipl\I18n\Translation;
use ipl\Web\FormDecorator\IcingaFormDecorator;

Expand All @@ -12,6 +16,27 @@ class CompatForm extends Form

protected $defaultAttributes = ['class' => 'icinga-form icinga-controls'];

/**
* Render the content of the element to HTML
*
* A duplicate of the primary submit button is being prepended if there is more than one present
*
* @return string
*/
public function renderContent(): string
{
if (count($this->submitElements) > 1) {
return (new HtmlDocument())
->setHtmlContent(
$this->duplicateSubmitButton($this->submitButton),
new HtmlString(parent::renderContent())
)
->render();
}

return parent::renderContent();
}

public function hasDefaultElementDecorator()
{
if (parent::hasDefaultElementDecorator()) {
Expand All @@ -22,4 +47,20 @@ public function hasDefaultElementDecorator()

return true;
}

/**
* Return a duplicate of the given submit button with the `class` attribute fixed to `primary-submit-btn-duplicate`
*
* @param FormSubmitElement $originalSubmitButton
*
* @return SubmitElement
*/
public function duplicateSubmitButton(FormSubmitElement $originalSubmitButton): SubmitElement
{
$attributes = (clone $originalSubmitButton->getAttributes())
->set('class', 'primary-submit-btn-duplicate');
$attributes->remove('id');

return new SubmitElement($originalSubmitButton->getName(), $attributes);
}
}
97 changes: 97 additions & 0 deletions tests/Compat/CompatFormTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

namespace ipl\Tests\Web\Compat;

use ipl\Html\FormElement\SubmitElement;
use ipl\Tests\Html\TestCase;
use ipl\Web\Compat\CompatForm;

class CompatFormTest extends TestCase
{
/** @var CompatForm */
private $form;

protected function setUp(): void
{
$this->form = new CompatForm();
}

public function testDuplicateSubmitButtonApplied(): void
{
$this->form->addElement('submit', 'submitCreate');
$this->form->addElement('submit', 'submitDelete');

$expected = <<<'HTML'
<form class="icinga-form icinga-controls" method="POST">
<input class="primary-submit-btn-duplicate" name="submitCreate" type="submit" value="submitCreate"/>
<div class="control-group form-controls">
<input class="btn-primary" name="submitCreate" type="submit" value="submitCreate"/>
</div>
<div class="control-group form-controls">
<input class="btn-primary" name="submitDelete" type="submit" value="submitDelete"/>
</div>
</form>
HTML;

$this->assertHtml($expected, $this->form);
}

public function testDuplicateSubmitButtonOmitted(): void
{
$this->form->addElement('submit', 'submitCreate');

$expected = <<<'HTML'
<form class="icinga-form icinga-controls" method="POST">
<div class="control-group form-controls">
<input class="btn-primary" name="submitCreate" type="submit" value="submitCreate"/>
</div>
</form>
HTML;

$this->assertHtml($expected, $this->form);
}

public function testDuplicateSubmitButtonAddedOnlyOnce(): void
{
$this->form->addElement('submit', 'submitCreate', ['id' => 'submit_id']);
$this->form->addElement('submit', 'submitDelete');

$expected = <<<'HTML'
<form class="icinga-form icinga-controls" method="POST">
<input class="primary-submit-btn-duplicate" name="submitCreate" type="submit" value="submitCreate"/>
<div class="control-group form-controls">
<input id="submit_id" class="btn-primary" name="submitCreate" type="submit" value="submitCreate"/>
</div>
<div class="control-group form-controls">
<input class="btn-primary" name="submitDelete" type="submit" value="submitDelete"/>
</div>
</form>
HTML;

// Call render twice to ensure that the submit button is only prepended once.
$this->form->render();
$this->assertHtml($expected, $this->form);
}

public function testDuplicateSubmitButtonRespectsOriginalAttributes(): void
{
$submitButton = new SubmitElement('test_submit', [
'class' => 'autosubmit',
'formnovalidate' => true
]);

$prefixButton = $this->form->duplicateSubmitButton($submitButton);

// Name should stay the same
$this->assertSame($submitButton->getName(), 'test_submit');
$this->assertSame($prefixButton->getName(), 'test_submit');

// Added attributes should stay the same
$this->assertSame($submitButton->getAttributes()->get('formnovalidate')->getValue(), true);
$this->assertSame($prefixButton->getAttributes()->get('formnovalidate')->getValue(), true);

// Class attribute should change to `primary-submit-btn-duplicate`
$this->assertSame($submitButton->getAttributes()->get('class')->getValue(), 'autosubmit');
$this->assertSame($prefixButton->getAttributes()->get('class')->getValue(), 'primary-submit-btn-duplicate');
}
}

0 comments on commit e0b4e25

Please sign in to comment.