1

I have a web page that contains HTML as,

<form action="/action_page.php">
     Select a Text File: <input type="file" onchange='ReadFile(this)'>
</form>

<input type="button" value ="Click" onclick="Execute();"/>

Now the JS code is,

var data = {};

function ReadFile(that) {
    if (that.files && that.files[0]) {
         var reader = new FileReader();
         reader.onload = function (e) {
             var out = e.targe.result;
              data = ParseAsMAP(out);
          };
          reader.readAsText(that.files[0]);
      }  
}

function Execute () {
   var models = data;

    $.ajax ({
            type : "POST",
            url : "myURLHere.svc/MyFunction"
            data : JSON.stringify({ModelsParam: Models}),
            contentType : "application/json",
            success : ServiceSuccess,
            error : ServiceFailed
            });
}

function ParseAsMAP(data) {
    //This function creates a map as shown below.
    // map["elem-1"] = "Nuble"
    // map["elem-2"] = "Flex"
    // map["elem-3"] = "Ricko"
    // map["elem-4"] = "Musk"
    // map["elem-5"] = "Nappy"
}

The above code works as expected. Based on user selection of a txt file, it will get the contents of the file and convert that to map with key & value pairs and store it in a var called data. This is later called in Execute function to pass to a Web Service function.

What I want to achieve now?

<form action="/action_page.php">
    Select a Text File: <input type="file" onchange='ReadFile(this)' multiple>
</form>

<input type="button" value ="Click" onclick="Execute();"/>

I want the user to be able to select multiple txt files in the input and then the ReadFile function should read each of these txt files and create a corresponding map of it and store it somewhere, am thinking possibly in an array of map or something like that. So that When user presses the click button, each of the map array elements can be read and then passed as JSON to web service.

Any ideas how this can be achieved? Am basically struggling with the part where all the selected txt files are converted to a map and then to store it securely, so that it can be accessed later when user presses the click button.

UPDATE:

I tried below, but that doesn't work. Basically in Execute function, the var dataEx is coming as empty.

var data = {};
var dataEx = {};
var totalFiles = 0;

    function ReadFile(that) {

       for (var i = 0; i < that.files.length; i++) {

        if (that.files && that.files[i]) {
             var reader = new FileReader();
             reader.onload = function (e) {
                 var out = e.targe.result;
                  data = ParseAsMAP(out);
                  dataEx[i] = data;
                  totalFiles++;
              };
              reader.readAsText(that.files[i]);
          }  
       }
    }

    function Execute () {

    for (var i = 0; i < totalFiles; i++) {
       var models = dataEx[i];

        $.ajax ({
                type : "POST",
                url : "myURLHere.svc/MyFunction"
                data : JSON.stringify({ModelsParam: Models}),
                contentType : "application/json",
                success : ServiceSuccess,
                error : ServiceFailed
                });
        }
    }
donguy76
  • 610
  • 3
  • 12
  • 33
  • Not sure what main issue is. You have file name for each to use as a key. Can use that as object key or as identifier property in array of objects – charlietfl Apr 03 '19 at 00:50
  • @charlietfl - the contents from text file are used as key & value. The issue are, 1. how to get all files selected by the user in the input tag? 2. Get contents of all those files and parse it and add to a map array? – donguy76 Apr 03 '19 at 00:54
  • When change occurs on a multiple input can iterate element.files. Then as you iterate and read each one create object and push to array or main object – charlietfl Apr 03 '19 at 00:57
  • @charlietfl - I have updated answer with an update section. – donguy76 Apr 03 '19 at 01:22
  • Fallen in the infamous loop closure trap. Use `let` instead of `var` ... see [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – charlietfl Apr 03 '19 at 01:26
  • `onload` is asynchronous so loop will have probably completed when it occurs and `i` will be maxed out – charlietfl Apr 03 '19 at 01:27

1 Answers1

0

In the ReadFile function change the below line -

dataEx[i] = data;

to

dataEx[totalFiles++] = data;

also get rid of -

totalFiles++