Reputation: 2016
I have seen a lot of questions about this but none of them solved my issue.
What I have:
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>
What I need:
I need to customize this button's color, text and size.
How can I customize it?
Upvotes: 4
Views: 11237
Reputation: 740
You could change the style using css.
input[type=file]::file-selector-button {
cursor: pointer;
border: 0;
padding: 8px;
background-color: rgb(91, 105, 194);
border-radius: 8px;
color: white;
}
input[type=file]::file-selector-button:hover {
background-color: rgb(54, 61, 115);
}
<div>
<input
type="file"
[accept]="'.csv'"
multiple/>
<label>Select file</label>
</div>
Upvotes: 1
Reputation: 2016
Finally solved this way (Valid for Angular Material and Bootstrap):
I set 3 separated components:
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:
Upvotes: 6
Reputation: 278
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
Upvotes: 2
Reputation: 601
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
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>
Upvotes: -2