I have a custom entity (contract_subscription) created in a custom module (amap) by a bunch of BaseFieldDefinition, one of which being a file field:

$fields['file'] = BaseFieldDefinition::create('file')
  ->setLabel(t('pdf file'))
    'target_type' => 'file',
    'file_extensions' => 'pdf',
    'uri_scheme' => 'private',
    'file_directory' => 'contracts/subscriptions',

I created a form to "mass"update this entity.
In this form, the file field is defined this way:

$form['subscriptions'][$key]['file'] = array(
    '#type' => 'managed_file',
    '#upload_validators' => array(
      'file_validate_extensions' => array('pdf'),

wich gives this:
enter image description here I'd like to replace the standard way the file field is presented by a simple button.
The click on the button would show a modal popup with the standard file field management in it.
How can I do that?

I updated my code this way.
Replaced the file field by a link and a hidden field:

  $form['subscriptions'][$key]['filelink'] = array(
    '#type' => 'link',
    '#title' => $title,
    '#url' => Url::fromRoute('amap.contract_subscription_file_form', ['file' => $fileId]),
    '#attributes' => [
      'id' => ['myLink' . $key],                     <-- New
      'class' => ['use-ajax'],
      'data-dialog-type' => 'modal',

  $form['subscriptions'][$key]['file'] = array(
  '#type' => 'hidden',
  '#attributes' => array('id' => 'myFile' . $key),   <-- New
  '#default_value' => $fileId,

Added this to amap.routing.yml

  path: '/amap/contract/subscription/{file}'
    _form: '\Drupal\amap\Form\ContractSubscriptionFileForm'
    _title: 'Add file'
    _access: 'TRUE' 

and this ContractSubscriptionFileForm definition:

class ContractSubscriptionFileForm extends FormBase
  public function getFormId()
    return 'contract_subscription_file_form';

  public function buildForm(array $form, FormStateInterface $form_state, $file = NULL)
    $form['file'] = array(
      '#type' => 'managed_file',
      '#upload_location' => 'private://contracts/subscriptions/',
      '#upload_validators' => array(
        'file_validate_extensions' => array('pdf'),
      '#default_value' => array($file),
    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
      '#ajax' => [
        'callback' => '::ajaxSubmitForm',
        'event' => 'click',
    $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
    return $form;

  public function validateForm(array &$form, FormStateInterface $form_state)
    parent::validateForm($form, $form_state);

  public function submitForm(array &$form, FormStateInterface $form_state)

  public function ajaxSubmitForm(array &$form, FormStateInterface $form_state)
    $response = new AjaxResponse();
    $html = '<a href="/amap/contract/subscription/999" id="myLink1" class="use-ajax" data-dialog-type="modal" data-drupal-selector="edit-subscriptions-0-filelink">999</a>';
    $response->addCommand(new ReplaceCommand('#myLink1', $html));
    $html = '<input data-drupal-selector="myFile1" type="hidden" name="subscriptions[1][file]" value="999">';
    $response->addCommand(new ReplaceCommand('#myFile1', $html));
    $response->addCommand(new CloseModalDialogCommand());
    return $response;

And now I get:
enter image description here when the file already exists
enter image description here when there is no file

The $html code in ajaxSubmitForm is hardcoded only for test purpose...
When I submit the modal, the original table form is updated accordingly (the link title = 999 and the link URI points to .../999.

My question is: I can get the value of file id from $form_state and replace the 999of my current code.
But I don't know how to retrieve the generated html for myLink1 and myFile1.
Any idea?

  • You probably don’t need anything Drupal-y for that - if you’ve already got the markup in the page, there are tons of libraries out there you can use to display the elements in a modal
    – Clive
    Apr 11, 2019 at 17:40
  • If you can modify the html of the output try this drupal.stackexchange.com/questions/249040/… sollution is not webform specific
    – GiorgosK
    Apr 11, 2019 at 17:52
  • The problem with doing it that way is you need a new form (or form mode), a route to get it from, etc @GiorgosK. Might be easier just to use some js if the content is already there
    – Clive
    Apr 11, 2019 at 18:03
  • @clive you are right I did not read the question carefully, I thought it was just for display
    – GiorgosK
    Apr 11, 2019 at 18:09
  • @Clive any examples I could look at?
    – gbmapo
    Apr 12, 2019 at 11:23


Your Answer

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

Browse other questions tagged or ask your own question.