css - Angular 11 - How to style file input's button with Angular Material - TagMerge
5Angular 11 - How to style file input's button with Angular MaterialAngular 11 - How to style file input's button with Angular Material

Angular 11 - How to style file input's button with Angular Material

Asked 10 months ago
5
5 answers

Finally solved this way (Valid for Angular Material and Bootstrap):

I set 3 separated components:

  1. The button that will be visible (It can be an Angular Material one or a Bootstrap one, as seen below)
  2. The file input
  3. The label that will contain the file name

HTML

<div>
  <button #file class="btn btn-light">Examinate</button>
  <div style="display: inline-block">
      <input #myInput formControlName="file"
      id="file" name="file" (change)="postMethod($event.target.files)" type="file"/>
      <p>{{file}}</p>
  </div>
</div> 

CSS

With CSS I force the input to be overlay the button, and I set the opacity=0 so that the button is visible.

- Button:

float:left; 
position:absolute; 
z-index:-1;

- Input:

opacity: 0; //Not visible
font-size: 0;
//Button dimensions
width: 90px; 
height: 37px; 
float: left; 

- Input (Hover):

cursor: pointer;

- Label:

float: left; 
margin-left: 6px; 
margin-top: 7px;

And this is the final result:

Customized button

Source: link

1

You simply cannot style input type file, the best approach is to create overlay element that will corespond with input type file.

With material you can style pretty much everything that has somthing to do with material, of corse you can add classes from material to custom components but that is not what material is for.

Simple example, you dont want to do that:

<div class="mat-card"></div>

If you can do this:

<mat-card></mat-card>

The same is with input, if you want it to be material style you should create somthing like this:

HTML:

<mat-card class="input-container">
  <button #file mat-flat-button color="primary">Examinar...
      <input multiple (change)="onFileSelected($event)" style="opacity: 0; position:absolute; left:0px; top:0px; width:100%; height:100%;" type="file"/>
  </button>
  {{files|json}}
</mat-card>

TS:

  files: string[] = [];
  onFileSelected(event) {
    if (event.target.files.length > 0) {
      for (let i = 0; i < event.target.files.length; i++) {
        this.files.push(event.target.files[i].name);
        console.log(event.target.files[0].name);
      }
    }
  }

CSS:

.input-container {
  position:relative;
}

Thats a simple example.


But i will still prefer to use some kind of npm package like : https://www.npmjs.com/package/ngx-dropzone

Source: link

-2

In your css/scss/sass:

#fi {
  background-color: pink;
  ...
}

It is not a good approach to style a single button with Angular Material. If you want to style groups, then i recommend to read this: https://material.angular.io/guide/customizing-component-styles

Edit:

Input elements of type file aren't trivial to style.

Here is a plunkr example how it can work:

.fileContainer {
    overflow: hidden;
    position: relative;
    cursor: pointer;
    background-color: pink;
}

.fileContainer [type=file] {
    cursor: inherit;
    display: block;
    font-size: 999px;
    filter: alpha(opacity=0);
    min-height: 100%;
    min-width: 100%;
    opacity: 0;
    position: absolute;
    right: 0;
    text-align: right;
    top: 0;
}
    <label class="fileContainer">
      File upload
      <input type="file"/>
    </label>

Source: link

0

This is my code inside and html page:
<input type="file" ngf-select ng-model="vm.attachment" name="file" accept="application/pdf" ngf-max-size="5MB" ngf-model-invalid="errorFile">
I have already tried with (after my input file hidde):
<md-button id="uploadButton" class="md-raised md-primary"> Choose Files </md-button>

link (scope, element, attrs) {
  const input   = element.find('#fileInput');
  const button = element.find('#uploadButton');

  if (input.length && button.length) {
    button.click((e) => input.click());
  }
}
The ng-model file has a name attribute that you can use to display the filename:
<button ngf-select ng-model="picFile" accept="image/*"> Select Picture</button>
File name: {{picFile.name}}
Make it hidden with display: none
<input type="file" id="input-file" name="file" style="display: none">
Add an onclick event, so a click here will point to our input file.
<md-button onclick="document.querySelector('#input-file').click()" class="md-raised md-primary"> Choose Files </md-button>

Source: link

0

Angular 11, Angular Material 8 and a file input like this:
<div class="form-group">
    <input #myInput type="file" formControlName="fi"
                     id="fi" name="fi" (change)="postMethod($event.target.files)">
</div>
HTML
<div>
  <button #file class="btn btn-light">Examinate</button>
  <div style="display: inline-block">
  <input #myInput formControlName="file"
      id="file" name="file" (change)="postMethod($event.target.files)" type="file"/>
      

{{file}}

</div> </div>
- Button:
float:left; 
position:absolute; 
z-index:-1;
- Input:
opacity: 0; //Not visible
font-size: 0;
//Button dimensions
width: 90px; 
height: 37px; 
float: left;
- Input (Hover):
cursor: pointer;

Source: link

Recent Questions on css

    Programming Languages