0

We're using JackUp for ajax image upload in Rails. We chose it because it doesn't assume very much and it's pretty light weight.

Following it's example code, we came up with something like this:

  let jackUp = new JackUp.Processor({
    path: '/images'
  });

  jackUp.on('upload:imageRenderReady', (e, options) => {
    options.image.attr("data-id", options.file.__guid__).css({
      border: "5px solid red"
    });
    $('[data-behavior=image-block-container]').prepend(options.image);

  }).on("upload:sentToServer", (e, options) => {
    $(`img[data-id='${options.file.__guid__}']`).css({
      borderColor: 'yellow'
    });

  }).on("upload:success", (e, options) => {
    $(`img[data-id='${options.file.__guid__}']`).css({
      borderColor: "green"
    });

  }).on("upload:failure", (e, options) => {
    alert(`'${options.file.name}' upload failed; please retry`);
    $(`img[data-id='${options.file.__guid__}']`).remove();
  });

  $('.file-drop').jackUpDragAndDrop(jackUp);

  $(document).bind('drop dragover', e => {
     e.preventDefault();
  });

This works just as expected with one image upload button (classed as file-drop). However, a page will have an unknown number of these image upload buttons.

When there is more than one upload button, every time a file is added it's appended to all image-block-container elements, instead of just the one that was targeted. It appears that jackUp has no notion of the element that triggered it.


What's the best way to allow each upload button to know what called it? I've tried surrounding it in an .on('drop'... block. That gave me access to the element, but none of JackUp's events fired.

Any help or advice for a lightweight Rails-friendly ajax upload gem is appreciated!

Kieran E
  • 3,616
  • 2
  • 18
  • 41

1 Answers1

0

You are broadly matching multiple parts of your DOM with this query selector: $('[data-behavior=image-block-container]'). Multiple elements matching this selector are presumably the cause of your weird update issue.

If you want to target just the element that the user was interacting with, the e variable in the upload:imageRenderReady event handler should have a [target][1] which is generally what the user was interacting with and should get you close to what you want (depending on how your DOM is structured).

From jQuery:

The target property can be the element that registered for the event or a descendant of it.

pherris
  • 17,195
  • 8
  • 42
  • 58
  • `e` in `upload:imageRenderReady` appears to have no reference to what the user was interacting with. This is what `e` looks like: http://puu.sh/omnI9/650cdf2fd7.png and this is `e.target` http://puu.sh/omnLR/015ff297f3.png. Trust me, nothing in `e.target, currentTarget or delegateTarget` have any reference to a DOM element. They all appear to be referencing `jQuery11210678854975767535` but I can't make out what that is. When I look into the `jQuery112...` object, there's nothing of note. – Kieran E Apr 18 '16 at 02:58
  • I'm assuming you also looked at the `options` argument? I think it will have `image` and `file`: https://github.com/thoughtbot/jack_up/blob/master/lib/assets/javascripts/jack_up/processor.coffee#L28 - You may be able to use `options.image.parentNode` or `options.image.parentNode.parentNode`... Failing that, you may have to create a separate JackUp instance for each upload and use DOM ID conventions (e.g. `id="imageupload-01"`) to differentiate the selectors for each. The repo seems old - numerous PRs from last year that aren't merged. – pherris Apr 18 '16 at 14:07
  • Thanks for the advice! I ended up forking the repo and modifying it to have this functionality. – Kieran E Apr 18 '16 at 19:43