0

I'm trying to have the filename of a chosen file appear in the body of a file picker. This is an Asp.Net Core view. I have the following file input:

<div class="form-group file-upload-wrapper">
    <input id="the-file" type="file" name="name" onchange="handleFile()" />    
    <label class="custom-file-label" for="the-file">Choose a file</label>                        
</div>

I want the filename to appear in place of the Choose a file text.

My JS looks like this:

@section Scripts {
<script language="javascript"> 

    function handleFile(file) {
        console.log(file);         
    }       

As it currently stands, I'm getting an error:

ReferenceError: handleFile is not defined

My assumption is that handleFile needs to look something like this:

document.getElementById("the-file").title = file.files[0].name;

Am I on the right lines with this, and why am I getting the above error?

JSFiddle here

4 Answers4

0

You can use event handler for that. Remove onchange attribute form that element and use below:

document.getElementById('the-file')
  .addEventListener('change', (e) => {
    handleFile(e)
  });

function handleFile(file) {
  console.log(file.target.value);
}

Here is the snippet:

document.getElementById('the-file')
  .addEventListener('change', (e) => {
    handleFile(e)
  });

function handleFile(file) {
  console.log(file.target.value);
  log(file.target.value);
}

function log(msg) {
 document.getElementById('result').innerText = msg;
}
<div class="form-group file-upload-wrapper">
  <input id="the-file" type="file" name="name" />
  <label class="custom-file-label" for="the-file">Choose a file</label>
</div>

<pre id="result"></pre>
0

From the documentation , you need to modify the code like below:

<div class="custom-file">
    <input type="file" class="custom-file-input" id="the-file" name="name"/>
    <label class="custom-file-label" for="the-file">Choose a file</label>
</div>

@section Scripts
{
  <script>
     document.getElementById('the-file').addEventListener('change', function (e) {
        var fileName = document.getElementById("the-file").files[0].name;
        var nextSibling = e.target.nextElementSibling
         nextSibling.innerText = fileName
     }); 
  </script>

}

You could refer to Bootstrap 4 File Input for more details.

Xueli Chen
  • 11,987
  • 3
  • 25
  • 36
0

why am I getting the above error?

The code within the fiddle is different from the OP. I'll take the code on Fiddle as an example.

  1. First of all, note that you added a bootstrp.min.js reference, however, you didn't add a jquery for it. Because bootstrap.min.js has a dependency on jquery, it throws before the handleFile() function is defined.

    That's why we could see an error of util.js:56 Uncaught TypeError: Cannot read property 'fn' of undefined at util.js:56 in the console. To fix that issue, either add a jquery.min.js before the bootstrap.min.js:

    enter image description here

    Or change the loading behavior of your js like:

    enter image description here

  2. And then you mix up the js statement with a function reference by :

    <input id="the-file" type="file" name="name" onchange="this.handleFile" /> 
    

    Note you should put a js statement instead of a single function reference within onchange="...". That being said, you could fix it by:

    <input id="the-file" type="file" name="name" onchange="handleFile(event.target.files)" /> 
    
  3. Your handleFile() uses a this that points to the window at runtime. As a result, it throws when invoked. Since we have passed the files as the arguments, change the function as below:

     function handleFile(files) {       
        console.log(files);         
    }       
    
itminus
  • 23,772
  • 2
  • 53
  • 88
-1

<div class="form-group file-upload-wrapper">
  <script>
    const handleFile = file => {
      console.log(file);         
     } 
    </script>
    
    <input id="the-file" type="file" name="name" value ="file" onchange="handleFile(value)" />    
    <label class="custom-file-label" for="the-file">Choose a file</label>                        
</div>
Vishal
  • 1