logo

Dodatni tipovi blokova (EBT) - Novo iskustvo rada sa Layout Builder-om❗

Dodatni tipovi blokova (EBT) – stilizovani, prilagodljivi tipovi blokova: slajdšouvi, kartice sa tabovima, kartice, akordeoni i mnogi drugi. Ugrađena podešavanja za pozadinu, DOM Box, javascript dodatke. Iskusite budućnost kreiranja rasporeda već danas.

Demo EBT moduli Preuzmite EBT module

❗Dodatni tipovi pasusa (EPT) – Novo iskustvo rada sa pasusima

Dodatni tipovi pasusa (EPT) – analogni skup modula zasnovan na pasusima.

Demo EPT moduli Preuzmite EPT module

Scroll
27/05/2025, by Ivan

U ovom članku nastavićemo da razumemo Form API u Drupalu 8 i napraviti višestepeni formular. Već smo napravili uobičajeni konfiguracioni formular za modul, višestepeni formular se pravi na sličan način koristeći $form_state za čuvanje podataka između koraka formulara.

Primere koda možete pronaći na github-u:

https://github.com/levmyshkin/drupalbook8

Za višestepeni formular potrebno je dodati klasu formulara:

/modules/custom/drupalbook/src/Form/MultiStepForm.php

<?php

/**
 * @file
 * Sadrži Drupal\drupalbook\Form\MultiStepForm.
 */

namespace Drupal\drupalbook\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class MultiStepForm extends FormBase
{

  protected $step = 1;

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames()
  {
  }

