0

I'm trying to find a particular element that's returned from Uppy, a file uploading library. But for some reason the selector I've put together keeps coming up empty.

Here's what it looks like:

Object.keys(updatedFiles).forEach(fileId => {
  let $files = $("#uppy-form .uppy-Dashboard-files").children('li');

  $files =>

  0:li#uppy_uppy-screenshot/from/2019/07/10/06/34/34/png-10-10-1d-1d-10-1d-1d-1e-image/png-25444-1562758476913.uppy-u-reset.uppy-DashboardItem
  1:li#uppy_uppy-screenshot/from/2019/07/22/04/17/30/png-10-10-1d-1d-10-1d-1d-1e-image/png-9572-1563787053498.uppy-u-reset.uppy-DashboardItem
  2:li#uppy_uppy-screenshot/from/2019/07/22/04/17/46/png-10-10-1d-1d-10-1d-1d-1e-image/png-130128-1563787069142.uppy-u-reset.uppy-DashboardItem
  3:li#uppy_uppy-screenshot/from/2019/07/22/04/18/01/png-10-10-1d-1d-10-1d-1d-1e-image/png-130002-1563787085262.uppy-u-reset.uppy-DashboardItem
  4:li#uppy_uppy-screenshot/from/2019/07/22/04/24/23/png-10-10-1d-1d-10-1d-1d-1e-image/png-29323-1563787465594.uppy-u-reset.uppy-DashboardItem
  5:li#uppy_uppy-screenshot/from/2019/07/22/04/29/01/png-10-10-1d-1d-10-1d-1d-1e-image/png-41412-1563787753290.uppy-u-reset.uppy-DashboardItem
  6:li#uppy_uppy-screenshot/from/2019/10/14/17/18/34/png-10-10-1d-1d-10-1d-1d-1e-image/png-813933-1571091517693.uppy-u-reset.uppy-DashboardItem
  7:li#uppy_uppy-screenshot/from/2019/10/14/17/18/47/png-10-10-1d-1d-10-1d-1d-1e-image/png-1121037-1571091530669.uppy-u-reset.uppy-DashboardItem
  8:li#uppy_uppy-screenshot/from/2019/10/14/17/22/35/png-10-10-1d-1d-10-1d-1d-1e-image/png-1108169-1571091758565.uppy-u-reset.uppy-DashboardItem
  9:li#uppy_uppy-screenshot/from/2019/10/18/03/40/01/png-10-10-1d-1d-10-1d-1d-1e-image/png-70136-1571388003926.uppy-u-reset.uppy-DashboardItem
  10:li#uppy_uppy-screenshot/from/2019/10/18/03/40/43/png-10-10-1d-1d-10-1d-1d-1e-image/png-77492-1571388045454.uppy-u-reset.uppy-DashboardItem

  ...
}

And here are the selector strings I've tried. In this instance, I'm attempting to select the first list item by its fileId:

let test1 = "#uppy_" + fileId.replace(/([$%&()*+,./:;<=>?@\[\\\]^\{|}~])/g, '\\$1');
=> "#uppy-screenshot\/from\/2019\/07\/10\/06\/34\/34\/png-10-10-1d-1d-10-1d-1d-1e-image\/png-25444-1562758476913"

let test2 = "#uppy_" + fileId.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g, "\\\\$&")
=> "#uppy-screenshot\\/from\\/2019\\/07\\/10\\/06\\/34\\/34\\/png-10-10-1d-1d-10-1d-1d-1e-image\\/png-25444-1562758476913"

let test3 = "#uppy_" + fileId.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g, "\\$&")
=> "#uppy-screenshot\/from\/2019\/07\/10\/06\/34\/34\/png-10-10-1d-1d-10-1d-1d-1e-image\/png-25444-1562758476913"
$files.find(test1) => 

jQuery.fn.init [prevObject: jQuery.fn.init(11), context: document, selector: "#uppy-screenshot\/from\/2019\/07\/10\/06\/34\/34\/…-1d-1d-10-1d-1d-1e-image\/png-25444-1562758476913"]
context:document
length:0

Evidently it doesn't like doubles for forward slashes, so test2 is out...

$files.find(test2) =>

Uncaught Error: Syntax error, unrecognized expression: #uppy-screenshot\\/from\\/2019\\/07\\/10\\/06\\/34\\/34\\/png-10-10-1d-1d-10-1d-1d-1e-image\\/png-25444-1562758476913
$files.find(test3) => 

jQuery.fn.init [prevObject: jQuery.fn.init(11), context: document, selector: "#uppy-screenshot\/from\/2019\/07\/10\/06\/34\/34\/…-1d-1d-10-1d-1d-1e-image\/png-25444-1562758476913"]
context:document
length:0

And what's throwing me for a loop is, if I go into the list item itself, it clearly states the id matches what I'm attempting to select with test1 and test3 (albeit, without the escaped characters)

$files.first()

jQuery.fn.init [li#uppy_uppy-screenshot/from/2019/07/10/06/34/34/png-10-10-1d-1d-10-1d-1d-1e-image/png-25444-1562758…, prevObject: jQuery.fn.init(11), context: document]
0:li#uppy_uppy-screenshot/from/2019/07/10/06/34/34/png-10-10-1d-1d-10-1d-1d-1e-image/png-25444-1562758476913.uppy-u-reset.uppy-DashboardItem

...

id:"uppy_uppy-screenshot/from/2019/07/10/06/34/34/png-10-10-1d-1d-10-1d-1d-1e-image/png-25444-1562758476913"

Any ideas? Is it something that's been right under my nose this whole time?

Spectator6
  • 363
  • 1
  • 5
  • 19
  • What are you trying to accomplish. I would use `.each()` if you're looping. Which are you trying to select or what are you trying to do with it? – Twisty Apr 09 '20 at 00:13
  • Hello @Twisty! Yes, I'm using .forEach to iterate through the `updatedFiles`. I've updated the OP with that included. What I'm trying to do is add some meta data into each Uppy fileId that corresponds with the order in which the files were dropped/added into the form. Uppy works asynchronously, so the order in which things actually hit the database and are saved usually causes things to be uploaded out of order. So I'm trying to find a way to preserve/record the order the files were initially added. – Spectator6 Apr 09 '20 at 00:23

2 Answers2

1

The only characters in fileId that need to be escaped are / and .. This appears to work for me.

let test1 = fileId.replace(/[\/.]/g, "\\$&");

And since you're searching for elements in the top-level $files collection, you should be using .filter(), not .find(). The latter only searches descendants, not the top-level elements.

$files.filter(test1)

You could use .find() this way:

$("#uppy-form .uppy-Dashboard-files").find(test1)
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • *smacks forehead* DOH! You're right @Barmar! I should have been `.filter()`ing And yes, you're right about only needing to escape the `/` Thank you for setting me straight on both! *high-fives* – Spectator6 Apr 09 '20 at 00:47
1

Consider the following.

$("#uppy-form .uppy-Dashboard-files > li").each(function(i, el){
  $(el).attr("data-up-id", i);
});

This will iterate each element and perform the needed action.

Twisty
  • 30,304
  • 2
  • 26
  • 45