Search code examples
jqueryarrayssortingfilelist

Sorting FileList data without form inputs


I'm rather new to understanding Javascript, Jquery and PHP. At this point I've spent close to 80 hours working on understanding this one fix and I'm hoping to gain some insight. I'm working with this drag and drop image upload functionality and I need to sort the image items within the FileList object alphanumerically base on their local filename to coincide with the organizational system of a photograph database. I understand that the FileList object is read-only, so I'm assuming this is achieved by adding these items into their own array to sort or compare.

Using this code,

files = e.dataTransfer.files;
newFiles = Array.from(files).map(({name}) => name);
            newFiles.sort();
    console.log(files);
    console.log(newFiles);

I was able to plug the file names into their own array, but I'm not sure how to proceed in comparing this new list of items to their original FileList counterpart for sorting. Output. (Notice how the last three items of the FileList object (files) returns unsorted and newFiles, while sorted, only contains the name data.)

I've tried utilizing this .slice method:

files = [].slice.call(files);

But I can't seem to get the code to fire. The images upload like normal without being sorted.

Same goes for this method:

files = [...e.dataTransfer.files].sort();

I've also attempted using MDN's recommended code:

files.sort((a, b) => a.localeCompare(b, navigator.languages[0] || navigator.language, {numeric: true, ignorePunctuation: true}));

but when I attempt to implement this fix, the console returns that LocaleCompare is not a function.

I have also looked into using Lauri Rooden's natural compare lite and Boris Moore's jsrender, but I don't understand how to go about implementing these plugins.

I started writing an iterator to determine if the two arrays could be compared and sorted as such, and I'm honestly just wondering if I'm on the right track?

for (i=0; i < files.length; i++) {
                      if (files.name[i] === newFiles[i]) {
                 files.splice(i, 1, newFiles[i]) }
             else{i++;
       }

I'm having some issues with an internal server error in the PHP, but if the regular code works with the error in place, could this be something that stands in the way of the FileList object being sorted?

Here's a fiddle with the code. The PHP is commented out below HTML so the code doesn't run at all & the Javascript iframe is split into 3 sections separated by comments. I know this post is long and there are lots of outside sources, but I wanted be sure I was thorough in my explanation. If you have any advice for an aspiring web dev (other than to quit ^_^;), I would greatly appreciate it! Thank you in advance! :)


Solution

  • Thanks for your advice, Gerard! I ended up going with a button to sort the photos via multidimensional array based upon an id once the photos have been dropped in:

    HTML:

    <div class="dontprint">
                <input TYPE="button" onclick="sortFunction()" id="sortButton" class="sortButton" value=" Sort ">
                <input TYPE="button" value=" Shortcut to Print! " onclick="printpage()" />
                <INPUT TYPE="button" onclick="history.go(0)" value=" Clear ">
            </div>
    

    Javascript:

    /* ---------------------------Added to index.html as script tag------------------------ */
    //Called on Button Click
    function sortFunction() {
    
    //Grab images, array them
    const pulled = document.getElementsByClassName("postedImage");
    imageObjects = Array.prototype.slice.call(pulled);
        
    //Store current image ID & Image Source in their own Arrays
    var imageIdArray = [];
    var imageSrcArray = [];
       for (let i = 0; i < imageObjects.length; i++) {
            imageSrcArray.push(imageObjects[i].currentSrc);
            imageIdArray.push(imageObjects[i].id);
            }  
    
    //Adopt a multidimensional Array to associate Image ID with Image Source 
    var multiArray = [];
       for (var i=0; i<imageIdArray.length && i<imageSrcArray.length; i++)
           {multiArray[i] = [imageIdArray[i], imageSrcArray[i]];
                }
    
    //Sort imageObjects (multiArray) alphanumerically
        multiArray.sort(function(a, b) {
            if(a[0] > b[0]) {return 1;}
            if (a[0] < b[0]) {return -1;}
                });
    
    //Sort Image ID's
    imageIdArray.sort();
    
    //Change image name on page
       var currentName = document.getElementsByClassName('name');
       var currentLink = document.getElementsByClassName('postedImage');
           for (let i = 0; i < currentName.length; i++) {
               var newerName = imageIdArray[i];
               currentName[i].innerHTML = newerName;
               }
    
    //Change image on page
    //(Caution: Shuffles image sources when button is clicked more than once. Unsure why.)
       for (let i = 0; i < currentLink.length; i++) {
            var newLink = multiArray[i][1];
            currentLink[i].src = newLink;
            }
    }
    
    /*-----------------------------Update these parts in script.js--------------------------*/
    uploadStarted:function(i, file, len){
                createImage(file);
                $.data(file).find('.name').text(file.name);
                //Give each file an ID representative of its name
                document.getElementById('sortId').id = file.name;
            },
    
            progressUpdated: function(i, file, progress) {
                $.data(file).find('.progress').width(progress);
                
            }
             
        });
    
    //Gave the image an ID and a Class for easy grabbing
        var template = '<div class="preview">'+
                            '<span class="imageHolder">'+
                                '<img / id="sortId" class="postedImage">'+
                                '<span class="uploaded"></span>'+
                            '</span>'+
                            
                                '<div class="name"></div>'+
                                
                            '</div>'+
                        '</div>';
    };
    

    In the event that someone knows how to fix an issue regarding sorting multidimensional arrays, I don't wish to shuffle the data url's with every button press. The arrays update with different image urls from the page any time the sort button is pressed. I'm also interested in knowing if Tif files could be supported by something like this, but I'll keep diving for info!