  /**
   * {@inheritdoc}
   */
  public function getFormID()
  {
    return 'multi_step_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state)
  {
    //$form = parent::buildForm($form, $form_state);

    // Dodajemo wrapper div koji će koristiti Form API za ažuriranje formulara koristeći AJAX
    $form['#prefix'] = '<div id="ajax_form_multistep_form">';
    $form['#suffix'] = '</div>';
    if ($this->step == 1) {
      $form['message-step'] = [
        '#markup' => '<div class="step">' . $this->t('Korak 1 od 2') . '</div>',
      ];
      $form['message-title'] = [
        '#markup' => '<h2>' . $this->t('Ko ste vi?') . '</h2>',
      ];
      $form['first_name'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Ime'),
        '#placeholder' => $this->t('Ime'),
        '#required' => TRUE,
      ];
      $form['last_name'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Prezime'),
        '#placeholder' => $this->t('Prezime'),
        '#required' => TRUE,
      ];

    }

    if ($this->step == 2) {
      $form['message-step'] = [
        '#markup' => '<div class="step">' . $this->t('Korak 2 od 2') . '</div>',
      ];
      $form['message-title'] = [
        '#markup' => '<h2>' . $this->t('Molimo unesite vaše kontakt podatke ispod:') . '</h2>',
      ];
      $form['phone'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Telefon'),
        '#placeholder' => $this->t('Telefon'),
        '#required' => TRUE,
      ];
      $form['email'] = [
        '#type' => 'email',
        '#title' => $this->t('Email adresa'),
        '#placeholder' => $this->t('Email adresa'),
        '#attributes' => array('class' => array('mail-first-step')),
        '#required' => TRUE,
      ];
      $form['subscribe'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Pretplatite se na newsletter'),
      ];
      $form['agree'] = [
        '#markup' => '<p class="agree">' . $this->t('Prijavom se slažete sa <a href="@terms">Uslovima korišćenja</a> i <a href="@policy">Politikom privatnosti</a>',
            array('@terms' => '/terms-and-conditions', '@policy' => '/privacy-policy')) . '</p>',
      ];
    }

    if ($this->step == 3) {
      $form['message-step'] = [
        '#markup' => '<p class="complete">' . $this->t('- Završeno -') . '</p>',
      ];
      $form['message-title'] = [
        '#markup' => '<h2>' . $this->t('Hvala vam') . '</h2>',
      ];

    }

    if ($this->step == 1) {
      $form['buttons']['forward'] = array(
        '#type' => 'submit',
        '#value' => t('Dalje'),
        '#prefix' => '<div class="step1-button">',
        '#suffix' => '</div>',
        '#ajax' => array(
          // Prosleđujemo wrapper koji smo napravili na početku formulara
          'wrapper' => 'ajax_form_multistep_form',
          // Prosleđujemo callback funkciju koju ćemo kasnije koristiti da prikažemo formular korisniku
          'callback' => '::ajax_form_multistep_form_ajax_callback',
          'event' => 'click',
        ),
      );
    }
    if ($this->step == 2) {
      $form['buttons']['forward'] = array(
        '#type' => 'submit',
        '#value' => t('Pošalji'),
        '#ajax' => array(
          // Prosleđujemo wrapper koji smo napravili na početku formulara
          'wrapper' => 'ajax_form_multistep_form',
          // Prosleđujemo callback funkciju koju ćemo kasnije koristiti da prikažemo formular korisniku
          'callback' => '::ajax_form_multistep_form_ajax_callback',
          'event' => 'click',
        ),
      );
    }

    $form['#attached']['library'][] = 'drupalbook/multistep_form';
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    return parent::validateForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    if ($this->step == 2) {
      $values = $form_state->getValues();
      $email = $values['email'];
      // Sačuvajte podatke ili pošaljite email ovde.
    }

    $this->step++;
    $form_state->setRebuild();
  }

  public function ajax_form_multistep_form_ajax_callback(array &$form, FormStateInterface $form_state) {
    return $form;
  }

}

Sledeće ćemo razjasniti šta svaka od ovih linija radi. U međuvremenu, hajde da napravimo rutu za naš formular:
/modules/custom/drupalbook/drupalbook.routing.yml:

drupalbook.multistep_form:
  path: '/multistep-form'
  defaults:
    _form: '\Drupal\drupalbook\Form\MultiStepForm'
    _title: 'Pretplatite se na newsletter'
  requirements:
    _permission: 'access content'

Ovo će kreirati formular na adresi /multistep-form:

search

Da bi se ovaj formular otvorio u modalnom prozoru, potrebno je dodati blok ili samo tekst sa specifičnom klasom use-ajax i atributom data-dialog-type="modal", sa linkom ka stranici formulara. Takođe je potrebno omogućiti sledeće biblioteke: core/drupal.dialog.ajax, core/jquery.form. Ako ovo uradite preko bloka, dobićete sledeći kod za dugme za otvaranje formulara u popup-u:modules/custom/drupalbook/src/Plugin/Block/SubscribeFormButton.php

<?php

namespace Drupal\drupalbook\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
 * Pruža dugme za pretplatu na newsletter.
 *
 * @Block(
 *   id = "drupalbook_subsribe_form_button",
 *   admin_label = @Translation("Pretplati se na newsletter"),
 * )
 */
class SubscribeFormButton extends BlockBase {
  /**
   * {@inheritdoc}
   */
  public function build() {
    $text = '<a href="/multistep-form" class="use-ajax" data-dialog-type="modal">Pretplati se</a>';

    return [
      '#markup' => $text,
      '#attached' => array(
        'library' => array(
          'core/drupal.dialog.ajax',
          'core/jquery.form',
        ),
      ),
    ];
  }

}

Formular u popup-u će izgledati ovako:

newsletter

Takođe sam povezao prilagođenu biblioteku iz fajla drupalbook.libraries.yml:

modules/custom/drupalbook/drupalbook.libraries.yml

multistep_form:
  css:
    css/multistep_form.css: {}
  js:
    scripts/multistep_form.js: {}
  dependencies:
    - core/jquery
    - core/jquery.once

Potrebno je stilizovati formular i povezati neophodne jQuery dodatke. Zbog toga je potrebno kreirati još fajlova:

modules/custom/drupalbook/css/multistep_form.css
modules/custom/drupalbook/scripts/multistep_form.js

Primere koda možete pronaći na github-u:
https://github.com/levmyshkin/drupalbook8