1

I'm trying to make a custom <input type="file"> button for a system, but the browser always gives me errors and when it doesn't, the button doesn't work as intended. I suspect I'm not using the escape operators correctly. Either that, or my UNIX environment is interfering with the correct functioning.

I've tried this in multiple ways, and have in mind the error is always the same: "Uncaught SyntaxError: Invalid or unexpected token".

fileName = e.target.value.split("\\").pop(); Throws out the error. This should be the correct code as it's what I'm trying to do;

fileName = e.target.value.split("\\\\").pop(); Doesn't throw an error, but makes the source code look like fileName = e.target.value.split("\\").pop();. This doesn't work as intended as what I want is only one "\" backslash.

Code is as follows:

<input type="file" name="file" id="file" class="inputfile" data-multiple-caption="{count} files selected" multiple />
<label for="file"><span>Choose a file</span></label>
.inputfile {
  width: 0.1px;
  height: 0.1px;
  opacity: 0;
  overflow: hidden;
  position: absolute;
  z-index: -1;
}

.inputfile + label {
  font-size: 1.25em;
  font-weight: 700;
  color: white;
  background-color: black;
  display: inline-block;
  cursor: pointer;
}

.inputfile:focus + label,
.inputfile + label:hover {
  background-color: red;
}

.inputfile:focus + label {
  outline: 1px dotted #000;
  outline: -webkit-focus-ring-color auto 5px;
}
var inputs = document.querySelectorAll('.inputfile');
Array.prototype.forEach.call(inputs, function(input) {
      var label = input.nextElementSibling,
        labelVal = label.innerHTML;

      input.addEventListener('change', function(e) {
          var fileName = '';
          if (this.files && this.files.length > 1)
            fileName = (this.getAttribute('data-multiple-caption') || '').replace('{count}', this.files.length);
          else
            fileName = e.target.value.split("\\").pop();

              if (fileName)
                label.querySelector('span').innerHTML = fileName;
              else
                label.innerHTML = fileName ? fileName : labelVal;
            });
      });

JSFiddle

What I'm trying to do is make the custom button change its innerHtml to the name of the file the user selected.

The JSFiddle works as intended with only two "\" backslashes. This is why I think UNIX is a suspect - "\" is also a special character, meaning a single-character quote. All web code runs inside this UNIX environment - we compile everything using it.

Any ideas or alternatives?

DootyBooty
  • 67
  • 1
  • 9

4 Answers4

1

Try change to '\\\' on some systems it works.

DuhVir
  • 447
  • 1
  • 4
  • 15
  • `fileName = e.target.value.split("\\\").pop();` makes source code look like `fileName = e.target.value.split("\").pop();` but still throws out the error. I really hoped this would work. – DootyBooty Sep 27 '19 at 11:49
  • Did you look at https://stackoverflow.com/questions/8618374/escaping-backslash-in-string-javascript – DuhVir Sep 27 '19 at 11:51
  • I have, but none of the answers, or comments, have helped me. My JSFiddle works as intended, just not in production code. – DootyBooty Sep 27 '19 at 11:59
  • Yeah, i'm searching this as well. Strange bug. Four of slashes should work. – DuhVir Sep 27 '19 at 12:03
  • Yes, I agree. But somehow, it doesn't, and it's making me crazy. – DootyBooty Sep 27 '19 at 12:08
1

Use / instead of \, as \ is generally used for escape characters...

or try using \\\ this is UNC (network pathing path/file name)

do a replace \ with /

Dean Van Greunen
  • 5,060
  • 2
  • 14
  • 28
1

I've been able to solve this by moving javascript out of the unix environment's reach and completely re-writing the function, this time using regular expressions to replace the file path string:

<input type="file" name="file" id="file" class="inputfile" onchange='troca()' />
<label for="file" id='label'><span>Choose a file</span></label>
function troca(){
    var file = document.getElementById("file");
    var nomeArq;
    var fullPath = file.value;
    if (fullPath) {
       var startIndex = fullPath.indexOf('\\\\') >= 0 ? fullPath.lastIndexOf('\\\\') : fullPath.lastIndexOf('/');
       var filename = fullPath.substring(startIndex);
       if (filename.indexOf('\\\\') === 0 || filename.indexOf('/') === 0) {
           filename = filename.substring(1);
       }
       nomeArq = filename;
    } else {
       nomeArq = 'image.jpg';
    }
    nomeArq = nomeArq.replace(/.*[\/\\]/, '');
    var label = document.getElementById('label');
    label.innerHTML = nomeArq;
}

Ironically, JSFiddling this doesn't work - it throws out "Uncaught ReferenceError: troca is not defined at HTMLInputElement.onchange". But hey, as long as it works on production code, right?

Thanks for everyone's help.

DootyBooty
  • 67
  • 1
  • 9
1

You should use "\/" with UNIX file system.

Thevs
  • 3,189
  • 2
  • 20
  • 32