Skip to content

Commit

Permalink
Merge pull request #367 from ndm2/floating-label-placeholders
Browse files Browse the repository at this point in the history
4.x - Automatically generate placeholders for floating labels.
  • Loading branch information
dereuromark authored Apr 4, 2022
2 parents 81910e1 + ca92f1a commit 6924ce4
Show file tree
Hide file tree
Showing 5 changed files with 408 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/View/Helper/FormHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use Cake\Core\Configure\Engine\PhpConfig;
use Cake\Utility\Hash;
use Cake\Utility\Inflector;
use Cake\View\Helper\FormHelper as Helper;
use Cake\View\View;
use InvalidArgumentException;
Expand Down Expand Up @@ -559,6 +560,7 @@ public function control(string $fieldName, array $options = []): string
$options = $this->_containerOptions($fieldName, $options);
$options = $this->_feedbackStyleOptions($fieldName, $options);
$options = $this->_ariaOptions($fieldName, $options);
$options = $this->_placeholderOptions($fieldName, $options);
$options = $this->_helpOptions($fieldName, $options);
$options = $this->_tooltipOptions($fieldName, $options);

Expand Down Expand Up @@ -1039,6 +1041,40 @@ protected function _ariaOptions(string $fieldName, array $options): array
return $options;
}

/**
* Modify options for placeholders.
*
* @param string $fieldName Field name.
* @param array $options Options. See `$options` argument of `control()` method.
* @return array
*/
protected function _placeholderOptions(string $fieldName, array $options): array
{
if (
!isset($options['placeholder']) &&
isset($options['label']['floating']) &&
$options['label']['floating'] &&
in_array($options['type'], ['text', 'textarea'], true)
) {
if (isset($options['label']['text'])) {
$options['placeholder'] = $options['label']['text'];
} else {
$text = $fieldName;
if (strpos($text, '.') !== false) {
$fieldElements = explode('.', $text);
$text = array_pop($fieldElements);
}
if (substr($text, -3) === '_id') {
$text = substr($text, 0, -3);
}

$options['placeholder'] = __(Inflector::humanize(Inflector::underscore($text)));
}
}

return $options;
}

