Here on this page we can see that it is possible to add some events with plupload library.
As far as I understood, this module allows us to append custom settings with:

  '#plupload_settings' => array(
    'runtimes' => 'html5',
    'chunk_size' => '1mb',
  ),

Logically, this is a place where events should be added considering plupload example stated above, consider for example

  init : {
  QueueChanged: function(up) {
    // Called when the files in queue are changed by adding/removing files
    log('[QueueChanged]');
  }

expecting something like

  '#plupload_settings' => array(
    'runtimes' => 'html5',
    'chunk_size' => '1mb',
    'init' => .......
  ),

I am not quite sure how to add it?
Or maybe it is better to use some other approach, js?

Thanks,
Vladan

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

slashrsm’s picture

#plupload_settings will work only for simple values. AFAIK it won't allow you to pass functions through it.

This would be interesting feature, though. We implemented something similar for disqus.module. Maybe we can take same approach here? See http://drupalcode.org/project/disqus.git/commit/3ab6de3bff78d92f5b02b5c1... for more info.

vladan.me’s picture

Status: Active » Needs review
FileSize
762 bytes

Sorry, it took a while, first I used some workaround (not enough exp :-) ) but now I am back to this, I believe this patch would work. Usage could be something like this:

  '#plupload_settings' => array(
    'runtimes' => 'html5',
    'chunk_size' => '1mb',
    'init' => array(
      'FilesAdded' => 'Drupal.mymodule.FilesAdded',
      'UploadComplete' => 'Drupal.mymodule.UploadComplete',
      ),
  ),

Can you please review it?

vladan.me’s picture

FileSize
687 bytes

Hm, in my case, in firefox dragging images into window now breaks after using custom events, not sure why is that happening but this helped. Any better idea?

slashrsm’s picture

Hm... not sure. Never tried to implement this feature. Isn't this last patch overriding default behaviour?

vladan.me’s picture

Thing is, I have asked this question aiming toward events but my actual need was same as #autostart feature in previous issue. Then, I have created that patch for #autostart but since I was already there, I figured I could do this as well. If both of those patches are applied, I would rather see handling #autostart first and then custom events. I think that most of users will use either this or autostart and if they are using both we can add one more line in custom events handling, something like:

if(!pluploadSettings.init) {
  pluploadSettings.init = {};
}

About prevent default, I don't really like proposed solution, it does override default behavior but I think any drag&drop is doing same anyway. Here is what happens in my case, same goes for both patches - I am getting default way of displaying image on drop functionality, first image of multiple selected is displayed in Firefox directly from HDD. If you have time to check it, can you please confirm this issue by, for instance, applying #autostart patch and then trying to drag&drop in latest release of Firefox?
Reference: stackoverflow

slashrsm’s picture

Status: Needs review » Needs work

I actually didn't experience that Firefox behaviour with this patch. Maybe it is related to a specific event. Which events are you using? I am using Firefox 24.0 at Ubuntu 13.04.

