Skip to content
Grav 2.0 is officially stable. Read the announcement →
Plugins

Form plugin : how to dynamically initialize form value depending on header data from a plugin

form plugins

Started by randoum 6 years ago · 4 replies · 962 views
6 years ago

Hi there,

I am trying to initialize form field's default values from a plugin based on data from the page header. For this I try to hock onFormInitialized but I cannot access page from here.

PHP
public function onFormInitialized(Event $event)
{
  $form = $event['form'];

  if( $form->getName() != 'my-form' ) {
    return;
  }

  $page = $this->grav['page'];
  $my_data = $page->header()->my_data;
  if( $my_data ) {
    $form->setData('my_data', $my_data);
  }
}

This is not working (Grav is rendering not_found.md)

Any suggestion on how to achieve this ?

6 years ago

@randoum, Played a bit with your code...

Having a page with the following header:

YAML
---
title: Contact
variables:
  name: My default value
form:
    name: contact

    fields:
        name:
          label: Name
          placeholder: Enter your name
          autocomplete: on
          type: text
          validate:
            required: true
     ... etc.

You could try the following in your plugin:

PHP
public function onPageInitialized(Event $event)
{
    $this->page = $event['page'];
}

public function onFormInitialized(Event $event)
{
    $form = $event['form'];
    if (isset($this->page) && $form->name === 'contact') {
        $form->setData('name.default', $this->page->header()->variables['name']);
    }
}

This will yield the following form:
image|469x67

Another possible solution is calling a static method of a plugin to get default values:

Form definition in Page

YAML
form:
    name: contact

    fields:
        name:
          label: Name
          placeholder: Enter your name
          autocomplete: on
          data-default@: ['\Grav\Plugin\MyPluginClass::getDefault', 'name']
          type: text
          validate:
            required: true

Plugin:

PHP
public function onPageInitialized($event) {
    self::$page = $event['page'];
}

public static function getDefault(string $field) {
    if (isset(self::$page)) {
        return self::$page->header()->variables[$field] ?? '';
    }
}
last edited 03/14/20 by pamtbaau
6 years ago

Hi,

Yes both work, I would not use the second one though cause static functions are meant to be static.

I also found another alternative, which I am not very satisfied with, but it works :

PHP
public function onTwigInitialized(Event $e)
{
  $this->grav['twig']->twig()->addFunction(
    new \Twig_SimpleFunction('set_form_default_values', [$this, 'setFormDefaultValues'])
  );
}

public function setFormDefaultValues($form)
{
  $form->setData(...);
}

In twig template:

TWIG
{{ set_form_default_values(form) }}
6 years ago

@randoum

I would not use the second one though cause static functions are meant to be static.

For my understanding, would you mind elaborating?

As an alternative:

PHP
public static function getDefault(string $field) {
    $grav = Grav::instance();

    $pages = $grav['pages'];
    $page = $pages->find('route/of/page');

    return $page ? $page->header()->variables['name'] : '';
}
last edited 03/14/20 by pamtbaau
6 years ago

There is a very elegant Grav-way of initialising form fields with data in frontmatter by using the Form Plugin method setAllData().

It's a well kept secret. On the other hand, the how-to is in this forum, see /forum/forms-blueprints/twig-in-form-yaml-dynamic-input-values-t5211

It took me over two years before I found that post last week. I will be dropping the plugin I created which resembles the answers in this thread.

Suggested topics

Topic Participants Replies Views Activity
Plugins · by Rene, 1 week ago
2 78 1 week ago
Plugins · by Xavier, 4 weeks ago
2 83 4 weeks ago
Plugins · by Luka Prinčič, 7 years ago
3 1210 1 month ago
Plugins · by Sebastian van de Meer, 1 month ago
1 77 1 month ago
Plugins · by PIERROT Alain, 2 months ago
3 102 2 months ago