Customize mat-selection-list - html

I have a list of elements. Every element is displayed on a row. How can I display four elements on a row?
My code is:
<div class="form" id="skillsList">
<mat-label>Choose skills</mat-label>
<mat-selection-list #skills>
<mat-list-option *ngFor="let skill of listOfSkills">
{{skill}}
</mat-list-option>
</mat-selection-list>
</div>

It looks like mat-list-option has display: block. So you can override that to get them to display however you want. For example:
<mat-list-option ngFor="let skill of listOfSkills"
style="display:inline-block; text-align:center;">
{{skill}}
</mat-list-option>
or using CSS:
mat-list-option {
display:inline-block !important;
text-align: center;
}

This is what you're going to want to do if you want exactly 4 per line as you had originally stated.
<div class="form" id="skillsList">
<mat-label>Choose skills</mat-label>
<mat-selection-list style="display: flex; flex-wrap: wrap" #skills>
<mat-list-option *ngFor="let skill of listOfSkills; let i = index" [attr.data-index]="i">
{{skill}}
<div *ngIf="i%4" style="flex-basis:100%;"></div>
</mat-list-option>
</mat-selection-list>
</div>
All you're doing is adding a modulo operator that triggers after every fourth item to break the line. The flex-wrap and display flex are to allow you to put flex basis on the div with the *ngIf

Related

Angular - How to remove padding-right from mat-list-text?

I am trying to add a button to a mat-list-item. This is my current HTML template code:
<mat-selection-list
[multiple]="false"
[class.selected]="currentItem"
formControlName="itemListControl"
>
<mat-list-option
*ngFor="let item of items"
[value]="item.id"
>
<div style="display: flex; justify-content: space-between; align-items: center">
<div style="display: flex; align-items: center">
{{ item.name }}
</div>
<button mat-icon-button>
<mat-icon>edit</mat-icon>
</button>
</div>
</mat-list-option>
</mat-selection-list>
When I inspect the site in my browser, I can see that there is a 16px padding which moves the button to the left inside the list item:
I already tried removing it by adding this to my scss file for the component:
.mat-list-item {
padding-right: 0 !important;
}
For some reason, this does not have any effect. It seems like this is not even applied at all to the element. What am I doing wrong and how can I get rid of this padding (without causing any potentially bad side effects)?
Please use like below. It would work.
.mat-list-text {
padding-right: 0 !important;
}
Thanks!
Use the whole selector(instead of just .mat-list-text, copy all the selector part of the css highlighted in the image above) to remove the the padding, angular material is very hard to modify. Dont forget to add the !important aswell. I had to do this previously. I hope it will work for you aswell.

How to remove the last empty space in css flex

I am using css flex on my project but it adds an empty box at the end of the items. How do I remove it?
My code
<div className="form-horizontal">
<div className="form-control">
<label htmlFor="">Name</label>
<input type="text" name="" id="" />
</div>
<div className="form-control">
<label htmlFor="">Email</label>
<input type="text" name="" id="" />
</div>
</div>
CSS
.form-horizontal{
display: flex;
width: 100%;
white-space: pre-wrap;
flex-wrap: wrap;
}
Try this. This should solve your problem
.form-control {
width: 100%;
}
Well the display: flex; will make your child elements inside them have a display of inline, so they will stick to each other, unless you separate them with justify-content or align-items.
Now if you have 2 elements (the child's elements) which their combined width is still less than the width of container box (parent element), well the rest of width missing is still there, just that it's not being used! (Because you need to maintain the aspect/design of the page)
But that doesn't means that you have a new box in your flex-blox. It's just free space, not being used.
Graphic explanation of the problem
Now you can still use that free space there with the justify-content or align items property, or you can add a new child element to the flex-blox!

Arrange <mat-list-item> objects in <mat-list> automatically

The sample code:
<div>
<mat-list fxLayout="row" dense>
<mat-list-item *ngFor="let label of labelsList"> <!-- just an array of strings -->
<button mat-button>
<mat-icon>cloud</mat-icon>
{{label}}
</button>
</mat-list-item>
</mat-list>
</div>
The result:
When I resize the browser window:
What I need: the buttons that don't "have room" to simply go on the next row.
How do I achieve this? I tried several combinations of CSS classes, properties, etc... nothing worked.
LATER EDIT: here's a complete reproducible example: https://angular-svt72k.stackblitz.io
mat-list-item is by default using the full width of its container and setting each item as display: block. To overrule this, you need to override the default Angular (Material) styling that comes with <mat-list>.
Setting .mat-list-test to display: flex and adding flex-flow: row wrap will make it go to the next line when there's not enough space available. Next to that, as said, the .mat-list-item styling is taking the full width. You can override it by setting display: initial and width: auto. Read more about flexbox at MDN.
CSS
.mat-list-test {
display: flex;
flex-flow: row wrap;
}
.mat-list-base .mat-list-item.mat-list-item-test {
display: initial;
width: auto;
}
See this example on StackBlitz to show the outcome.

How to distribute and resize elements using fxFlex?

The goal
I'm trying to write my own search bar for mat-table. The search bar consists only of inputs - one for each column. I placed it right above the table and now I'm trying to distribute them equally with the help of flex-layout, like the table does with its columns.
The problem
But the problem is that those inputs don't listen to me and don't shrink but they overflow outside the wrapping element. I need them to shrink equally to fit in the wrapping section but I don't know how to do this.
The code
Here is the sample of the code I wrote so far:
<section fxLayout="row" class="search-table" style="overflow-x: auto;">
<mat-form-field *ngFor="let item of items" fxFlex>
<input matInput type="text" placeholder="sample text" fxFlex>
</mat-form-field>
</section>
.search-table {
border: 1px solid black;
}
EDIT
Here's stackblitz example of my problem. Flex-layout don't work there for some reason so I added flex to css.
The problem comes from the .mat-form-field-infix class which sets a width of 180px on the input.
Solution: Add the class below to the styles.css file
.mat-form-field-infix {
width: auto!important;
}
StackBlitz: here

Is there a way I can add a class to a row in an ng-repeat when a cell is hovered over?

If I have HTML like this:
<div style="display: table">
<div style="display: table-row; border-collapse: separate; border-spacing: 2px;"
ng-class="{clicked: row.current == true}"
ng-click="home.rowClicked($index)"
ng-dblclick="ctrl.rowDoubleClicked(row)"
ng-repeat="row in home.grid.data">
<div style="display: table-cell">{{ row.abc }}</div>
<div style="display: table-cell">{{ row.def }}</div>
</div>
</div>
Is there a way that I can change the class of the row when a user hovers over either of the two divs? Note that I just added the inline CSS so people could see that I was using display: table-row.
The reason I would like to do this is because I want to change the background color of all the cells in a row as the user hovers over just one cell in that row. If there is another way to do this then I would welcome any suggestions.
It is possible to add class for example via jQuery. But in your case just add your table row any class eg. row and add this line in your .css file:
.row:hover {backgroud-color: yellow;}