1

I need to help the user to fill a set of fields in a content type form, this way :

The users start to fill one of the concerned fields: They click on a button that will open a modal form. The modal form will propose some choices depending on the filled fields; when users choose a proposition, the modal form closes and the fields of the original form get updated with the chosen proposition.

I have tested 2 methods to open the modal form and I have issues with both.

With the first method, I can open and close the modal form, but I can't transmit field values from the form 1 to the modal form; with the second method, I can pass the field values to the modal form, but I fail closing this modal form.

How can I update the fields from the first form when I close the modal form?

This is my .module file. Read the comments for details.

use Drupal\Core\Url;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Ajax\CloseModalDialogCommand;


/**
 * Implements hook_form_FORM_ID_alter().
 */
function my_test_module_form_node_article_form_alter(&$form, &$form_state, $form_id)  {

    $form['#attached']['library'][] = 'core/drupal.dialog.ajax';

    $form['my_fieldset'] = array (
            '#type' => 'fieldset',
            '#title' => t ( 'My fieldset' ),
            '#collapsible' => TRUE,
            '#collapsed' => FALSE,
            '#tree' => TRUE
    );
    $form['my_fieldset']['my_field_1'] = array(
        '#type' => 'textfield',
        '#title' => t('Field 1'),
    );
    $form['my_fieldset']['my_field_2'] = array(
            '#type' => 'textfield',
            '#title' => t('Field 2'),
    );
    // METHOD 1
    // Problem : it doesn't allow to transmit my field values (from the $form_state) to the modal Form
    $form['my_fieldset']['open_modal1'] = array(
            '#type' => 'link',
            '#title' => t('Open modal 1'),
            '#url' => Url::fromRoute('my_test_module.modal_form'),
            '#attributes' => array(
                    'class' => array('button', 'use-ajax'),
                    'data-dialog-type' => 'modal',
            ),
    );
    // METHOD 2
    // Problem : The modal form can't be closed
    $form['my_fieldset']['open_modal2'] = array(
            '#type' => 'submit',
            '#value' => t('Open modal 2'),
            '#ajax' => array(
                    'callback' =>  'my_test_module_open_modal_form',
                    'event' => 'click',
            ),
    );
}

/**
 * Ajax Callback for the form - it opens the modal form
 *
 */
function my_test_module_open_modal_form($form, $form_state) {

    $values = $form_state->getValues(); 

    // Get the modal form
    $modal_form = \Drupal::formBuilder()->getForm('Drupal\my_test_module\Form\MyModalForm',$values['my_fieldset']['my_field_1'],$values['my_fieldset']['my_field_2']);
    // Add an AJAX command to open a modal dialog with the form as the content.
    $response = new AjaxResponse();
    $response->addCommand(new OpenModalDialogCommand(t('My Modal'), $modal_form, ['width' => '555']));  
    return $response;
}

The modal form class I use is the following one.

/**
* @file
* Contains \Drupal\my_test_module\Form\MyModalForm.
*/

namespace Drupal\my_test_module\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseModalDialogCommand;

/**
 * This class restitutes the modal form
 *
 */
class MyModalForm extends FormBase {

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

    public function buildForm(array $form, FormStateInterface $form_state, $field_1 = NULL, $field_2 = NULL) {

        $form['m1'] = array(
                '#markup' => 'Field 1 : ' . $field_1,
        );
        $form['m2'] = array(
                '#markup' => 'Field 2 : ' . $field_2,
        );

        $form['results'] = array (
                '#type' => 'table',
                '#header' => array('Field 1', 'Field 2',''),
        );


        $form['results'][0]['field_1'] = array(
                '#markup' => 'AAAA',
        );
        $form['results'][0]['field_2'] = array(
                '#markup' => 'BBBB',
        );
        $form['results'][0]['submit0'] = array(
                '#type' => 'submit',
                '#value' => 'Choose',
                'name' => '0',
                '#attributes' => [
                        'class' => [
                                'use-ajax',
                        ],
                ],
                '#ajax' => array(
                        'callback' => '::ajaxCloseModal',
                        'event' => 'click',
                ),
        );

        $form['results'][1]['field_1'] = array(
                '#markup' => 'AAAA',
        );
        $form['results'][1]['field_2'] = array(
                '#markup' => 'BBBB',
        );
        $form['results'][1]['submit1'] = array(
                '#type' => 'submit',
                '#value' => 'Choose',
                'name' => '1',
                '#attributes' => [
                        'class' => [
                                'use-ajax',
                        ],
                ],
                '#ajax' => array(
                        'callback' => '::ajaxCloseModal',
                        'event' => 'click',
                ),
        );
        return $form;

    }

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

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

    public function ajaxCloseModal(array &$form, FormStateInterface $form_state) {
        $response = new AjaxResponse();
        $response->addCommand(new CloseModalDialogCommand());
        //Get the triggering element, then replace the field_1 and field_2 values in the original form
        return $response;

    }


}

1 Answer 1

-1

For closing model form you can use jquery. When field value will update javascript change event will occur so you can trigger modal form close button or link

$( "#textField" ).change(function() {
  $( "#close" ).trigger( "click" ); // if modal form have close button or some url
  $( "#modal" ).modal( "toggle" ); // in case of using bootstrap modal form
});

References: .change(), .trigger()

1
  • I would like to avoid using jquery at this point when I'm not far from a full Drupal solution. But that will be an option if I don't find other solution. Thanks.
    – user70263
    Commented Nov 14, 2017 at 13:26

Your Answer

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

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