Jun 15, 2014

Take two: Building a form using a route path with a wildcard

This posting is a follow-up to the one published immediately before this one. It's necessary to read that older post first in order to understand this one, which provides an alternate and simpler solution.


   - - - - -
Thanks to Darren Lee who pointed out to me another way to pass an optional parameter to a form building class derived from FormBase, I was able to implement an alternate solution that is simpler and cleaner.

This solution does not require a class variable or the constructor that assigns a value to it. Instead, the buildForm() method receives an extra optional parameter instead of using a class variable.

(1)  First, as in the previous post, it's necessary to define a route in the routing file, which is the same as before. The path contains the wildcard {oid}. DoUpdate is a new class to be defined and acts as an intermediary.

  path: /admin/config/system/optimizely/add_update/{oid}

    _content: \Drupal\optimizely\DoUpdate::buildUpdateForm
    _title: Optimizely Edit Project
    _permission: administer optimizely

(2)  The definition for class  DoUpdate simply consists of the method buildUpdateForm() specified in the route above. By using the  _content  property, the value of {oid} in the path is automatically passed as an argument to the method.

In the body of buildUpdateForm(), the first parameter in the call to  getForm() is the name of the form building class instead of an instance of that class, which is what was passed before. In addition, there is a second parameter, which is the value of the wildcard.

class DoUpdate {
  public static function buildUpdateForm($oid) {
    return \Drupal::formBuilder()->getForm(


(3) Finally, the buildForm() method of the form building class has an optional parameter $oid. When this method is called for the wildcard path defined in the routing file, the param will have a value set. Otherwise, the param defaults to NULL.

class AddUpdateForm extends FormBase {

  public function buildForm(array $form, array &$form_state, 
                            $oid = NULL) {
    // body of buildForm ...
  // ... the rest of the class definition, as before.

If the value of $oid is set, the  buildForm() method uses it to fetch the values of the existing project from the database to pre-populate the fields of the form that it builds. Otherwise, the fields are left blank.

Update: see  http://optimizely-to-drupal-8.blogspot.com/2014/12/beta-3-beta-4-routes-use-controller.html


Form API in Drupal 8

1 comment: