Jump to content

Formbuilder: allow html in label


Shoekrates
 Share

Recommended Posts

Hi,

I want to add a checkbox to my contact form to have users confirm that they have read the privacy policy before sending the form.
In the label of the Checkbox I want to add a link to the privacy statement page. But HTML isn't rendered, it apears as text output in the label.

How can I allow html in formbuilder checkbox labels?

Thanks for a hint.

Link to comment
Share on other sites

My thought is that you could use a hook  to add the html into the rendering of the Inputfield, or maybe you could add a Markup field in FormBuilder so you can place this link, right bellow the checkbox. 

Link to comment
Share on other sites

  • 2 months later...

@Klenkes To accomplish this, you need to replace line 94 in InputfieldCheckbox.module

"<span class='pw-no-select'>" . $this->entityEncode($label) . "</span></label>";

with this:

"<span class='pw-no-select'>" . $label . "</span></label>";

but it isn't a good idea to modify core parts.

@ryan Is it possible that you remove the entityEncode from InputfieldSelect in the core, so we can use hyperlinks, classes,  etc. in the label, or are there any security concerns? What Klenkes describes is a common need here in Germany. The other solution using InputfieldMarkup isn't as good as this solution. 

However I think one could replace the render function of the InputfieldCheckbox.module with a hook, but it would be nicer to have this feature in the core.

What do you think?

Link to comment
Share on other sites

I tried to replace the InputfieldCheckbox render function with a hook in my `_init.php`but it did not work. I get the error in the screenshot below.

Here is my hook function:

$this->addHookAfter('InputfieldCheckbox::render', function ($event) { // outside a class
//    $page = $event->object;
//    if ($page->template == 'admin') return;
    // tell ProcessWire we are replacing the method we've hooked
    $event->replace = true;

    $label = '';
    $user = wire('user');
    if ($user->language) $label = Inputfield::getSetting("checkboxLabel$user->language");
    if (!$label) $label = Inputfield::getSetting("checkboxLabel");
    if (!$label && $this->checkedValueIsLabel) $label = $this->checkedValue;
    if (!$label) $label = Inputfield::getSetting('label2');

    $this->set('skipLabel', $this->description || $label ? Inputfield::skipLabelFor : Inputfield::skipLabelHeader);
    if (!$label) $label = $this->label;

    // TBA: if($this->uncheckedValue) return $this->renderRadio();

    $attrs = Inputfield::getAttributes();
    $attrs['value'] = $this->checkedValue;

    $out =
        "<label><input type='checkbox' " . Inputfield::getAttributesString($attrs) . " />" .
        "<span class='pw-no-select'>" . $label . "</span></label>";

    $event->return = $out;
});

 

error.png

Link to comment
Share on other sites

  • 1 month later...

Well, had to do this now for including a privacy policy link in a formbuilder label 🙂

$wire->addHookAfter("InputfieldCheckbox::render",function($event){
    $field = $event->object;
    $output = $event->return;
    $policyUrl = $this->pages->get("name=privacy-policy")->url;
    if($field->name == "privacy_policy"){
        $output = str_replace("privacy policy","<a href='{$policyUrl}'>privacy policy</a>", $output);
    }
    $event->return = $output;    
});

 

  • Like 2
Link to comment
Share on other sites

  • 1 year later...
On 9/21/2018 at 12:06 AM, elabx said:

Well, had to do this now for including a privacy policy link in a formbuilder label 🙂


$wire->addHookAfter("InputfieldCheckbox::render",function($event){
    $field = $event->object;
    $output = $event->return;
    $policyUrl = $this->pages->get("name=privacy-policy")->url;
    if($field->name == "privacy_policy"){
        $output = str_replace("privacy policy","<a href='{$policyUrl}'>privacy policy</a>", $output);
    }
    $event->return = $output;    
});

 

@elabx I tried this method inside _init.php file but it didn't work.. Plus I need to link the Checkbox field label to the privacy policy page

Link to comment
Share on other sites

These things usually go in ready.php
I do all sorts of manipulation to forms from ready.php

Example with link to privacy policy:

$wire->addHookBefore('FormBuilderProcessor::renderReady', function($event) {
  $form = $event->arguments(0);
  $agree = $form->getChildByName('datenschutz');// get the field
  if(!$agree) return;

  $gdpr_page = wire('pages')->get(2096)->url;// URL to privacy policy

  $agree->appendMarkup = "<div class='ds-zusatz'><p>
    <strong>Ich stimme zu</strong>, dass meine Angaben aus dem Formular zur Beantwortung meiner Anfrage erhoben und verarbeitet werden.<br><strong>Hinweis:</strong> Sie können Ihre Einwilligung für die Zukunft jederzeit per E-Mail widerrufen. 
    <br>Detaillierte Informationen zum Umgang mit Nutzerdaten finden Sie in unserer <a href='$gdpr_page'>Datenschutzerklärung</a></p></div>";
});

 

  • Like 1
Link to comment
Share on other sites

  • 6 months later...

I combined dotnetic's suggestion with elabx's hook:

<?php

$wire->addHookAfter("InputfieldCheckbox::render",function($event){
    $field = $event->object;
    $output = $event->return;

    if($field->name == "privacy_policy_accepted"){
        $output = str_replace($field->entityEncode($field->checkboxLabel), $field->checkboxLabel, $output);
    }

    $event->return = $output;
});

?>

Basically undoes the encoding

  • Like 2
Link to comment
Share on other sites

  • 4 weeks later...

Hi,
I don't know FormBuilder yet, but if I prepare a form like this...

        $form = $modules->get("InputfieldForm");
        //...
        $field = $modules->get("InputfieldText");
        $field->label = 'Multi<br>line<br>label';
        $field->description = 'Multi<br>line<br><span style="color:red;">description</span>';
        $field->attr('id+name','testfield');
        $form->append($field);
        //...


        
... to be able to pass HTML code to labels and descriptions of form fields I can set ...

        $field->entityEncodeLabel = Inputfield::textFormatMarkdown;
        $field->entityEncodeText = Inputfield::textFormatMarkdown;
        $field->textFormat = Inputfield::textFormatMarkdown;


        
(ProcessWire 3.0.165, don't know whether it also applies for earlier versions...)

This can probably be used in the hook mentioned before, too.

Unfortunately a <p> tag is rendered around such a label, but I add to my CSS ...

        label p { display: inline-block; margin: 0; padding: 0; }


... and then it's ok.

Link to comment
Share on other sites

Sorry, too fast... My statement only works for labels and description, not for options, because InputfieldRadios for exmaple always sets $label = $this->entityEncode($label, Inputfield::textFormatBasic); - ignoring the field's textFormat setting ... 😞
So for options the above mentioned hook hack seems to be the way...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...