How to move Angular Component throughout the page - html

I'm pretty new to the Angular framework and I'm making an app with a bunch of Angular components. Right now I'm trying to do a Search Page where I have an input for searching characters, and then after you've picked one of the lists it will show the character's stats card.
So what I want is to move both the search input and the card which appears after selecting a character in the middle of the screen, instead of having them both positioned at the left side of the screen.
Here is a picture that shows what I want to accomplish:
Here is my code right now (might be a bit messy but I just started like a month and a half ago learning JS, HTML, and CSS):
Search Component Template =>
<div fxLayot="column">
<div style="background: #4c4848" class="detailContainer">
<h1>Buscador de Personajes:</h1>
</div>
<br><br>
<div fxLayout="row">
<div fxLayot="column">
<form class="autocomplete-form">
<mat-form-field class="enable-full-width" style="background: #4c4848; border-radius: 5px; border: 4px solid black;">
<mat-label>Nombre</mat-label>
<input type="text" placeholder="Pick one" aria-label="Number" matInput [formControl]="searchInput"
[matAutocomplete]="auto" (input)="search()">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" (optionSelected)="selectedOption($event)" [displayWith]="checkValue">
<mat-option *ngFor="let character of suggestions" [value]="character">
{{character.name}}
</mat-option>
<mat-option *ngIf="characters.length === 0 && searchInput.value.trim().length>0" value="">
ERROR 404 - No se encontró nada con el término "{{searchInput.value}}".
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
</div>
<span class="middler"></span>
<div *ngIf="selectedCharacter" fxLayout="column" style="width: 400px;">
<app-character-card [character]="selectedCharacter"></app-character-card>
</div>
(Don't know why they appear in distinct code blocks sorry for that)
Search Component CSS =>
.autocomplete-form {
min-width: 500px;
max-width: 500px;
width: 100%;
}
.enable-full-width {
width: 500px;
}
.detailContainer {
text-align: center;
justify-content: center;
align-items: center;
border: 5px solid black;
border-radius: 7px;
padding-top: 10px;
}
.centered {
text-align: center;
justify-content: center;
align-items: center;
}
Character Card Component Template =>
<mat-card>
<mat-card-header>
<div mat-card-avatar class="header-image"></div>
<mat-card-title class="charname">{{character.name}}</mat-card-title>
<mat-card-subtitle class="charage">{{character.age}}</mat-card-subtitle>
</mat-card-header>
<img mat-card-image [src]="character | image">
<mat-card-content>
<mat-card-title>{{character.race}}</mat-card-title>
<mat-card-subtitle>{{character.class}}</mat-card-subtitle>
<hr>
<div fxLayout="column" fxLayoutAlign="center" fxLayoutGap="10px">
<div fxLayout="row" fxLayoutGap="30px">
<div fxFlex="50">
<strong>Fuerza: </strong>{{character.strength}}
</div>
<div fxFlex="50">
<strong>Inteligencia: </strong>{{character.intelligence}}
</div>
</div>
<div fxLayout="row" fxLayoutGap="30px">
<div fxFlex="50">
<strong>Destreza: </strong>{{character.dexterity}}
</div>
<div fxFlex="50">
<strong>Carisma: </strong>{{character.charisma}}
</div>
</div>
<div fxLayout="row" fxLayoutGap="30px">
<div fxFlex="50">
<strong>Constitución: </strong>{{character.constitution}}
</div>
<div fxFlex="50">
<strong>Sabiduría: </strong>{{character.wisdom}}
</div>
</div>
</div>
<hr>
</mat-card-content>
<mat-card-actions>
<button mat-button color="warn" [routerLink]="['..', character.characterId]">
Leer Más
</button>
<button mat-button color="info" [routerLink]="['../../editcharacter', character.characterId]">
Editar
</button>
<a mat-button color="info" [routerLink]="['../..', character.userId, character.characterId, 'inventory']">
Inventario
</a>
</mat-card-actions>
Character Card Component CSS =>
mat-card {
margin-top: 20px;
}
img {
height: 500px;
}
.charname, .charage {
margin-top: 5px;
}
.header-image {
background-image: url('././assets/d20.png');
background-size: cover;
}
I really just need them positioned in the center. I also have this problem in my ItemSearchComponent, but I suppose If I can't answer this, I could easily extrapolate to the other one. Thanks!
If you need any more code just ask.

To achieve that put the search and the results-of-the-search on the same DIV, in "row mode" one below the other, then center that DIV horizontally with many methods out there I usually go for display:flex
<div class="head">
buscador de personajes
</div>
<div class="searchContainer">
<div class="searchVertical">
<div class="border">your<br>SearchBox</div>
<div class="border">search<br>Resuts</div>
</div>
</div>
CSS
.searchContainer {
width: 100% ;
display: flex ;
justify-content: center;
}
.searchVertical {
display:flex ;
flex-direction: column;
}
.border {
border : 1px red solid ;
}
.head {
width: 100% ;
border: 1px green solid ;
}
This is how it looks
https://www.geeksforgeeks.org/how-to-center-a-div-using-flexbox-property-of-css/

Related

How to make horizontal cards using Angular Material

I am trying to make these vertical cards into horizontal cards.
I am using the Cards component from Angular Material.
I can create cards only vertically, but I need the cards arranged on a horizontal level.
Here I'm attaching my code for reference.
HTML:
<body>
<div class="wrap">
<!-- <img class="img-bg" background-image src="assets/logo.png"> -->
<div class="text">
<h1 style="font-weight: bold; text-align: center;">Welcome to Data Portal...</h1>
<br>
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>Catalog</mat-card-title>
</mat-card-header>
<mat-card-content>
<p>Here you can find the details about users/roles.</p>
</mat-card-content>
<mat-card-header>
<mat-card-title>Data Portal</mat-card-title>
</mat-card-header>
<mat-card-content>
<p>Here you can find the details about all the databases and tables.</p>
</mat-card-content>
</mat-card>
<br>
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>Data Portal</mat-card-title>
</mat-card-header>
<mat-card-content>
<p>Here you can find the details about all the databases and tables.</p>
</mat-card-content>
</mat-card>
</div>
</div>
</body>
CSS:
.example-card {
height: 200px;
width: 400px;
max-width: 300px;
margin-left: 100px;
background-color: lightgrey;
color: black;
text-align: center;
}
sample image
Create a container for all the mat-cards, then change the flow of the elements inside the container using CSS. For example:
<div style="display: flex;">
<mat-card>...</mat-card>
<mat-card>...</mat-card>
</div>
<div fxLayout="row wrap" fxLayoutGap="16px grid">
<div fxFlex="25%" fxFlex.xs="100%" fxFlex.sm="33%">
<mat-card class="mat-elevation-z4" >
</mat-card>
</div>
See link below for reference https://zoaibkhan.com/blog/create-a-responsive-card-grid-in-angular-using-flex-layout-part-1/
You need a container for mat-cards first, then you can set flex to make it horizontal or even vertical if you want. Some code is below maybe will help you.
.wrap{
display: flex;
margin: 0 auto //center the content
}
.example-card{
border: 1px solid black;
border-radius: 5px;
text-align: center;
height: 200px;
width: 400px;
max-width: 300px;
margin-left: 100px;
background-color: lightgrey;
color: black;
text-align: center;
}
<div class="wrap">
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>Catalog</mat-card-title>
</mat-card-header>
<mat-card-content>
<p>Here you can find the details about users/roles.</p>
</mat-card-content>
<mat-card-header>
<mat-card-title>Data Portal</mat-card-title>
</mat-card-header>
<mat-card-content>
<p>Here you can find the details about all the databases and tables.</p>
</mat-card-content>
</mat-card>
<br>
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>Data Portal</mat-card-title>
</mat-card-header>
<mat-card-content>
<p>Here you can find the details about all the databases and tables.</p>
</mat-card-content>
</mat-card>
</div>

Get button below each image in Angular *ngFor

I tried lots of methods to get the button below each image from ngFor loop in angular 10 but it populates the button next to the image not in each image it's showing as a list I attached the image output also. This is the code that I tried.
CSS
.container {
position: relative;
text-align: center;
}
.original {
width: 250px;
height: 250px;
float: left;
margin: 1.66%;
transition-duration: 0.3s;
border-radius: 15px;
}
Html
<ng-container *ngFor="let img of imageData">
<div class="container">
<img class="original" [alt]="img.Name"
src="https://localhost:44349/{{img.ImagePath}}"
width="350" height="350"/>
</div>
<button type="submit" (click)="deleteImage(img.Id)" class="btn btn-danger"><i
class="far fa-trash-alt"></i>
Remove
</button>
</ng-container>
Try this markup, move the closing div after the button element:
<ng-container *ngFor="let img of imageData">
<div class="container card">
<img class="original" [alt]="img.Name"
src="https://localhost:44349/{{img.ImagePath}}"
width="350" height="350"/>
<button type="submit" (click)="deleteImage(img.Id)" class="btn btn-danger"><i
class="far fa-trash-alt"></i>
Remove
</button>
</div>
</ng-container>
with new css class using flexbox:
.card {
display: flex;
flex-direction: column;
}
UPDATE
according to some css classes like btn, btn-danger I presume bootstrap used.
You can wrap the whole thing inside a div with these classes:
<div class="d-flex flex-wrap">
General info and docs
Stackblitz demo

Position icon next to text

I have created a div which shows an icon and text but I need to get the icon next to the text instead of above it. Currently looks like this:
And I need the icon to be next to the text like this (the icon needs to be displayed to the left of the text without moving the text so the header still aligns with the phone number):
Code:
<div fxLayout="row" fxLayoutAlign="space-around center">
<div>
<mat-icon svgIcon="phone-outline"> </mat-icon>
<h3>Customer Support</h3>
<label>123456</label>
</div>
<div>
<mat-icon svgIcon="email-outline"> </mat-icon>
<h3>Email</h3>
<label>test#email.com</label>
</div>
<div>
<mat-icon svgIcon="map-marker-outline"> </mat-icon>
<h3>Address</h3>
<label>address line 1</label>
</div>
</div>
I have three divs and using fxLayoutAlign aligns them next to each other accoss the page but if I put the icon into a seperate div the fxLayoutAlign moves it too far across the page. Is there a better way to align the divs?
Tried so far:
Tried putting the icon on the same line as the text but that puts the icon too close to the text:
<h3><mat-icon svgIcon="phone-outline"> </mat-icon> Customer Support</h3>
I need to have space between the icon and text and align it with the text.
Using CSS to try align still causes the icon to be too close to the text (and not aligned correctly):
.align-items { display: flex; justify-content: space-between; } .align-content { display: flex; align-items: center; }
Moving the icon in CSS using margins looks like its working but it has now moved the second line with the phone number:
The phone number should be directly under the header text (like in first screenshot above)
Here is another approach with pure css.
css
.align-items {
display: flex;
justify-content: space-between;
}
.align-content {
display: flex;
}
mat-icon {
margin-right: 10px;
}
.align-text-item {
display: flex;
flex-direction: column;
align-items: center;
}
h3 {
margin-top: 0px;
}
html
<div class="align-items ">
<div class="align-text-item">
<div class="align-content">
<mat-icon svgIcon="thumbs-up" aria-hidden="false" aria-label="Example thumbs up SVG icon"></mat-icon>
<div>
<h3>Customer Support</h3>
123456
</div>
</div>
</div>
<div class="align-text-item">
<div class="align-content">
<mat-icon svgIcon="thumbs-up" aria-hidden="false" aria-label="Example thumbs up SVG icon"></mat-icon>
<div>
<h3>Email</h3>
123456
</div>
</div>
</div>
<div class="align-text-item">
<div class="align-content">
<mat-icon svgIcon="thumbs-up" aria-hidden="false" aria-label="Example thumbs up SVG icon"></mat-icon>
<div>
<h3>Address</h3>
123456
</div>
</div>
</div>
</div>
Create a class for the divs wrapping the icon and heading. No fxLayout is needed
.align-icon{
display: flex;
align-items: flex-end;
}
You can use the matPrefix and matSuffix
<mat-form-field class="example-full-width">
<mat-icon matPrefix>mode_edit</mat-icon>
<mat-label>EXAMPLE</mat-label>
<mat-icon matSuffix>mode_edit</mat-icon>
</mat-form-field>
<div fxLayout="row" fxLayoutAlign="space-around center">
<div>
<h3>Customer Support<mat-icon svgIcon="phone-outline"> </mat-icon></h3>
</div>
<div>
<mat-icon svgIcon="email-outline"> </mat-icon>
<h3>Email</h3>
</div>enter code here
<div>
<mat-icon svgIcon="map-marker-outline"> </mat-icon>
<h3>Address</h3>
</div>
</div>

HTML + CSS fails on center alignment of mat-icon

Problem: my generated columns doesn't center align my mat-icon.
What am I missing?
On ngFor my datatable columns are generated dynamically, but no one's align correctly.
Inside my DIV there's a mat-icon that's (by default) apply for left alignment.
HTML Code:
<div *ngFor="let col of colunas">
<ngx-datatable-column [name]="col.ds_titulo_coluna" *ngIf="col.fl_exibe_coluna">
<ng-template let-row="row" ngx-datatable-cell-template>
<div *ngIf="row[col.id] === 'pend'">
<div class="v-align-middle">
<mat-icon class="warning">info</mat-icon>
</div>
</div>
<div *ngIf="row[col.id] === 'rep'">
<div class="v-align-middle">
<mat-icon class="red-fg">report_off</mat-icon>
</div>
</div>
<div *ngIf="row[col.id] === 'ok'">
<div class="v-align-middle">
<mat-icon class="green-fg">check_circle</mat-icon>
</div>
</div>
<div *ngIf="row[col.id] === 'ag'">
<div class="v-align-middle">
<mat-icon class="orange-fg">schedule</mat-icon>
</div>
</div>
</ng-template>
</ngx-datatable-column>
</div>
SCSS Code:
.ngx-datatable-column.text-center
{
display: flex !important;
align-items: center !important;
margin-left: 10px;
}
.warning{
color: #dec71b;
}
.v-align-middle {
vertical-align: middle;
}
Result of code:
Replace .v-align-middle CSS rules as per below. Hope this will be worked for you.
.v-align-middle {
display: flex;
justify-content: center;
align-items: center;
}

extra option causing button to move up and down

How do you position a button so it stays fixed?
I have an Angular app and when the 3rd option is displayed for a multiple choice, the next and back buttons move down.
Some of the questions only have 2 options and some have 3.
Is there a way to make it so that the buttons stay at one position? I tried using position property in css and margin-bottom, but no luck.
2 Options
3 Options
CSS
button {
background-color: #004273;
font-family: 'Roboto';
color: white;
border: 2px solid #93b9dd;
border-radius: 8px;
padding-top: 2%;
padding-bottom: 2%;
font-size: 1em;
}
.buttons2 {
width:48%;
float: right;
}
.buttons1 {
width: 48%;
float: left;
}
HTML
<h2 style="color: white;" align="center">{{statement}}</h2>
<h2 style="color: white;" align="center">{{question}}</h2>
<div class="radio-{{questionType}} col-sm-4 col-sm-offset-4 col-xs-offset-4">
<div class="form-check">
<mat-radio-group [(ngModel)]="selectedValue" class="options">
<mat-radio-button value="{{radio1}}">{{radio1}}</mat-radio-button> <br>
<mat-radio-button value="{{radio2}}">{{radio2}}</mat-radio-button> <br>
<span *ngIf="radio3">
<mat-radio-button value="{{radio3}}">
{{radio3}}
</mat-radio-button>
</span>
</mat-radio-group>
</div>
</div>
<div class="row">
<div class="col-sm-6 col-sm-offset-3" style="padding-top: 2%;">
<button *ngIf="state !== 1; else disabled_btn" class="buttons1 btn btn-primary" (click)="onClickedBack.emit(selectedValue)">BACK</button>
<ng-template #disabled_btn>
<button class="buttons1 btn" (click)="onClickedBack.emit(selectedValue)" disabled>BACK</button>
</ng-template>
<button class="buttons2 btn btn-primary" (click)="onClickedNext.emit(selectedValue)">NEXT</button>
</div>
</div>
You can use the :nth-child() CSS selector to modify the behavior of the options.
.options > :nth-child(3) {
height: 0;
overflow-y: visible;
}
The above selects the 3rd direct child of .options class element group, removes the height, but ensures that it still shows. You may have to adjust this based on other CSS.