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;
}
}