Hidden Inputs for Selecting Images in HTML, CSS, and JavaScript
Welcome back to the course. In this video we need to introduce the concept of hidden inputs.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

Right now we have this 'Choose file: no file chosen' thing and we can only choose this. We can't change this text and the style too much, so what we have to do is hide this and create a button that will trigger this input.

I have a w3 schools webpage pulled up (link below) that will explain hidden inputs, plus we'll look at an example.

If we look at this example, we can see that they have to inputs on the page, first name and submit. But if we look at the code itself, you'll see that in the code they have an extra input which says type="hidden".

large

And it says custID. So what they're doing here is they're hiding this but they still want it so that when you submit it still has a customer ID in the input and the Submit. We want the same thing. We want to be able to still have the choose file and be able to upload an image with a button that we can style the way we want.

So right now in our app, if we choose a file we get an error, and if we click on image it doesn't work obviously because we already got an error. That's what we'll figure out after. But for now we just need to figure out how to get that input. So let's go to work.

I'm going to type out what we need in our formFields.js

formFields.js

export class FormImage extends Component {
    render() {
        const { className, title, input, type, imageUrl } = this.props;
        return (
            <div className={`${className} form-image`}>
                <label className='form-image__title'>{title}</label>
                <img
                    className='form-image__image'
                    src={imageUrl} 
                />
                 <input {...input} 
                        type='file'
                        style={{display: 'none'}}
                        id='file'
                        name='file'
                        accepts='image/*'
                        value={undefined}
                        />
                {/* replace button/input goes here */}
            </div>
        )
    }
}

Let's look at this now, and try to upload a new image. Technically we won't see anything because our input is set to display: 'none' but if we comment that out really quickly, we can test it out.

large

And we can select an image now without an error. Now, we don't really want to see this, so uncomment our styles. And if you need some placeholder images can just go to unsplash.com (link below) and get some images. You can get them from anywhere on Unsplash and they're all commercial free.

Anyway what we need to do is write another input and then write some styles over that input, and the reason we're doing it this way is because you can't change the styles of the default input that much. We don't want it to do all that we just want it to say replace like we have in our design.

Let's write another input.

formFields.js

export class FormImage extends Component {
    render() {
        const { className, title, input, type, imageUrl } = this.props;
        return (
            <div className={`${className} form-image`}>
                <label className='form-image__title'>{title}</label>
                <img
                    className='form-image__image'
                    src={imageUrl} 
                />
                <input 
                    className='form-image__replace'
                    type='button'
                    // id=''
                    value='Replace'
                />
                <input {...input} 
                        type='file'
                        style={{display: 'none'}}
                        id='file'
                        name='file'
                        accepts='image/*'
                        value={undefined}
                        />
                {/* replace button/input goes here */}
            </div>
        )
    }
}

Now let's style our button. Open up form-fields.scss and let's add in styles inside of .form-image.

form-fields.scss

.form-image {
    display: flex;
    flex-direction: column;
    &__title {
        @include red-title;
        margin-bottom: 2rem;
    }
    &__image {
        height: 13.7rem;
        width: 16rem;
        border: none;
        background-color: gray;
    }
    &__replace {
        border-radius: 1.6rem;
        border: 1px solid white;
        background-color: white;

        width: 7.4rem;
        height: 2.4rem;

        font-size: 1.4rem;
        line-height: 1.7rem;
        text-align: center;

        color: $color-red-BA;
    }
}

Let's try that out.

large

Okay, we want to place it in the middle, but because we used flex-box there isn't much we can do. So let's take it and put it on a CSS grid.

form-fields.scss

.form-image {
    display: grid;
    grid-template-rows: [title-s] 1fr [title-e image-s] 13.7rem [image-e];
    grid-template-columns: [s] 16rem [e];

    & > * {
        grid-column: s/e;
    }

    &__title {
        @include red-title;
        margin-bottom: 2rem;
        grid-row: title-s/title-e;
    }
    &__image {
        height: 13.7rem;
        width: 16rem;
        border: none;
        background-color: gray;
        grid-row: image-s/image-e;
    }
    &__replace {
        border-radius: 1.6rem;
        border: 1px solid white;
        background-color: white;

        width: 13rem;
        height: 2.4rem;

        font-size: 1.4rem;
        line-height: 1.7rem;
        text-align: center;

        color: $color-red-BA;
        grid-row: image-s/image-e;

        justify-self: center;
        align-self: center;
    }
}

Let's check it out.

large

Now our button's in the right place, and it's the correct width. What we want to do is make this background a little lighter to show that we don't have an image in here, so let's change the background color to background-color: rgb(218,218,218); so that it's a little more subtle.

So now what we need to do is actually hook up the replace button and make it not have the focus color. We want it to have the same animation as our cancel and submit buttons. We can easily throw in an animation by going to the animation styles in form-fields.js and adding the replace button in.

large

Now we just need a hook it up to our hidden input and then get the image and throw it in to our field, and that's really easy. Let's go into formFields.js and on this first import we add some javascript onClick functionality that will actually do something.

Recall that we made our input have an id of file, which we will be referencing.

formFields.js

export class FormImage extends Component {
    render() {
        const { className, title, input, type, imageUrl } = this.props;
        return (
            <div className={`${className} form-image`}>
                <label className='form-image__title'>{title}</label>
                <img
                    className='form-image__image'
                    src={imageUrl} 
                />
                <input
                    className='form-image__replace'
                    type='button'
                    // id=''
                    value='Replace'
                    onClick={
                        () => 
                        document.getElementById('file') ? document.getElementById('file').click() : ''
                    }
                />
                <input {...input} 
                        type='file'
                        style={{display: 'none'}}
                        id='file'
                        name='file'
                        accepts='image/*'
                        value={undefined}
                        />
                {/* replace button/input goes here */}
            </div>
        )
    }
}

That should be good. Let's go and check it out.

large

Now we can select a file, but we still need to actually upload and display it, but we'll work on that in the next video.

Let's commit our code.

git status
git add .
git commit -m "built hidden input and triggered it with an additional button input"

Resources

Code at this stage

Hidden Inputs

Example text editor

Unsplash free images