Posted by cprofessionals on April 6, 2020 at 11:07pm
I am unable to get the folowing code to trigger an ajax event. The ajax event does not seem to exist. Any Ideas?
$form['import_file'] = array(
'#type' => 'managed_file',
'#name' => 'import_file',
'#title' => t('Select Import File'),
'#size' => 20,
'#description' => t('CSV only for now'),
'#upload_validators' => $validators,
'#upload_location' => 'public://easy_import',
'#progress_indicator' => 'bar',
'#default_value' => array($this->conf->get('import_file')),
'#ajax' => [
'callback' => [$this, 'fileSelectAjaxCallback'],
'event' => 'change',
'effect' => 'slide',
'wrapper' => 'entity-ajax', // This element is updated with this AJAX callback.
'progress' => [
'type' => 'throbber',
'message' => $this->t('Checking...'),
],
],
);
Comments
Have you checked to see what
Have you checked to see what the HTML output of this ends up being? A successful Ajax would put something like
onChange="some JS code"as an attribute of an HTML element. But... This element is a Managed File, which is not a base HTML element, so probably the Drupal code that handles it just doesn't know what to do with this Ajax event.
So... A few thoughts:
a) This page on api.drupal.org lists the form/render elements:
https://api.drupal.org/api/drupal/elements/8.8.x
b) From there you can get to the ManagedFile class, which is the element you are using (look up the #type of 'managed_file' in the first column of the table):
https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Element%...
Hm. It looks like that class already has some Ajax processing when a file is uploaded. Maybe your best bet would be to override that class, making a new element type, and override the existing uploadAjaxCallback() method that is already somehow tied into the Ajax for this class?
Actually, if you look at the processManagedFile() method (which is what is called when the form element is rendered into HTML), you can see that it is putting its own Ajax processing into the output, and not checking to see if you've put your own Ajax processing in.
So if you really want a different Ajax handling, I think you will need to make your own element class and override one or both of these methods?
Hope this helps...
Drupal programmer - http://poplarware.com
Drupal author - http://shop.oreilly.com/product/0636920034612.do
Drupal contributor - https://www.drupal.org/u/jhodgdon
Thanks for the input! Weird
Thanks for the input!
Weird that all other elements have ajax but this one. Also odd that tothers have not needed this. Usually when I run into this I am asking the wrong question. I have posted on Slack and in forums to get some assistance, but this one is not being touched.
Are you suggesting adding an ajax event to the managed_file widget? I am really unclear where to start with this. I will do some research. any shortcuts you can think of?
Use the existing one?
I think I'm suggesting:
a) Override the ManagedFile class (which is a form element, technically, not a widget). You'll need to also put in the plugin part of the docs header (which will tell Drupal that your class is also a form element and assigns it an ID), and put it in the right directory and namespace (src/Element directory, your_module\Element namespace).
b) In your class, override the uploadAjaxCallback() method so that it does what you want it to do, in place of the default behavior.
c) If you want Ajax behavior for some other event other than someone uploading a file, you would also need to override the processManagedFile method so that it sets up the field to respond to that event, and call a new method that you'll put on your element class similar to uploadAjaxCallback().
d) In your form builder code, reference this new element type in place of #type = managed_file (put in your plugin ID).
That's a bit abbreviated... hope it helps!
Drupal programmer - http://poplarware.com
Drupal author - http://shop.oreilly.com/product/0636920034612.do
Drupal contributor - https://www.drupal.org/u/jhodgdon