3

I want to create a custom form element for email that have a textfield and button and when click button send an email but ajax not working inside form elemen class. I test it in form api and it's ok but when move in form element on button click nothing happend this is my code

<?php
/**
 * Created by IntelliJ IDEA.
 * User: peter
 * Date: 24/12/18
 * Time: 13:59
 */

namespace Drupal\aqr_basic\Element;


use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\FormElement;

/**
 * Provides a form element to display a email.
 *
 *
 * @FormElement("aqr_email")
 */
class EmailElement extends FormElement {


  public function getInfo() {
    $class = get_class($this);
    return [
      '#pre_render' => [
        [$class, 'preRenderSelect'],
      ],
    ];
  }


  public static function preRenderSelect($element) {
    dump($element);
    $email = [
      '#type' => 'email',
      '#title' => $element['#emailTitle'],
    ];
    $email = array_merge($email,$element['email']);
    $btnSendCode = [
      '#type' => 'ajax_button',
      '#value' => $element['#btnSendCodeTitle'],
      '#ajax' => [                  //////this ajax not work
        'callback' => '::email',
        'event' => 'click',
      ],
    ];

    $btnSendCode = array_merge($btnSendCode,$element['btnSendCode']);
    $verifyGroup = [
      '#type' => 'fieldgroup',
      '#attributes' => ['class' => ['hidden']],

    ];
    $verifyGroup['emailCode'] = [
      '#type' => 'textfield',
      '#title' => $element['#emailCodeTitle'],
    ];
    $verifyGroup['emailCode'] = array_merge($verifyGroup['emailCode'],$element['verifyGroup']['emailCode']);
    $verifyGroup['btnVerifyCode'] = [
      '#type' => 'ajax_button',
      '#value' => $element['#btnVerifyCodeTitle'],
      '#suffix' => '<div class="verification-desc email_verify">' . $element['#description'] . '</div>',
    ];
    $verifyGroup['btnVerifyCode'] = array_merge($verifyGroup['btnVerifyCode'],$element['verifyGroup']['btnVerifyCode']);

    $element = [
//      '#attached'=>[
//        'library' => ['aqr_basic/state'],
//        'drupalSettings' => [
//          'id' => $element['#id'],
//          'cities' => json_encode($cities),
//        ],
//      ],
      'email' => $email,
      'btnSendCode' => $btnSendCode,
      'verifyGroup' => $verifyGroup,
      '#attributes' => ['id' => ['email-wrapper-id'], 'class' => ['email_verify']],
    ];
    dump($element);
    return $element;
  }


  /**
   * {@inheritdoc}
   */
  public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
    return $input;
  }

  public static function email(array &$form, FormStateInterface $form_state) {

    dump($form);

    return $form;
  }
}

2 Answers 2

1

I believe you may need this syntax as your callback, I think because everything went to being 'static' when you moved your demo code from a form to a Element.

 $btnSendCode = [
  '#type' => 'ajax_button',
  '#value' => $element['#btnSendCodeTitle'],
  '#ajax' => [                  
    'callback' => ['\Drupal\aqr_basic\Element\EmailElement', 'email'],
    'event' => 'click',
  ],
];
0

You need to add a wrapper and div ID to where you want the ajax to load

  '#ajax' => [               
    'callback' => '::email',
    'wrapper' => 'load-me-here', // we tell ajax to target this ID
    'event' => 'click',
  ],
  // attach the ID you targeted above to some element.
  '#attributes' => ['id' => 'load-me-here'],

  // you could create a new element if you want.
  // there is so many variations you can do to add the ID.

  //  $element['load'] = [
  //   '#type' => 'fieldset',
  //   '#title' => t('Load the stuff here'), 
  //   '#attributes' => ['id' => 'load-me-here'],
  //  ];

  // OR

  //  $element['load'] = [
  //   '#type' => 'markup',
  //   '#title' => t('Load the stuff here'), 
  //   '#markup' => '<div id="load-me-here"></div>', 
  //  ];

  // OR

  //  $element['load'] = [
  //   '#type' => 'fieldset',
  //   '#title' => t('Load the stuff here'), 
  //   '#prefix' => '<div id="load-me-here">',
  //   '#suffix' => '</div>',
  //  ];

Also, remove the dump($form); from your ajax email callback function, this prevents it from working.

You'll have to install Devel and use dpm($form); if you want to see the structure of the array. Also, note that Devel's kint($form); wont work on ajax callback either.

5
  • tnx I test your code but not help me and wrapper only for when you want replace html. see api.drupal.org/api/drupal/core!core.api.php/group/ajax/8.2.x
    – sadeghpro
    Jan 7, 2019 at 4:58
  • @sadeghpro how else do you expect to see your dump dpm($form); and your return $form if there is no new html?
    – No Sssweat
    Jan 7, 2019 at 5:19
  • my problem is there is no ajax call to have response. nothing happened when click a button. if ajax send request then I must change dump($form) and set up it.
    – sadeghpro
    Jan 7, 2019 at 5:34
  • @sadeghpro like I mentioned dump($form) causes issues. Try with just return $form and get that working first.
    – No Sssweat
    Jan 7, 2019 at 5:48
  • ok I remove dump($form) and only return form but nothing change. I tell you I use firefox inspect network tab there is no ajax request when click button.I think render api don't add ajax to element when I use element in another custom element
    – sadeghpro
    Jan 7, 2019 at 6:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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