Can't figure out why the columns aren't being structured with this HTML component:
<div class="container">
<div class="row">
<div class="col-6">
<p>Some text</p>
</div>
<div class="col-6">
<p>Some text</p>
</div>
</div>
</div>
if i use col-someNumber, it does not work
columns displaying incorrectly
But if i use the class 'col', it works.
columns displaying correctly
this is my component.ts
import { Component, OnInit } from '#angular/core';
import { Product } from '../model/product.model';
import { ProductService } from './product.service.component';
#Component({
selector: 'app-products',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css', '../../../node_modules/bootstrap/dist/css/bootstrap.min.css']
})
I need one columns smaller than the other, that's why i don't use '.col'.
'.col-' should do the work.
I also replaced my html with multiple bootstrap .col- examples, but none seems to work
Related
I'd like to display formated HTML using type script function in an angular component, I wanted it to display question from diferent type, I tried this,
import {Component, OnInit} from '#angular/core';
import {TP, Question, Qtype} from "../tp";
import * as Exercice from '../assets/Exercice.json';
#Component({
selector: 'app-tp',
templateUrl: './tp.component.html',
styleUrls: ['./tp.component.css']
})
export class TpComponent implements OnInit {
constructor() {
}
ngOnInit(): void {
}
displayQCM(question: Question) {
return `
<div>
<hr class="w-100">
<h3>Question n°${question.number} ${question.questionType}</h3>
<p>${question.questionContent}</p>
...
QCM question element
...
</div>
`;
}
displayTrueOrFalse(question: Question) {
return `
<div>
<hr class="w-100">
<h3>Question n°${question.number} ${question.questionType}</h3>
<p>${question.questionContent}</p>
...
true or false question element
...
</div>
`;
}
displayQuestion(question: Question) {
return `
<div>
<hr class="w-100">
<h3>Question n°${question.number} ${question.questionType}</p>
<p>${question.questionContent}</p>
...
normal question element
...
</div>
`;
}
}
<div class="row justify-content-center">
<div class="col-12 col-lg-6">
<h2>Questions</h2>
{{displayQCM()}}
{{displayQuestion()}}
{{displayTrueOrFalse()}}
</div>
</div>
but the HTML display only as plain text writing fully the code on the page, do you know how to fix this ?
EDIT: edited code to be more in the context, the question comes from a json file and there's 3 type of them, I created a function to translate them into Question and depending on there type I want 3 way to display them in 3 different forms, each type as a long HTML development and are displayed with different tag and element
You need to use [innerHTML] property in your html file
<div class="row justify-content-center">
<div class="col-12 col-lg-6">
<h2>Questions</h2>
<div [innerHTML]="displayQCM()"></div>
<div [innerHTML]="displayQuestion()"></div>
<div [innerHTML]="displayTrueOrFalse()"></div>
</div>
</div>
If you are just trying to inject dynamic content you need to sanitize your html string and then use innerHtml. From your question Im not sure what the goal is and there must be a better way without injecting Html but you would need to clarify the goal.
questions: Array<SafeHtml> = new Array<SafeHtml>();
myJson: Array<string> = []; //I dont know where its coming from
constructor(private sanitizer: DomSanitizer) {
}
ngOnInit(): void {
myJson.forEach((question) => {
this.questions.push(this.sanitizer.sanitize(question));
})
}
<div class="row justify-content-center">
<div class="col-12 col-lg-6">
<h2>Questions</h2>
<div *ngFor="let q of questions" [innerHtml]="q"></div>
</div>
</div>
Why you don't use ngFor to list all questions?
HTML
<div class="row justify-content-center">
<div class="col-12 col-lg-6">
<h2>Questions</h2>
<div *ngFor="let question of allQuestions">
<hr class="w-100">
<h3>Question n°{{question.number}} {{question.questionType}}</h3>
<p>{{question.questionContent}}</p>
</div>
</div>
</div>
And allQuestions is your question array
You can add conditions depends on question type with *ngIf:
<p *ngIf="question.questionType=== 'normal'"></p>
or you can use ng-template:
<ng-template [ngIf]="question.questionType === 'normal'">Your HTML code for normal question</ng-template>
<ng-template [ngIf]="question.questionType === 'trueFalse'">Your HTML code for trueFalse question</ng-template>
Exemple
TS :
displayQCM : boolean;
displayQuestion : boolean;
displayTrueOrFalse : boolean;
HTML
<div class="row justify-content-center">
<div class="col-12 col-lg-6">
<h2>Questions</h2>
<div *ngIf="displayQCM">...</div>
<div *ngIf="displayQuestion">...</div>
<div *ngIf="displayTrueOrFalse">...</div>
</div>
</div>
I wish to generate a Table of Contents ( ToC ) by parsing the HTML that is already present in the templateUrl of my component.
This is my component.ts :
#Component({
selector: 'app-presentation',
templateUrl: './presentation.component.html',
styleUrls: ['./presentation.component.css']
})
export class PresentationComponent implements OnInit {
public toc = '';
constructor() { }
ngOnInit(): void {
// parse tempalteUrl here
// set the this.toc variable
}
}
and this is my component.html :
<div class="container">
<div class="row">
<div class="col-sm-4">
{{toc}}
</div>
<div class="col-sm-8">
<h1>Title</h1>
<h2>Sub Title1</h2>
<p>some text</p>
<h2>Sub Title2</h2>
<p>more text</p>
<h1>Title2</h1>
<h2>Sub Title3</h2>
<p>random text</p>
<h2>Sub Title4</h2>
<p>extra text</p>
</div>
</div>
</div>
What I wish to do is to extract all of the and children and then use them to generate the ToC.
Only <div class="col-sm-8"> has the elements I am interested in
All <h1> are direct children of that div
All <h2> are direct children of a <h1>
The aim of what I am trying to do is have as little HTML as possible to edit at each update when I want to change the content of my website.
Couple ways I can think of are inject ElementRef if just reading whole HTML doc, Renderer2 if going to modify HTML and output in ngOnInit(); add template ref and read ViewChild in ngAfterViewInit()
<div #toc class="col-sm-8">...</div>
import { Component , ElementRef, ViewChild } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
#ViewChild('toc') toc: ElementRef;
constructor(private elRef: ElementRef) {}
ngOnInit() {
console.log(this.elRef.nativeElement.innerHTML);
}
//template ref + viewChild
ngAfterViewInit() {
console.log(this.toc.nativeElement.innerHTML);
}
}
app.component.html code
<div class="container">
<div class="row" id="ads">
<div class="col-xs-4">
<app-card *ngFor="let car of cars"
[carNotifyBadge]="car.carNotifyBadge"
[carNotifyYear]="car.carNotifyYear"
[carCondition]="car.carCondition"
[carPrice]="car.carPrice"
[carUsageinKM]="car.carUsageinKM"
[carName]="car.carName"
[imgSource]="car.imgSource"
>
</app-card>
</div>
</div>
</div>
app.component.ts code
import { Component ,Input} from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title:string = "Angular-App"
cars = [
{....},{....},{....}
]
}
card.component.html
<div class="card rounded">
<div class="card-image">
<span class="card-notify-badge">{{carNotifyBadge}}</span>
<span class="card-notify-year">{{carNotifyYear}}</span>
<img class="img-fluid" [src]="imgSource" alt="Alternate Text" />
</div>
<div class="card-image-overlay m-auto">
<span class="card-detail-badge">{{carCondition}}</span>
<span class="card-detail-badge">{{carPrice}}</span>
<span class="card-detail-badge">{{carUsageinKM}}</span>
</div>
<div class="card-body text-center">
<div class="ad-title m-auto">
<h5>{{carName}}</h5>
</div>
<a class="ad-btn" href="#">View</a>
</div>
</div>
card.component.ts
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.css']
})
export class CardComponent implements OnInit {
constructor() { }
#Input() carNotifyBadge = '';
#Input() carUsageinKM = '';
#Input() carName = '';
#Input() carNoticarNotifyYearfyBadge = '';
#Input() imgSource = '';
#Input() carCondition = '';
#Input() carPrice = '';
#Input() carNotifyYear = '';
ngOnInit(): void {
}
}
Since in app.component.html I have used grid system of bootstrap and using structural directives ngFor I am dynamically adding elements to DOM. I expect the cols to be side by side, whereas I am getting it below each other as shown in the image.
How to display cols side by side as per bootstrap behaviour ?
Make sure bootstrap CSS is loaded in the application if not, follow these steps.
Steps to include Bootstrap in Application
Pass only car item to the child component, all properties within car object yu will be able to access in the child component.
<div class="container">
<div class="row" id="ads">
<div class="col-xs-6 col-md-4" *ngFor="let car of cars">
<app-card [car]="car"></app-card>
</div>
</div>
</div>
In the child component, receive the car object inputs from the parent component.
#Input car;
make sure, that bootstrap is included in your bundled.css file.
has '#ads' any styles which override bootstraps behavior?
helpful link for install bootstrap using-bootstrap-with-angular
I had similar problem. I use a bootstrap and a commercial theme built on it. I tried to present list of records in bootstrap grid.
I have main app-component which presents the web page. Then I have card-list component which presents grid list within app-component.
When I typed:
styleUrls: [
'./credential-card.component.css',
'../../assets/css/bootstrap.min.css',
'../../assets/css/style.css']
Cards were properly styled, but grid didn't work.
When I removed styles
styleUrls: [
'./credential-card.component.css']
I lost styling but grid worked fine.
What fixed the problem was to implement another component card-detail and invoke it from card-list. I removed bootstrap CSS from card-list, and added to card-detail.
Finally, I have something like this in card-list component:
<section class="pricing-wrapper pt-70 pb-100">
<div class="container">
<div class="row justify-content-center">
<div *ngFor="let item of credentials" class="col-lg-4 col-md-6 col-sm-8">
<card-detail [shortName]="item.payload.doc.data().shortName" [priceDescription]="item.payload.doc.data().priceDescription"></card-detail>
</div>
</div>
</div>
And this in card-detail:
<div class="pricing-style-5 mt-30">
<div class="pricing-header">
<div class="pricing d-flex align-items-center flex-wrap">
<h3 class="heading-3 font-weight-400 title">{{shortName}}</h3>
<span class="price">{{priceDescription}}</span>
</div>
</div>
</div>
enter image description here
html code
<div id="myModal" class="modal">
<div class="modal-content">
<div class="modal-header" style="text-align: center;">
<span class="close">×</span>
<h2>Register Account</h2>
</div>
<div class="modal-body">
<div class="signup-body">
<div class="su-body" style="background-color:#3B5998;">
Employer
</div>
<div class="su-body" style="background-color:#3B5998;">
Candidate
</div>
</div>
<div class="signup-body">
<div class="su-body" style="background-color:#3B5998;">
Login with Faceboo
</div>
<div class="su-body" style="background-color:#3B5998;">
Login With Google
</div>
</div>
<div class="signup-body">
<div class="su-body" style="background-color:#3B5998;">
Login With Linkedin
</div>
<div class="su-body" style="background-color:#3B5998;">
Login With Twitter
</div>
</div>
</div>
<div class="modal-footer">
<div class="signup-body">
<!-- <button>Sign up</button> -->
<div class="su-body" style="background-color:#3B5998;">
Sign up
</div>
</div>
<p>Already have ab account</p>Login
</div>
</div>
</div>
I want to create a registration page has given below in angular 6. But my question is when user can register two ways (either employer or candidate ) so how can i send Api particular field data. please help me.
Please check below solution might be it can help you to observe Registration Type:
Registered Event in Html:
<div class="signup-body">
<div class="su-body" style="background-color:#3B5998;">
<a href="#" target="_blank" (onclick)="changeReg('Employer')" >Employer</a>
</div>
<div class="su-body" style="background-color:#3B5998;">
<a href="#" target="_blank" (onclick)="changeReg('Candidate')" >Candidate</a>
</div>
</div>
Create a data sharing service
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs';
#Injectable()
export class DataService {
private regSource = new BehaviorSubject('Employer'); //Default registration type
currentReg = this.regSource.asObservable();
constructor() { }
changeRegType(regTyp: string) {
this.regSource.next(regTyp)
}
}
Set New Registration type within Supplied Html component:
import { Component, OnInit } from '#angular/core';
import { DataService } from "../data.service";
#Component({
selector: 'app-registration',
styleUrls: ['./registration-selection.component.css']
})
export class RegistrationSelectionComponent implements OnInit {
constructor(private data: DataService) { }
changeReg(regType:String) {
this.data.changeRegType(regType);
}
}
Get default/new registration type in signup component:
import { Component, OnInit } from '#angular/core';
import { DataService } from "../data.service";
#Component({
selector: 'app-signup',
template: `
{{message}}
`,
styleUrls: ['./signup.component.css']
})
export class SignUpCmponent implements OnInit {
regType:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentReg.subscribe(reg => this.regType = reg)
}
}
I have 3 components in angular 2 application.The class="container-fluid content" is css class in app.component.html. This class="container-fluid content" is default css for other components. Now I want to set background-color:blue in the detail component. I tried to set in detail.component.ts like this styles:['.container-fluid content{background-color: blue;}'] It did not work. If I set in app.component.html like this <div class="container-fluid content" style="background-color: blue;"> It applies to both the components. How to override this class="container-fluid content" in detail component?
//my project structure
app
- app.component.html
-app.component.ts
- welcome
-welcome.component.html
-welcome.component.ts
- detail
-detail.component.html
-detail.component.ts
//app.component.html
<div class="container-fluid content">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
</div>
//welcome.component.html
<h1>welcome page heading</h1>
<div fxLayout="row" fxLayoutWrap style="padding-bottom: 25px;
padding-top: 25px; margin: auto;justify-content: center" >
<md-card>
<md-card-content>
<h1></h1>
<h2></h2>
<h2>
</h2>
</md-card-content>
</md-card>
</div>
//detail.component.html
<h1>Details page heading</h1>
<div fxLayout="row" fxLayoutWrap style="padding-bottom: 25px;
padding-top: 25px; margin: auto;justify-content: center" >
<md-card>
<md-card-content>
<h1></h1>
<h2></h2>
<h2>
</h2>
</md-card-content>
</md-card>
</div>
//detail.component.ts
import { OnInit, Component } from '#angular/core';
import { DetailService } from '../detail/detail.service';
import { HostBinding} from '#angular/core';
#Component({
providers: [DetailService ]
templateUrl: './detail.component.html',
styles: ['h3 {margin:5px}']
})
export class DetailComponent implements OnInit {
#HostBinding('class.blueClass') blue: boolean = false;
constructor( private _detailService: DetailService ) { }
ngOnInit() {
this.blue = true;
}
}
In child component, you can add this param to #Component.
// child-component.component.ts
#Component({
selector: 'child-component',
templateUrl: 'child-component.component.html',
styleUrls: ['child-component.component.css']
encapsulation: ViewEncapsulation.None
})
// child-component.component.css
.container-fluid content{background-color: blue;}
You can ref this side for more infomartion :
https://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html
Have you tried with the hostbinding and adding a new class there?
#HostBinding('class.blueClass') blue: boolean = false;
And in the second component just switch that on onInit?
ngOnInit() {
this.blue = true;
}
The other way could be in the component definition, you can add the following line :
host: {'class': 'blueClass'}
and you do the rest of the css work in css instead.