5

Creating app to upload files from local directory, it was a successful for me. Until the part where I start add some styles and features, I've encounter some issues. after creating connection between <input> + <label>.

<input
  id="file"
  type="file"
  name="selectedFile"
  onChange={this.onChange}
/>
<label htmlFor="file">{file}</label>

The goal was to have text render on label tag instead of actual input following onChange event function.

Following ternary conditional with the fileName (from state) and file, they both are set at null as default. Since no file is been selected, the condition is set at false and text "Choose a file" will display on <label>.

render() {
  const { fileName } = this.state;
    let file = null;

    file = fileName 
      ? ( <span>File Selected - {fileName[0]}</span>) 
      : ( <span>Choose a file...</span> );

Anytime user select on <label> painted "Choose a file" text. it triggers onChange function to have file directory pop up at front of browser. Once file is selected from list, the condition becomes true. And should paint actual file name on <label> eg something.jpg...

<label htmlFor="file">{file}</label>

I didn't get any, it wasn't successful for me... However, I've strong suspect it has something to do with this syntax fileName[0]...

<span>File Selected - {fileName[0]}</span>)

I may have it wrong. Any suggestions? Thanks in advance

Here's full syntax...

export default class Form extends Component {
  state = {
     fileName: '',
  };

  onChange = e => {
    switch (e.target.name) {
      case 'fileName':
        this.setState({ fileName: e.target.files[0] });
      break;
      default:
        this.setState({ [e.target.name]: e.target.value });
     }
  };

render(){
   const { fileName } = this.state;
   let file = null;

   file = fileName 
      ? ( <span>File Selected - {fileName[0]}</span>) 
      : ( <span>Choose a file...</span> );

   return(
      <form onSubmit={this.onSubmit}>
         <div>
            <input
               id="file"
               type="file"
               name="selectedFile"
               onChange={this.onChange}
            />
            <label htmlFor="file">{file}</label>
            </div>
        </form>
     );
  }
}
1
  • I will say, I spent a whole lot of time trying to understand this code, and in particular the whole Switch/Case block of code. Why is that there? I didn't understand the input onChange event can return id, type, and name. Why does that matter? Well it would allow you to update numerous elements in a single form with a single onChange() function, one form element per case. This is awesome. Thx for sharing... Commented Mar 6, 2020 at 16:07

1 Answer 1

9

If I understand your question correctly, then it seems you're wanting the <label /> to display the filename of the file that was selected by the user?

This can be achieved by using the .name property on the file asscoaited with the input's change event:

class Form extends React.Component {

  constructor(props) {
    super(props)
    this.state = {
       fileName: '',
    };
  }

  onChange = e => {

    switch (e.target.name) {
      // Updated this
      case 'selectedFile':
        if(e.target.files.length > 0) {
            // Accessed .name from file 
            this.setState({ fileName: e.target.files[0].name });
        }
      break;
      default:
        this.setState({ [e.target.name]: e.target.value });
     }
  };

render(){
   const { fileName } = this.state;
   let file = null;

   file = fileName 
      ? ( <span>File Selected - {fileName}</span>) 
      : ( <span>Choose a file...</span> );

   return(
      <form onSubmit={this.onSubmit}>
         <div>
            <input
               id="file"
               type="file"
               name="selectedFile"
               onChange={ (event) => this.onChange(event) }
            /> { /* Updated this to an arrow function */ }
            <label htmlFor="file">{file}</label>
            </div>
        </form>
     );
  }
}

For a working example, see this jsFiddle - hope that helps!

Sign up to request clarification or add additional context in comments.

4 Comments

Darce Denny, the .name properties is it -- i have updated from {file} into {file.name} eg -> <label htmlFor="file">{file.name}</label>. Its now able to display file name in text.
@sirrus great! - did the jsFiddle I linked to work for you?
Yes, JSFiddle you shared worked for me -- this one got light blub lit in my head on .name property
@sirrus glad to hear that it helped :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.