3

i have form build in standard like:

public function getFormId() { }
public function buildForm(array $form, FormStateInterface $form_state) { }
public function validateForm(array &$form, FormStateInterface $form_state) { }
public function submitForm(array &$form, FormStateInterface $form_state) { }

in my build form it return $form array with button add and remove.

if i press add, i would like to add new textfield above the add button (or anywhere else)

and next to the new text field i like to have a minus button ( - ) to remove the text field.

how do i achieve this in drupal 8 with ajax? how do i position the newly added textfield? how do i generate the field id ($form['composition']['DynamicallyAddedAndRemove'])?

i know how to build ajax callback but im not sure how to add new field and/or remove it dynamically through ajax

this is what i did and it didn't work, any idea why

class MyForm extends FormBase {
  /**
   * Class constructor.
   */
  public function __construct($coreService) { }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) { }

  /**
   * {@inheritdoc}
   */
  public function getFormId() { return 'id_form'; }

  /**
   * Overrides Drupal\Core\Entity\EntityFormController::form().
   *
   * Builds the entity add/edit form.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param FormStateInterface $form_state
   *   An associative array containing the current state of the form.
   *
   * @return array
   *   An associative array containing the settings add/edit form.
   */   
  public function buildForm(array $form, FormStateInterface $form_state) {

  /*
   * to make it short... $form build here
   * then continue...
   */

    // Initialize the counter if it hasn't been set.
    if (null !== ($form_state->get('fields'))) {
      // Nested this deep to avoid conflicts with other modules
      $form_state->set('fields', array(
        'module' => array(
          'fieldset' => array(
            'items_count' => 0
          )
        )
      ));
    }

    $max = $max = $form_state->get(['fields','module','fieldset','items_count']);

    $form['fields']['module']['fieldset'] = array(
      '#type' => 'details',
      '#title' => t('title here'),
      '#description' => t('description here'),
      '#open' => TRUE,
    );

    // Add elements that don't already exist
    for ($delta = 0; $delta <= $max; $delta++) {
      if (!isset($form['fieldset'][$delta])) {
        $element = array('#type' => 'textfield','#title' => t('tittle 00'),'#required' => FALSE);
        $form['fieldset'][$delta]['t00'] = $element;
        $element = array('#type' => 'textfield','#title' => t('title 01'),'#required' => FALSE);
        $form['fieldset'][$delta]['t01'] = $element;
        $element = array('#type' => 'textfield','#title' => t('title 02'),'#required' => FALSE);
        $form['fieldset'][$delta]['t02'] = $element;
      }
    }

    $form['fieldset']['add'] = array(
      '#type' => 'submit',
      '#name' => 'add',
      '#value' => t('Add field'),
      '#submit' => array(array($this, 'addSubmit')),
      '#ajax' => array(
        'callback' => array($this, 'addfield'),
        'wrapper' => 'foo-replace',
        'effect' => 'fade',
      ),
    );

    $form['submit'] = array(
      '#type' => 'submit',
      '#value' => t('Submit'),
    );


    return $form;
  }

  /**
    * Ajax submit to add new ingredient.
  */
  public function addSubmit(array &$form, FormStateInterface $form_state) {
    $max = $form_state->get(['fields','module','fieldset','items_count']);
    $form_state->set(['fields','module','fieldset','items_count'],$max++);
    $form_state->set('rebuild', TRUE);
  }

  /**
    * Ajax callback to add new ingredient.
  */
  public function addfield(array &$form, FormStateInterface $form_state) {
    return $form['fieldset'];
  }

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

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Display result.
  }

}

Thank you,

-1
public function buildForm(array $form, FormStateInterface $form_state) {        
  $form['fields']['modules'] = array(
      '#type' => 'details',
      '#open' => TRUE,
      '#title' => t('sample field'),
      '#description' => t('Explaination about sample field is here, Lorem ipsum dolor sit amet. bla yadda bla yadda. this is a very long description here. Lorem ipsum dolor sit amet. bla yadda bla yadda. this is a very long description here.Lorem ipsum dolor sit amet. bla yadda bla yadda. this is a very long description here.Lorem ipsum dolor sit amet. bla yadda bla yadda. this is a very long description here.Lorem ipsum dolor sit amet. bla yadda bla yadda. this is a very long description here.thank you.'),
      '#prefix' => '<div id="modules-wrapper">',
      '#suffix' => '</div>',
    );

    $max = $form_state->get('fields_count');
    if(is_null($max)) {
      $max = 0;
      $form_state->set('fields_count', $max);
    }

    // Add elements that don't already exist
    for($delta=0; $delta<=$max; $delta++) {
      if (!isset($form['fields']['modules'][$delta])) {
        $element = array(
            '#type' => 'textfield',
            '#title' => t('field Name'),
            '#autocomplete_route_name' => 'route here',
        );
        $form['fields']['modules'][$delta]['iqqq'] = $element;
        $element = array('#type' => 'textfield','#title' => t('aaa'),'#required' => FALSE);
        $form['fields']['modules'][$delta]['iaaa'] = $element;
        $element = array('#type' => 'textfield','#title' => t('sss'),'#required' => FALSE, '#suffix' => '<hr />');
        $form['fields']['modules'][$delta]['isss'] = $element;
      }
    }

    $form['fields']['modules']['add'] = array(
      '#type' => 'submit',
      '#name' => 'addfield',
      '#value' => t('Add more field'),
      '#submit' => array(array($this, 'addfieldsubmit')),
      '#ajax' => array(
        'callback' => array($this, 'addfieldCallback'),
        'wrapper' => 'modules-wrapper',
        'effect' => 'fade',
      ),
    );

    $form['submit'] = array(
      '#type' => 'submit',
      '#value' => t('Submit sample'),
    );


    return $form;
  }

  /**
    * Ajax submit to add new field.
    */
  public function addfieldsubmit(array &$form, FormStateInterface &$form_state) {
    $max = $form_state->get('fields_count') + 1;
    $form_state->set('fields_count',$max);
    $form_state->setRebuild(TRUE);
  }

  /**
    * Ajax callback to add new field.
    */
  public function addfieldCallback(array &$form, FormStateInterface &$form_state) {
    return $form['fields']['modules'];
  }
  • I get an Uncaught AjaxError when using this code. – Matt Aug 9 '16 at 20:29
  • Hi , how it can apply to a content type form ? will it be applicable ? – KTM Jan 19 '18 at 14:16
  • You should add a description of why this works and what fixed it. Don't just post a block of code as an answer. – mbomb007 Apr 19 '19 at 14:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.