I am using the ngx-pagination library for my angular app.
Besides the previous and next button I want to add 2 more buttons to go directly on the last page or on the first page.
How can I achieve this ?
Template logic
import { Component, OnInit } from '#angular/core';
import { TestimonialsDataService } from '../../services/testimonials-data.service';
#Component({
selector: 'app-card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.scss']
})
export class CardComponent implements OnInit {
public authors: Object = {};
public pageList: number = 1;
constructor(private _testimonialsService: TestimonialsDataService) { }
ngOnInit(): void {
this._testimonialsService.getData().subscribe(data => this.authors = data);
}
}
<div class="container">
<div class="content">
<div class="card" *ngFor="let author of authors['user'] | paginate: {id: 'list-pagination', itemsPerPage: 9, currentPage: pageList}" >
<div class="card-content">
<img class="image" src="{{author.image}}"/>
<p class="author">{{author.name}}</p>
<p class="job">{{author.job}}</p>
<p class="company">{{author.company}}</p>
<p class="country"><span class="flag flag-IT"></span><span class="country">{{author.country}}</span></p>
</div>
</div>
</div>
<pagination-controls id="list-pagination" lastLabel="Next" class="list-pagination" directionLinks="true" (pageChange)="pageList = $event"></pagination-controls>
</div>
You can customize the pagination-template and try adding these buttons
<pagination-template #p="paginationApi" [id]="config.id
(pageChange)="config.currentPage = $event">
<div class="custom-pagination">
<div class="pagination-first-page">
<span (click)="p.setCurrent(1)">
First Page
</span>
</div>
<div class="pagination-previous" [class.disabled]="p.isFirstPage()">
<span *ngIf="!p.isFirstPage()" (click)="p.previous()">
<
</span>
</div>
<div class="page-number" *ngFor="let page of p.pages" [class.current]="p.getCurrent() === page.value">
<span (click)="p.setCurrent(page.value)" *ngIf="p.getCurrent() !== page.value">{{ page.label }}</span>
<div *ngIf="p.getCurrent() === page.value">
<span>{{ page.label }}</span>
</div>
</div>
<div class="pagination-next" [class.disabled]="p.isLastPage()">
<span *ngIf="!p.isLastPage()" (click)="p.next()"> > </span>
</div>
<div class="pagination-last-page">
<span (click)="p.setCurrent(p.getLastPage())">
Last Page
</span>
</div>
</div>
</pagination-template>
Related
Component.html
<div class="bootstrap-wrapper" *ngIf="!isSubmit">
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<!-- instructions -->
<h2>Instructions</h2>
</div>
<div class="col-md-8">
<!-- questions -->
<ng-container *ngIf="questions">
<h2>{{questions[0].quiz.title}}</h2>
</ng-container>
<mat-card *ngFor="let q of questions, let i= index" class="mt20">
<mat-card-content>
<p> Q {{i+1}}) <span [innerHTML]="q.content"></span> </p>
<mat-divider></mat-divider>
<div class="row mt20" >
<div class="col-md-6">
<input type="radio" [value]="q.option1"
[name]="i"
// this is where i am getting error
[(ngModel)] ="q.givenAnswer"
/>
{{q.option1}}
{{i}}
</div>
<div class="col-md-6">
<input type="radio" [value]="q.option2"
[name]="i"
// this is where i am getting error
[(ngModel)] ="q.givenAnswer"
/>
{{q.option2}}
{{i}}
</div>
</div>
<div class="row mt20">
<div class="col-md-6">
<input type="radio" [value]="q.option3"
// this is where i am getting error
[name]="i"
[(ngModel)] ="q.givenAnswer"
/>
{{q.option3}}
{{i}}
</div>
<div class="col-md-6">
<input
type="radio"
[value]="q.option4"
// this is where i am getting error
[name]="i"
[(ngModel)] ="q.givenAnswer"
/>
{{q.option4}}
{{i}}
</div>
</div>
</mat-card-content>
</mat-card>
<div class="container text-center mt20">
<button (click)="submitQuiz()" mat-raised-button color="accent">Submit
Quiz</button>
</div>
</div>
<div class="col-md-2">
</div>
</div>
</div>
</div>
<!-- Show Result -->
<div class="bootstrap-wrapper" *ngIf="isSubmit">
<div class="row">
<div class="col-md-6 offset-md-3">
<mat-card>
<mat-card-header>
<mat-card-title>
<h1 class="text-center mall">Quiz Result</h1>
</mat-card-title>
</mat-card-header>
<mat-card-content>
<h1>Marks Obtained: {{marksGot}}</h1>
<h1>Correct Ansers: {{correctAnswers}}</h1>
<h1>Questions Attempted: {{attempted}}</h1>
</mat-card-content>
<mat-card-actions>
<button mat-raised-button color="accent">Print</button>
<button mat-raised-button color="accent" [routerLink]="'/user-
dashboard/0'">Home</button>
</mat-card-actions>
</mat-card>
</div>
</div>
</div>
Component.ts
import { LocationStrategy } from '#angular/common';
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { QuestionService } from 'src/app/services/question.service';
import Swal from 'sweetalert2';
#Component({
selector: 'app-start-quiz',
templateUrl: './start-quiz.component.html',
styleUrls: ['./start-quiz.component.css']
})
export class StartQuizComponent implements OnInit {
qid;
questions;
marksGot = 0;
correctAnswers = 0;
attempted = 0;
isSubmit = false;
constructor(private locationSt: LocationStrategy, private _route: ActivatedRoute, private
_question: QuestionService) { }
ngOnInit(): void {
this.preventBackButton();
this.qid = this._route.snapshot.params['qid'];
this.loadQuestions();
}
loadQuestions() {
this._question.getQuestionsOfQuizForTest(this.qid).subscribe(
(data: any) => {
this.questions = data;
this.questions.forEach((q) => {
q['givenAnswer'] = '';
});
console.log(data);
},
(error) => {
Swal.fire('Error', 'Error in loading questions of quiz', 'error');
}
);
}
preventBackButton() {
history.pushState(null, null, location.href);
this.locationSt.onPopState(() => {
history.pushState(null, null, location.href);
})
}
submitQuiz() {
Swal.fire({
title: 'Do you want to Submit quiz?',
showCancelButton: true,
confirmButtonText: 'Submit Quiz',
icon: 'info',
}).then((e) => {
if (e.isConfirmed) {
//calculation
this.isSubmit=true;
this.questions.forEach((q) => {
if (q.givenAnswer == q.answer) {
this.correctAnswers++;
let marksSingle = this.questions[0].quiz.maxMarks / this.questions.length;
this.marksGot += marksSingle;
}
if (q.givenAnswer.trim() != '') {
this.attempted++;
}
});
console.log("Correct Answers " + this.correctAnswers);
}
})
}
}
enter image description here
When i am name as [name] it is showing number is not assignable to type String and when i am using name it is compiling successfully but i have three questions in a quiz and while selecting an option of a particular question other options of other questions are getting deselected. what to do?
Thanks in Advance
[(ngModel)]="q.givenAnswer" type="radio" [value]="q.option1" name={{i}}
Here I am sharing my Angular Code:
1. app-component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-all-trades',
templateUrl: './all-trades.component.html',
styleUrls: ['./all-trades.component.css']
})
export class AllTradesComponent implements OnInit {
// Arrays of Object
crops = [
{
name:'Rice',
checked: false
},
{
name:'Wheat',
checked : false
},
{
name:'Barley',
checked : false
},
{
name:'Soyabean',
checked : false
},
];
constructor() { }
ngOnInit(): void {
}
// Here I tried the logic but its not working
onChange(event, index, item) {
item.checked = ! item.checked
console.log(index, event, item);
}
}
2. app-component.html
<app-header></app-header>
<div
fxLayout="row"
fxLayout.lt-md="column"
fxLayoutAlign="space-between start"
fxLayoutAlign.lt-md="start stretch"
>
<div class="container-outer" fxFlex="20">
<div class="filters">
<section class="example-section">
<span class="example-list-section">
<h1>Select Crop</h1>
</span>
<span class="example-list-section">
<ul>
<li *ngFor="let crop of crops; let i = index">
<mat-checkbox
[checked]="item.checked"
(change)="onChange($event, i, item)"
>
{{ crop.name }}
</mat-checkbox>
</li>
</ul>
</span>
</section>
<section class="example-section">
<span class="example-list-section">
<h1>Select District</h1>
</span>
<span class="example-list-section">
<ul>
<li *ngFor="let district of districts">
<mat-checkbox>
{{ district.name }}
</mat-checkbox>
</li>
</ul>
</span>
</section>
</div>
</div>
<div class="content container-outer" fxFlex="80">
<mat-card
class="crop-card"
style="min-width: 17%"
*ngFor="let crop of crops"
>
<mat-card-header>
<img
mat-card-avatar
class="example-header-image"
src="/assets/icons/crops/{{ crop.name }}.PNG"
alt="crop-image"
/>
<mat-card-title>{{ crop.name }}</mat-card-title>
<mat-card-subtitle>100 Kgs</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<p>PRICE</p>
</mat-card-content>
</mat-card>
</div>
</div>
<app-footer></app-footer>
Here I shared my output window, as you guys can see on left hand side I have created mat-checkbox, all I need to do is that when I check the "RICE" box its should only show the RICE CARD and when I check Wheat then only Wheat Card.
the first thing to know is that you
Can't have multiple template bindings on one element
as you saw when trying to do so and here is the official document for that if you are interested
so here are two possible solutions for you
hide unchecked cards by [hidden] directive as below:
<mat-card [hidden]="!crop.checked">
wrap your card in another element like a div and do as below:
<div *ngFor="let crop of crops">
<mat-card
class="crop-card"
style="min-width: 17%"
*ngIf="crop.checked">
.
.
</mat-card>
</div>
I created a component called <bradcam-area>, this section should be displaying titles of each page. I thought of using
So here is the HTML:
<div class="bradcam_area bradcam_bg_1">
<div class="container">
<div class="row">
<div class="col-xl-12">
<div class="bradcam_text text-center">
<h3> Change this based on the page </h3>
</div>
</div>
</div>
</div>
</div>
And here is the TS file:
export class BradcamAreaComponent implements OnInit {
// Titles
titles = {
about: 'About Me',
services: 'Here is what I provide',
portfolio: 'My awesome work here',
contact: 'Get in touch'
}
constructor() { }
ngOnInit() {
}
}
I researched can't figure out what should I do.
here is the about page for example:
<app-header></app-header>
<bradcam-area></bradcam-area>
<!-- You can add extra content under this comment -->
<about-area></about-area>
<app-footer></app-footer>
Instead of using *ngIf (seeing your own solution), you could simply do this :
<h3> {{ titles[router.url] }} </h3>
Much more compact, fast and easier to maintain and update.
I found a solution. I used the ngIf method <h3 *ngIf="router.url === '/about'">
and in the <bradcam-area> Ts file I added these
private router: Router;
constructor(router: Router) {
this.router = router;
}
and here is the Final HTML template of <bradcam-area>
<div class="bradcam_area bradcam_bg_1">
<div class="container">
<div class="row">
<div class="col-xl-12">
<div class="bradcam_text text-center">
<h3 *ngIf="router.url === '/about'"> {{ titles.about }} </h3>
<h3 *ngIf="router.url === '/services'"> {{ titles.services }} </h3>
<h3 *ngIf="router.url === '/portfolio'"> {{ titles.portfolio }} </h3>
<h3 *ngIf="router.url === '/contact'"> {{ titles.contact }} </h3>
</div>
</div>
</div>
</div>
</div>
I'm working with Reactive Forms and I'm trying to pass my form down to child components, but I'm running into the error above. Initially at the top level of the form I was using a FormArray to hold my form and that was working fine before I tried passing it down to the child components. Thanks to this post I now know that the top level of a form should be a FormGroup and the FormArray should be a child of the FormGroup.
So now I am nesting my FormArray inside of a FormGroup and I'm getting the error above. I'm not sure what I'm doing wrong? Below in the relevant code.
// Parent component.ts
ngOnInit() {
if (!!this.rows) {
this.tableForm = new FormArray([]);
this.rows.forEach((row) => {
this.rowGroup = new FormGroup({})
this.columns.forEach(column => {
this.rowGroup.addControl(column.key, new FormControl(row[column.key]));
});
this.tableForm.push(this.rowGroup);
})
this.tableGroup = new FormGroup({
rows: new FormControl(this.tableForm)
})
}
}
// Parent HTML
<section
*ngIf="!!modal"
class="modal__mask">
<section
class="modal__container"
#carousel
[ngStyle]="{'left': start + 'px'}"
(window:resize)="onResize($event)"
[formGroup]="tableGroup">
<div
*ngFor='let row of selectedRows; let i = index'
class="modal modal__large"
[formArrayName]="rows">
<div
[formGroupName]="i"
[ngClass]="{'opacity': modalPage !== i}">
<div class="modal__header modal__header--large">
<h6>Edit Employee Details</h6>
</div>
<div class="u-flex u-wrap">
<div
class="u-flex modal__body"
style="width: 50%"
*ngFor="let column of columns">
<div
*ngIf="column.label"
class="input__wrapper"
[ngClass]="{'input__wrapper--inline': layout === 'horizontal'}">
<z-input
*ngIf="column.label"
class="u-maxX"
[group]="tableGroup"
[config]="column">
</z-input>
<!-- <div>
<label
class="input__label">
<p class="t-bold t-data">{{column.label}}</p>
</label>
<div class="z-input__default">
<input
class="input u-maxX"
[formControlName]="column.key"
[value]="row[column.key]">
</div>
</div> -->
</div>
</div>
<section class="modal__footer u-fillRemaining">
<div class="u-flex">
<button
class="button button--medium"
(click)="nextSelectedRow()">
<div class="button__content">
<i
class="icon icon--medium"
*ngIf="!!icon">
{{icon}}
</i>
<span>Skip</span>
</div>
</button>
</div>
<div class="u-flex">
<button
class="button button--low"
(click)="reset(row, i)">
<div class="button__content">
<i
class="icon icon--medium"
*ngIf="!!icon">
{{icon}}
</i>
<span>Reset</span>
</div>
</button>
<button
class="button button--low"
(click)="saveChanges(row, i)">
<div class="button__content">
<i
class="icon icon--medium"
*ngIf="!!icon">
{{icon}}
</i>
<span>Save Changes</span>
</div>
</button>
</div>
</section>
</div>
</div>
</div>
// Child component.ts
#Input() config;
#Input() group: FormGroup;
#Input() view: string;
#Input() layout: string;
// Child HTML
<div
class="input__wrapper"
[ngClass]="{'input__wrapper--inline': layout === 'horizontal'}"
[formGroup]="group"
[ngSwitch]="config.type">
<label
class="input__label"
*ngIf="!!config.label">
<p class="t-bold t-data">{{config.label}}</p>
</label>
<z-select
*ngSwitchCase="'select'"
[config]="config"
[group]="group"
[view]="view"
gridColumn="1 / 5">
</z-select>
<div class="z-input__default">
<input
*ngSwitchDefault
class="input u-maxX"
[formControlName]="config.key"
[attr.type]="config.type"
[attr.placeholder]="config.placeholder">
</div>
The HTML is written where I am getting the file name but i want to get rid of the file extension and also store the files in an array and access them in the UI.
<div class="myReadingListContainer">
<div class="readingList">
My Reading List
</div>
<div class="myReadingList">
<div class="uploadWrap">
<input type="file" #file (change)="onChange(file.files)" class="fileUploadInput" />
<div class="innerText">
<img src="assets/img/my_reading_list/Add.svg" class="addIcon">
<h6 class="addFile">Add Files</h6>
</div>
</div>
<div *ngFor="let file of fileList">
<div class="selectedFile">
<div class="documentName">
{{file.name}}
</div>
<span *ngIf="file.type === 'application/pdf'">
<img src="assets/img/my_reading_list/PDF.svg" class="fileTypeImage">
</span>
<span *ngIf="file.type === 'application/vnd.ms-excel'">
<img src="assets/img/my_reading_list/Excel.svg" class="fileTypeImage">
</span>
<div class="readingStatus">
20/35 Pages
</div>
<div class="progress">
<div class="progressBar"></div>
</div>
</div>
</div>
</div>
</div>
The typescript file is written like this. Since I am new to Angular 6 any help is really appreciated, thanks in advance
import { Component, OnInit } from "#angular/core";
#Component({
selector: "app-myReadingList",
templateUrl: "./myReadingList.component.html",
styleUrls: \["./myReadingList.component.scss"\]
})
export class MyReadingListComponent implements OnInit {
//localUrl: String;
fileList: any = \[\];
files: any;
constructor() {}
onChange(files: FileList) {
console.log(files);
this.files = files;
this.fileList.push(files\[0\]);
this.fileList.forEach(file => {
let temp = file.name.split(".");
file.name = temp.splice(0, temp.length - 1).join(".");
});
console.log(this.fileList);
}
ngOnInit() {}
}
Here is the sample code to remove file extension while displaying from each fileList.name
<div class="documentName">
{{file.name.split('.').slice(0, -1).join('.')}}
</div>
Demo for the same