We should probably implement autostart patch via events anyway (use #autostart and #autosubmit, create two functions in JS and put them in 'init' array in pre_render hook). If we take this approach we first need to get this in and then work on autosubmit after that.

+++ b/plupload.js
@@ -43,7 +43,19 @@
+      if (elementSettings['init'] || false) {
+        pluploadSettings.init = {};
+        for (var key in elementSettings['init']) {

I think that this feature would be easier to use if we would dedicate special Form API argument to it and then do some pre_render magic to translate it to JS settings. It would look something like this:

$form['upload'] = array(
  '#type' => 'plupload',
  '#event_callbacks' => array(
    'UploadProgress' => 'Drupal.myModule.uploadProgressCallback',
  ),
);

What do you think about that?

And of course... This also needs README.txt entry and both patches need documentation pages update as a follow-up.

vladan.me’s picture

FileSize
2.49 KB

There might be other factors included since I am not testing on clean Drupal version... Never mind, shouldn't be plupload issue.
I think that autoupload would make better name than autostart for uploading?
I hope that I understood well your words in following patch. It's combined patch, autoupload&autosubmit and events support. Please review...
I'll make README.txt when you approve code.

vladan.me’s picture

Status: Needs work » Needs review
slashrsm’s picture

  1. +++ b/plupload.module
    @@ -258,7 +258,20 @@
    +  ¶
    +  if(isset($element['#autoupload'])) {
    +    $settings['init']['FilesAdded'] = 'Drupal.behaviors.plupload.FilesAdded';
    +  }
    +  if(isset($element['#autosubmit'])) {
    +    $settings['init']['UploadComplete'] = 'Drupal.behaviors.plupload.UploadComplete';
    +  }
    +  if(isset($element['#submit_element'])) {
    +    $settings['submit_element'] = $element['#submit_element'];
    +  }
    +  if(isset($element['#event_callbacks'])) {
    +    $settings['init'] = array_merge($settings['init'], $element['#event_callbacks']);
    +  }
    +  ¶
    

    I'd rather see this in PHP. pre_render hook is probably the right place to do that.

  2. +++ b/plupload.js
    @@ -6,6 +6,24 @@
    +  ¶
    +  // Add Plupload events for autoupload and autosubmit
    +  FilesAdded:function (up, files) {
    +    setTimeout(this.start(), 100);
    +  },
    +  UploadComplete: function(up, files) {
    +    //if submit_element exists get that one (directly from Drupal.settings?):
    +    var submit_element = window.Drupal.settings.plupload["edit-files"].submit_element;
    +    if(submit_element) {
    +      $(submit_element).click();
    +    }
    +    // else just submit form you find
    +    else {
    +      var $form = $(".plupload-element").parents('form');
    +      $($form[0]).submit();
    +    }
    +  },
    +          ¶
       attach: function (context, settings) {
    

    This functions do not belong in Drupal.behaviours. We should probably move them to Drupal.plupload or something like this.

You are leaving a lot of trailing whitespace. Try to configure your IDE to auto-trim this.

vladan.me’s picture

FileSize
4.53 KB

This functions do not belong in Drupal.behaviours. We should probably move them to Drupal.plupload or something like this.

Ah, yes, sorry...

I'd rather see this in PHP. pre_render hook is probably the right place to do that.

Didn't I put it inside it, hm? Is there another pre_render?

function plupload_element_pre_render($element) {
  $settings = isset($element['#plupload_settings']) ? $element['#plupload_settings'] : array();

  // The Plupload library supports client-side validation of file extension, so
  // pass along the information for it to do that. However, as with all client-
  // side validation, this is a UI enhancement only, and not a replacement for
  // server-side validation.
  if (empty($settings['filters']) && isset($element['#upload_validators']['file_validate_extensions'][0])) {
    $settings['filters'][] = array(
      // @todo Some runtimes (e.g., flash) require a non-empty title for each
      //   filter, but I don't know what this title is used for. Seems a shame
      //   to hard-code it, but what's a good way to avoid that?
      'title' => t('Allowed files'),
      'extensions' => str_replace(' ', ',', $element['#upload_validators']['file_validate_extensions'][0]),
    );
  }

  if(isset($element['#autoupload'])) {
    $settings['init']['FilesAdded'] = 'Drupal.plupload.FilesAdded';
  }
  if(isset($element['#autosubmit'])) {
    $settings['init']['UploadComplete'] = 'Drupal.plupload.UploadComplete';
  }
  if(isset($element['#submit_element'])) {
    $settings['submit_element'] = $element['#submit_element'];
  }
  if(isset($element['#event_callbacks'])) {
    $settings['init'] = array_merge($settings['init'], $element['#event_callbacks']);
  }

  if (empty($element['#description'])) {
    $element['#description'] = '';
  }
  $element['#description'] = theme('file_upload_help', array('description' => $element['#description'], 'upload_validators' => $element['#upload_validators']));

  $element['#attached']['js'][] = array(
    'type' => 'setting',
    'data' => array('plupload' => array($element['#id'] => $settings)),
  );

  return $element;
}
slashrsm’s picture

Version: 7.x-2.x-dev » 7.x-1.1
Component: Code » Documentation
Category: feature » support

Ah... stupid me... Sorry for that!

+  if(isset($element['#autoupload'])) {
+    $settings['init']['FilesAdded'] = 'Drupal.plupload.FilesAdded';
+  }
+  if(isset($element['#autosubmit'])) {
+    $settings['init']['UploadComplete'] = 'Drupal.plupload.UploadComplete';
+  }

Those should probably be empty() checks. Maybe also put #autosubmit inside #autoupload condition as it is kind of a dependency.

+  if(isset($element['#submit_element'])) {
+    $settings['submit_element'] = $element['#submit_element'];
+  }

We don't need that as it is already added above.

Otherwise looks very nice. Thank you for your great work!

slashrsm’s picture

Version: 7.x-1.1 » 7.x-2.x-dev
Component: Documentation » Code
Category: support » feature

Changing version as it needs to go to 7.x-2.x first, but it should be pretty easy to backport (cherry-pick will probably work w/o any problems).

vladan.me’s picture

Version: 7.x-1.1 » 7.x-2.x-dev
Component: Documentation » Code
Category: support » feature

We don't need that as it is already added above.

Hm, I didn't get this, which idea you have to pass submit_element to js?
Thanks!

--------------------------------------------------
Edit, I figure it out, I'll upload patch now

vladan.me’s picture

FileSize
6.58 KB

There, documentation included. You can give final touch. :)

vladan.me’s picture

FileSize
6.52 KB

Ah, one more thing minor thing, It's about parameter in setTimeout()

slashrsm’s picture

Status: Needs review » Needs work

Hm... you probably don't work against HEAD but 7.x-1.1. In 7.x-1.2 we added new option called "#submit_element". Pull latest code and you'll see what it is all about. It is good practice if you always create your patches against latest module code (i.e. HEAD).

+++ b/sites/all/modules/contrib/plupload/README.txt
@@ -36,6 +36,13 @@
+    'autoupload' => TRUE,
+    'autosubmit' => TRUE,
+    'submit_element' => '#id-of-my-submit-element',

My idea was to have those two as separate options (i.e. #autosubmit and #autoupload), not as a part of #plupload_settings. As they really do not map to settings 1-on-1.

Taking paragraph above into consideration we also don't need "submit_element" as it already exists. Check: http://drupalcode.org/project/plupload.git/commitdiff/6884b4a

vladan.me’s picture

Assigned: Unassigned » vladan.me
Status: Needs work » Needs review
FileSize
7.76 KB

My apologies for beginner mistakes once again... I am just trying make contribution to this great module. Thank you for tips and patience, I appreciate it.
I have created patch against HEAD now but I believe that trailing whitespace was caused by some of previous patches, not mine... I've added few changes as well, mostly styling. I think this one should be ready for commit, but, to make sure, please have another look.

slashrsm’s picture

Status: Needs review » Needs work

No problem at all. I really appreciate your hard work. This will bring great new features to this module. I am planning to release new version when we commit this. And we are all making mistakes and learning every day anyway. :)

Yes... some whitespace was yours and some was in 7.x-1.1, but was already removed. It is very good habit to always enable auto-trim. This makes out code much cleaner.

I have just two little bits:

  1. +++ b/sites/all/modules/plupload/plupload.js
    @@ -1,7 +1,23 @@
    +Drupal.plupload.uploadCompleteCallback = function(up, files) {
    +  var $this = $(".plupload-element");
    +  // If there is submit_element trigger it.
    +  var submit_element = window.Drupal.settings.plupload[$this.attr('id')].submit_element;
    

    This will work if there is only one plupload element on a form, but fail if there are more. Can we use "up" instead of "$this"?

  2. +++ b/sites/all/modules/plupload/plupload.module
    @@ -265,11 +265,22 @@
    +    $settings['init'] = array_merge((array)$settings['init'], (array)$element['#event_callbacks']);
    +  }
     
    

    Why do we need this casts?

vladan.me’s picture

1) Yeah, I guess we can change that to use "up", something like this probably
var $this = $("#"+up.settings.container);
2) I put comment just above that line, thing is array_merge() expects arrays as type php manual and if our $settings['init'] is not set, has value NULL so implicitly we are casting it to an array. It just won't work with NULL, believe me, I tried, hehe. :)

slashrsm’s picture

2) I put comment just above that line, thing is array_merge() expects arrays as type php manual and if our $settings['init'] is not set, has value NULL so implicitly we are casting it to an array. It just won't work with NULL, believe me, I tried, hehe. :)

I think it would be better to properly initialize $settings['init'] as an empty array if not initialized yet. It makes code much more readable and understandable.

The other one looks good.

vladan.me’s picture

FileSize
7.52 KB

How about this?
I have fixed some coder errors too...

slashrsm’s picture

Assigned: vladan.me » Unassigned
Status: Needs work » Fixed

Great! Committed to both 7.x-2.x and 7.x-1.x.

http://drupalcode.org/project/plupload.git/commit/969141e
http://drupalcode.org/project/plupload.git/commit/9236913

Thank you so much for your great work!

P.S.: Another suggestion. Consider using interdiffs when contributing. It is becoming a standard nowdays, specially if you contribute to core. More info: https://drupal.org/documentation/git/interdiff

vladan.me’s picture

Thank you once again for continuous support. Glad I could help.
Sure, I'll have a look on it.
Cheers!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

  • Commit 9236913 on 7.x-1.x, 8.x-1.x authored by vladan.me, committed by slashrsm:
    Issue #2065927 by vladan.me: Added Plupload events support.