DEV Community

oskar calvo
oskar calvo

Posted on

Añadir programáticamente un campo de tipo cshs a un formulario.

El módulo Client-side Hierarchical Select de Drupal permite elegir un elemento de un select cuando tenemos una jerarquía en árbol con múltiples valores.

(Fuente de la foto: https://www.drupal.org/project/cshs)

Añadir este widget a las entidades de contenido es sencillo, simplemente en la pestaña de "Administrar la visualización del formulario" podemos elegir que widget queremos usar y si tenemos activado el módulo Cshs lo veremos para los campos de taxonomías.

El problema es que los formularios creados a medida para añadir funcionalidades, o los formularios de entidades de configuración no tienen la opción de "Administrar la visualización del formulario".

En este caso muestro como usando el módulo Hux añado un hook_form_alter para añadir un campo adicional a la entidad que trae el módulo simplenews para poder categorizar los tipos de boletines que se crean usando un vocabulario ya definido en el proyecto.


  /**
   * Implement hook_form_alter().
   */
  #[Alter('form')]
  public function addThematicFieldToNewsletters(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) : void {

        if (in_array($form_id, ['simplenews_newsletter_edit_form', 'simplenews_newsletter_add_form'], TRUE)) {
          $form['container_thematics'] = [
            '#type' => 'fieldset',
            '#title' => $this->t('Thematics'),
          ];

          $form['container_thematics']['thematics'] = [
            '#type' => 'cshs',
            '#title' => $this->t('Select the thematic'),
            '#options' => $this->buildCshsOptions('thematics'),
            '#weight' => 100,
                /** @var \Drupal\simplenews\Entity\Newsletter $newsletter */
            '#default_value' => $form_state->getFormObject()->getEntity()->getThirdPartySetting('gobcan_newsletters', 'thematics', NULL),

          ];

            // Añadir entity builder para procesar los third party settings
            $form['#entity_builders'][] = [$this, 'buildThematicsEntity'];
        }

  }

Enter fullscreen mode Exit fullscreen mode

Para definir correctamente el widget de formulario de Cshs tenemos que definir el campo del formulario como ´'#type' => 'cshs',´ , además el array de ´#Options´ no sirve un array de tipo clave valor, sino que tiene que tener una estructura concreta para que Cshs pueda procesarlo, por eso se ha creado el método ´buildCshsOptions()´.


    /**
     * Entity builder para las temáticas.
     */
    public function buildThematicsEntity($entity_type, \Drupal\simplenews\Entity\Newsletter $newsletter, &$form, \Drupal\Core\Form\FormStateInterface $form_state) : void {
      $thematics_value = $form_state->getValue('thematics');
      $newsletter->setThirdPartySetting($module_name, 'thematics', $thematics_value);
    }

Enter fullscreen mode Exit fullscreen mode

Esta funciión es la función necesaria para guardar los valores en la entidad como configuraciones de terceros.

  private function buildCshsOptions(string $vocabulary): array {

    $term_options = [];
    $terms = $this->entityTypeManager
      ->getStorage('taxonomy_term')
      ->loadTree($vocabulary,0,NULL,TRUE);

    foreach ($terms as $term) {
      $termId = $term->id();
      if($term->parent->target_id) {
        $term_options[$termId] = new CshsOption($term->getName(),$term->parent->target_id);
      } else {
        $term_options[$termId] = new CshsOption($term->getName());
      }
    }

        return $term_options;
  }

Enter fullscreen mode Exit fullscreen mode

En este método construimos la estructura del array que necesita Cshs para poder construir el widget correcto, usamos la clase CshsOption que trae el módulo para hacerlo.

El código es de David Mudie (dmudie) lo saqué de esta Issue en Drupal.org

Top comments (0)