Can I replace the button displayed by Blazor's InputFile component with another element?

8.3k views Asked by At

I am using the element to upload image files to my hosted Blazor WASM site. The component renders a button with the words "Choose Files" on it.

I would like to replace this button with an image (or my own text, or anything else). I have tried using CSS to set a background image to the URL of an image I would want to use, and set the background-color of the button to "transparent", but this does not seem to change anything.

2

There are 2 answers

4
Jason D On BEST ANSWER

The source code for this component can be found here: https://github.com/SteveSandersonMS/BlazorInputFile

I studied the code and found that this component is built using the standard Blazor input type.

<input type=file>

Steve shows a way to override the default functionality and style of the button using CSS.

Here is an example I created based on what I found:

<style>
    .file-input-zone {
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: blue;
        color: white;
        cursor: pointer;
        position: relative;
        width: 120px;
        height: 30px;
    }

        .file-input-zone:hover {
            background-color: lightblue;
        }

        .file-input-zone input[type=file] {
            position: absolute;
            width: 100%;
            height: 100%;
            opacity: 0;
            cursor: pointer;
        }
</style>

<div class="file-input-zone">
    <InputFile />
    Get me a file!
</div>

It will give you a button that looks like this:

enter image description here

You might pick up more tips by studying his source code further.

0
Jelgab On

Starting with the solution proposed by Jason D, I did it like this and the pointer shows as expected (cursor : pointer) :

    <style>
    .file-input-zone {
        display                  : flex;
        -ms-align-items          : center;
        -o-align-items           : center;
        -webkit-align-items      : center;
        align-items              : center;
        -o-justify-content       : center;
        -webkit-justify-content  : center;
        justify-content          : center;
        background-color         : orange;
        color                    : white;
        cursor                   : pointer;
        position                 : relative;
    }

    .file-input-zone :hover {
            background-color : lightblue;
        }

        .file-input-zone input[ type = file ] {
            position : absolute;
            width    : 100%;
            height   : 100%;
            opacity  : 0;
            cursor   : pointer;
        }
</style>

<button class = "btn file-input-zone">
    <InputFile />
    
    <i class="oi oi-cloud-upload"></i>

    <span class = "ms-3">
        Select your file(s)
    </span>
</button >

In my case, I also wanted a message for the case where no files have been selected yet (and to have a reference to the selected files). With that addition, I made it like this:

    <style>
    .file-input-zone {
        display                 : flex;
        -ms-align-items         : center;
        -o-align-items          : center;
        -webkit-align-items     : center;
        align-items             : center;
        -o-justify-content      : center;
        -webkit-justify-content : center;
        justify-content         : center;
        background-color        : orange;
        color                   : white;
        cursor                  : pointer;
        position                : relative;
    }

    .file-input-zone :hover {
            background-color : lightblue;
        }

        .file-input-zone input[ type = file ] {
            position : absolute;
            width    : 100%;
            height   : 100%;
            opacity  : 0;
            cursor   : pointer;
        }
</style>

< button class = "btn file-input-zone">
    <InputFile
        id       = "seleccionarArchivoInput"
        OnChange = "@ActualizarListaSeleccionada" />
    
    <i class="oi oi-cloud-upload"></i>

    <span class = "ms-3">
        Seleccionar Archivo
    </span>
</ button>

    <div class = "ms-4" style = "@( this._listaArchivosSeleccionados.Count == 0 ? "" : "visibility: hidden;" )">
        <span class = "text-secondary small" >
            (No files selected yet)
        </span>
    </div>

Code:

    private List<IBrowserFile> _listaArchivosSeleccionados = new();

    private async Task ActualizarListaSeleccionada ( InputFileChangeEventArgs datosEvento )
{
    this._listaArchivosSeleccionados.Clear();

    IReadOnlyList<IBrowserFile> archivosSeleccionados = datosEvento.GetMultipleFiles();

    foreach ( IBrowserFile archivoItem in archivosSeleccionados )
    {
        this._listaArchivosSeleccionados.Add( archivoItem );
    }
}

I didn't use "@if( this._listaArchivosSeleccionados == 0 )" and then the message block inside, to avoid UI disruption (elements below moving up and down). For the same reason, I didn't use "display: none;".

I used Blazor WebAssembly with .Net 6 and Bootstrap Css ver 5.1