/**
* Modify options for control's help.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,90 @@ public function testDefaultAlignTextControlWithFloatingLabel()
'floating' => true,
],
]);
$expected = [
'div' => ['class' => 'mb-3 form-floating form-group text'],
'input' => [
'type' => 'text',
'name' => 'title',
'id' => 'title',
'placeholder' => 'Title',
'class' => 'form-control',
],
['label' => ['for' => 'title']],
'Title',
'/label',
'/div',
];
$this->assertHtml($expected, $result);
}

public function testDefaultAlignTextControlWithFloatingLabelAndCustomLabelText()
{
unset($this->article['required']['title']);
$this->Form->create($this->article);

$result = $this->Form->control('title', [
'label' => [
'floating' => true,
'text' => 'Custom Label',
],
]);
$expected = [
'div' => ['class' => 'mb-3 form-floating form-group text'],
'input' => [
'type' => 'text',
'name' => 'title',
'id' => 'title',
'placeholder' => 'Custom Label',
'class' => 'form-control',
],
['label' => ['for' => 'title']],
'Custom Label',
'/label',
'/div',
];
$this->assertHtml($expected, $result);
}

public function testDefaultAlignTextControlWithFloatingLabelAndCustomPlaceholder()
{
unset($this->article['required']['title']);
$this->Form->create($this->article);

$result = $this->Form->control('title', [
'label' => [
'floating' => true,
],
'placeholder' => 'Custom Placeholder',
]);
$expected = [
'div' => ['class' => 'mb-3 form-floating form-group text'],
'input' => [
'type' => 'text',
'name' => 'title',
'id' => 'title',
'placeholder' => 'Custom Placeholder',
'class' => 'form-control',
],
['label' => ['for' => 'title']],
'Title',
'/label',
'/div',
];
$this->assertHtml($expected, $result);
}

public function testDefaultAlignTextControlWithFloatingLabelAndDisabledPlaceholder()
{
unset($this->article['required']['title']);
$this->Form->create($this->article);

$result = $this->Form->control('title', [
'label' => [
'floating' => true,
],
'placeholder' => false,
]);
$expected = [
'div' => ['class' => 'mb-3 form-floating form-group text'],
'input' => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,117 @@ public function testHorizontalAlignTextControlWithFloatingLabel()
'floating' => true,
],
]);
$expected = [
'div' => ['class' => 'mb-3 form-group row text'],
['div' => ['class' => 'offset-sm-5 col-sm-7 form-floating']],
'input' => [
'type' => 'text',
'name' => 'title',
'id' => 'title',
'placeholder' => 'Title',
'class' => 'form-control',
],
'label' => ['class' => 'ps-4', 'for' => 'title'],
'Title',
'/label',
'/div',
'/div',
];
$this->assertHtml($expected, $result);
}

public function testHorizontalAlignTextControlWithFloatingLabelAndCustomLabelText()
{
unset($this->article['required']['title']);
$this->Form->create($this->article, [
'align' => [
'sm' => [
FormHelper::GRID_COLUMN_ONE => 5,
FormHelper::GRID_COLUMN_TWO => 7,
],
],
]);

$result = $this->Form->control('title', [
'label' => [
'floating' => true,
'text' => 'Custom Label',
],
]);
$expected = [
'div' => ['class' => 'mb-3 form-group row text'],
['div' => ['class' => 'offset-sm-5 col-sm-7 form-floating']],
'input' => [
'type' => 'text',
'name' => 'title',
'id' => 'title',
'placeholder' => 'Custom Label',
'class' => 'form-control',
],
'label' => ['class' => 'ps-4', 'for' => 'title'],
'Custom Label',
'/label',
'/div',
'/div',
];
$this->assertHtml($expected, $result);
}

public function testHorizontalAlignTextControlWithFloatingLabelAndCustomPlaceholder()
{
unset($this->article['required']['title']);
$this->Form->create($this->article, [
'align' => [
'sm' => [
FormHelper::GRID_COLUMN_ONE => 5,
FormHelper::GRID_COLUMN_TWO => 7,
],
],
]);

$result = $this->Form->control('title', [
'label' => [
'floating' => true,
],
'placeholder' => 'Custom Placeholder',
]);
$expected = [
'div' => ['class' => 'mb-3 form-group row text'],
['div' => ['class' => 'offset-sm-5 col-sm-7 form-floating']],
'input' => [
'type' => 'text',
'name' => 'title',
'id' => 'title',
'placeholder' => 'Custom Placeholder',
'class' => 'form-control',
],
'label' => ['class' => 'ps-4', 'for' => 'title'],
'Title',
'/label',
'/div',
'/div',
];
$this->assertHtml($expected, $result);
}

public function testHorizontalAlignTextControlWithFloatingLabelAndDisabledPlaceholder()
{
unset($this->article['required']['title']);
$this->Form->create($this->article, [
'align' => [
'sm' => [
FormHelper::GRID_COLUMN_ONE => 5,
FormHelper::GRID_COLUMN_TWO => 7,
],
],
]);

$result = $this->Form->control('title', [
'label' => [
'floating' => true,
],
'placeholder' => false,
]);
$expected = [
'div' => ['class' => 'mb-3 form-group row text'],
['div' => ['class' => 'offset-sm-5 col-sm-7 form-floating']],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,102 @@ public function testInlineAlignTextControlWithFloatingLabel()
'floating' => true,
],
]);
$expected = [
['div' => ['class' => 'col-auto']],
'div' => ['class' => 'form-floating form-group text'],
'input' => [
'type' => 'text',
'name' => 'title',
'id' => 'title',
'placeholder' => 'Title',
'class' => 'form-control',
],
'label' => ['for' => 'title'],
'Title',
'/label',
'/div',
'/div',
];
$this->assertHtml($expected, $result);
}

public function testInlineAlignTextControlWithFloatingLabelAndCustomLabelText()
{
unset($this->article['required']['title']);
$this->Form->create($this->article, [
'align' => 'inline',
]);

$result = $this->Form->control('title', [
'label' => [
'floating' => true,
'text' => 'Custom Label',
],
]);
$expected = [
['div' => ['class' => 'col-auto']],
'div' => ['class' => 'form-floating form-group text'],
'input' => [
'type' => 'text',
'name' => 'title',
'id' => 'title',
'placeholder' => 'Custom Label',
'class' => 'form-control',
],
'label' => ['for' => 'title'],
'Custom Label',
'/label',
'/div',
'/div',
];
$this->assertHtml($expected, $result);
}

public function testInlineAlignTextControlWithFloatingLabelAndCustomPlaceholder()
{
unset($this->article['required']['title']);
$this->Form->create($this->article, [
'align' => 'inline',
]);

$result = $this->Form->control('title', [
'label' => [
'floating' => true,
],
'placeholder' => 'Custom Placeholder',
]);
$expected = [
['div' => ['class' => 'col-auto']],
'div' => ['class' => 'form-floating form-group text'],
'input' => [
'type' => 'text',
'name' => 'title',
'id' => 'title',
'placeholder' => 'Custom Placeholder',
'class' => 'form-control',
],
'label' => ['for' => 'title'],
'Title',
'/label',
'/div',
'/div',
];
$this->assertHtml($expected, $result);
}

public function testInlineAlignTextControlWithFloatingLabelAndDisabledPlaceholder()
{
unset($this->article['required']['title']);
$this->Form->create($this->article, [
'align' => 'inline',
]);

$result = $this->Form->control('title', [
'label' => [
'floating' => true,
],
'placeholder' => false,
]);
$expected = [
['div' => ['class' => 'col-auto']],
'div' => ['class' => 'form-floating form-group text'],
Expand Down
Loading

0 comments on commit 6924ce4

Please sign in to comment.