Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Add Form\Element labelOptions property w/ implemented use case #4677

Merged

Conversation

stefanotorresi
Copy link
Contributor

Having a labelOptions array of dedicated properties for the form labels makes custom rendering of the form a bit easier.

One use case is the possibilty to disable HTML escaping of the label text.

A common use case for this is an hyper link inside the label, which pretty much any html form with a 'privacy terms' checkbox needs.

Since Form\View\Helper\FormRow escapes the label content, the only way of doing this at the moment is using custom view templates using a wide range of form view helpers.

That denies the purpose of Form\View\Helper\Form and Form\View\Helper\FormRow.

This PR adds labelOptions property and accessors to the Form\Element class, and handles the disable_html_escape option in Form\View\Helper\FormRow.

I reckon that adding an array to the Form\Element class just to handle a view helper option may seem a bit overkill in this case, but I'm looking from a wider angle: being able to tie custom options to the form element label itself gives much more flexibility when developing custom view templates and helpers; the example above is just the simplest I had to deal with.

@EvanDotPro
Copy link
Member

Well, I'm not 100% sure on that use-case, but as far as the tests go, I'd say you should leave testSpecificOptionsSetLabelAttributes() as-is, and just add another test, instead of modifying the existing one. If you have to modify an existing test when adding functionality, that makes it look like there could be a BC break from a casual review perspective, even if that's not necessarily the case.

$label = $escapeHtmlHelper($label);
$labelAttributes = $element->getLabelAttributes();
// ElementInterface may not provide label specific methods
if (method_exists($element, 'getLabelOptions')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe put an @TODO to clean up this duck typing for 3.0 when we can break BC.

{
$element = new Element('foo');
$element->setOptions(array(
'label_options' => array('moar' => 'foo')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PhpStorm user, eh?

Indentation is messed up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm I replicated the same indentation of the previous method. I thought I had to line the array keys to the opening parenthesis above. Should it be just one level instead?

[edit] np, looking at the other methods answered the question. Not PhpStorm's fault btw :-P

@@ -118,10 +118,14 @@ public function openTag($attributesOrElement = null)
));
}

$labelAttributes = $attributesOrElement->getLabelAttributes();
// @todo ElementInterface may not provide label specific methods
if (method_exists($attributesOrElement, 'getLabelAttributes')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of a method exists; it is far preferable to provide an additional interface. This is done in several areas of the framework to provide additional behavior. This way when an element implements the behavior you can check to see if it is an instance of rather than doing an internal hash table lookup on the object itself.

IMO this makes it easier to extend the framework further as you can see even in the ModuleManager which provides interfaces for certain extension points.

So I added the interface as @mwillbanks suggested, and a trait too while
i was at it. I made the interface a bit more generic, that introduced
some redundancy with ElementInterface, but i guess the two will
eventually get merged in zf3.
@weierophinney
Copy link
Member

There's a BC problem with this, and not what you would expect: PHP 5.3.3 does not allow implementing multiple interfaces that define the same method, even if the signatures are the same. This means that setLabel() and getLabel() cannot be in the LabelAwareInterface. As such, on merge, I'm going to rename it to LabelOptionsAwareInterface and will remove those methods.

@ghost ghost assigned weierophinney Jun 28, 2013
weierophinney added a commit that referenced this pull request Jun 28, 2013
Add Form\Element labelOptions property w/ implemented use case
weierophinney added a commit that referenced this pull request Jun 28, 2013
- Removed set/getLabel from new interface
- Renamed interface to LabelOptionsAwareInterface
- Renamed trait to LabelOptionsAwareTrait
- Updated code to reference renamed interface
weierophinney added a commit that referenced this pull request Jun 28, 2013
@weierophinney weierophinney merged commit 737ff5d into zendframework:develop Jun 28, 2013
@stefanotorresi stefanotorresi deleted the form-label-options branch June 28, 2013 17:11
stefanotorresi pushed a commit to stefanotorresi/zf2-documentation that referenced this pull request Sep 11, 2013
* Add FormRow docs
* Some corrections here and there
* Add docs for zendframework/zendframework#4677
stefanotorresi pushed a commit to stefanotorresi/zf2-documentation that referenced this pull request Sep 11, 2013
* Add FormRow docs
* Some corrections here and there
* Add docs for zendframework/zendframework#4677 and zendframework/zendframework#5101
This was referenced Oct 4, 2013
@chludwig
Copy link

Thanks for the update, but I am missing this option for button elements. Buttons are rendered in a different way.

See line 97 in FormButton.php

return $openTag . $escape($buttonContent) . $this->closeTag();

@franz-deleon
Copy link
Contributor

i have a problem with this change and it breaks a lot of my forms and i assume most people will too.
I cannot successfully turn this switch off/on (disable_html_escape)

//inside form
    public function init()
    {
        $this->setAttribute('method', 'post');
        $this->setLabelOptions(array(
            'disable_html_escape' => true,
        ));

        $this->add(array(
            'type' => 'Text',
            'name' => 'displayname',
            'options' => array(
                'label' => 'Display Name:<span>*</span>',
            ),
            'attributes' => array(
                'size' => 70,
                'id' => 'name',
            ),
            'label_options' => array(
                'disable_html_escape' => true,
            ),
        ));
}

@stefanotorresi
Copy link
Contributor Author

label_options is still an element option, so the correct spec is this:

$form->add(array(
    'type' => 'Text',
    'name' => 'displayname',
    'options' => array(
        'label' => 'Display Name:<span>*</span>',
        'label_options' => array(
            'disable_html_escape' => true,
        ),
    ),
    'attributes' => array(
        'size' => 70,
        'id' => 'name',
    ),
));

Now that I notice it, Form\Factory::configureElement() may use a little tweak to allow the notation you tried, which is certainly more intuitive.

By the way, if your existent forms were affected or not by the change depends on what view helpers you are using, because rather than this PR, the breaking change you may refer to has been introduced in #5101, involving the FormLabel view helper and not the Form and FormRow ones, which behaviour has not been changed (they escaped the labels already, this PR only added the opt-out option).

@franz-deleon
Copy link
Contributor

ahh i see now that is how to implement this. i have to change a bunch of forms when this change occurs

@stefanotorresi
Copy link
Contributor Author

No. ;)
´FormRow´, ´FormButton´ and ´FormLabel´ are the only helpers involved with the element label. ´FormText´ renders just the input. That can let me assume that you are also using ´FormLabel´ to render the label, which is indeed the one with the breaking change.

@franz-deleon
Copy link
Contributor

yes i stand corrected thats why i deleted that comment :D . and yes indeed i am using formLabel for rendering,

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants