Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Just encountered the error:
Uncaught TypeError: Cannot read property 'submitButtonSelector' of undefined
This happens when I use the Drag and Drop after validation fails. If I put the following in an after build function:
<?php
$selector = variable_get('dragdropfile_submit_button_selector', DRAGDROPFILE_SUBMIT_BUTTON_SELECTOR);
drupal_add_js(array('dragDropFile' => array('submitButtonSelector' => $selector)), 'setting');
?>
it does then work again after validation. Can anyone else replicate this error?
Comments
Comment #2
tce CreditAttribution: tce commentedComment #3
rudiedirkx CreditAttribution: rudiedirkx commentedWhich validation? JS does a simple client side validation for file extension. Which validation fails for you? I'm assuming server side. I want to reproduce.
Comment #4
tce CreditAttribution: tce commentedSorry, yeah, server validation. In node edit, when I press the submit button and the form validation fails and page reloads again, I get this error and the drag and drop no longer works. However, if I use 'hook_form_alter' and put the code in an after build function it does then work after validation. I've not tested this on a vanilla Drupal install though, which I will do later today - I am using a lot of modules for the site I'm working on.
Just curious, could you not attach this to the form instead? eg:
UPDATE
=======
I created a site at https://simplytest.me/ with this module and the same problem occurs.
Step 1: Create a site with drag and drop enabled, add an image field to a content.
Step 2: Go to add content, click submit and validation should fail as no title.
Step 3: Drag a file into the box. Nothing happens but error shown in console.
My hunch is the setting is not being remembered due to form caching, so maybe attaching or adding in after_build could fix?
Comment #5
rudiedirkx CreditAttribution: rudiedirkx commentedNow that's debugging! Thanks man. (I can't seem to get DDF working at all on SimplyTest though. It keeps telling me "The uploaded file likely exceeded the maximum file size (2 MB) that this server supports.".)
I can add more settings in
#attached
, but the problem is if they exist double, the JS setting will be broken too. So I have to be very sure exactly where and when to add it, so it always exist once. I thought this is why#attached
existed: if the element is rendered, the attached JS is included. Maybe I still misunderstand.Maybe tomorrow...
Comment #6
tce CreditAttribution: tce commentedAs I understand it, dragdropfile_field_widget_form_alter() will not run again after validation fails, because the form is called from the cache at this time. So the call to drupal_add_js() to add the setting does not run causing the JS error as your JS code is expecting it.
Either of the below solutions fix the problem for me.
1) Move your drupal_add_js() code into an after_build function.
2) Replacing drupal_add_js() with #attached
I think the best way is using #attached.
I'm not sure what you mean but I think render() uses drupal_add_js() when it sees #attached anyway, so it should work the same as how you have it now, the only difference is that drupal_add_js() is eventually getting called after validation and not lost due to form caching. That's how I understand it anyway.
Comment #8
rudiedirkx CreditAttribution: rudiedirkx commentedOoooooooh, I wasn't using
#attached
for the JS settings! OMG I'm a dumbass. Yes, you're right of course,#attached
is the best. Sorry that took a while =)I'm still getting fails on validate though. I have 2 multiple drag & drop image fields. When I drag 1 image onto a field, then submit without title, it fails on validation, but all
#attached
JS & CSS isn't included anymore. The 1 dropped image is there, but no drop container anywhere, not even on the other (empty) field. That's weird...That problem goes away if I remove the
$form_state['#dragdropfile']
check, which' function was to add all JS & CSS only once, but apparently Drupal is smart (?) enough to do that anyway. This is the best way I think, because every separate element should require all JS, not just the first in the form build process.Let me know if the last commit works for you. It should be referenced around here somewhere.
Comment #9
tce CreditAttribution: tce commentedAh yes, I'm seeing the other bug. When validation fails, I can now (with the fix) drag an image over, but if validation fails again after that, the drag and drop container disappears.
Removing the
if (empty($form_state['#dragdropfile']))
check fixes the problem. I don't think that's needed as the array that is built to add the css and js assets use the filename as the key, so there is no risk of duplicating assets. If you go to drupal_add_js() at the bottom it says:Your module works a treat now, thank you.
Comment #10
rudiedirkx CreditAttribution: rudiedirkx commentedI knew the files wouldn't be included twice, but I was afraid the settings might be. I still don't understand why they're not. For some reason it works and I don't understand why. Or maybe they are, but the deep merge is smart enough to not make it an array...
The safer option is to attach the settings to the DOM element, maybe with a data attribute, but since this works, I guess we're done. Thanks for all the explanation and debugging!
Comment #11
rudiedirkx CreditAttribution: rudiedirkx commentedI'll create a new release soon.
Comment #12
tce CreditAttribution: tce commentedOh I see. Not sure, but if I put only the settings part of the code in the check it still works:
Comment #13
rudiedirkx CreditAttribution: rudiedirkx commentedWhaaat? That's even weirder, because that's the part it was missing before!
Screw it. This works. Don't touch it! I'm making a new release.