I am trying to create something like in Xing the CV maker -> https://lebenslauf.com/.
I do have different Arrays of Objects.
But I am not able to create the A4 pages which will render the data and if the array it is larger than one page create new page A4 and add data there.
The function needs to be so if the array is larger for one size, then create a new page a4 and put the data there.
In the stackblitz I have added an array and some random text and designed an A4 letter.
I referred to this question and answer, but didn't help me too much.
CSS to set A4 paper size.
I tried to fake pagination and to create A4 sizes but didn't work.
I looked in this code with jquery there. It works, but I am unable to compile it in Angular.
https://jsfiddle.net/tm637ysp/10/
Can someone help me here ?
I have created two projects in stackblitz. Maybe they will help.
https://stackblitz.com/edit/angular-ivy-fjhpdu.
https://stackblitz.com/edit/angular-ivy-uzmdwg
I wanted to reopen this question because the approved answer from @HirenParekh it doesn't work as I wanted.
The problem it is now, If the text in one Object it is very large it wont add a new page in a realtime, but only if I reload the page.
I think that the code will be for add new page or edit page will be rendered only in ngOnInit
.
The directive that is provided to do that job, I think it is not working as excepted.
Here is the stackblitz
what he tried to help me.
https://stackblitz.com/edit/angular-ivy-zjf8rv
This is the code I am trying to show data.
<div style="transition: transform 0.25s ease 0s;transform: scale(1.3);transform-origin: 50% 0px 0px;backface-visibility: hidden;perspective: 1000px;display: block;margin: 0px 11.5385%;font-size:10px;width: 76.9231%;-webkit-font-smoothing: antialiased;">
<app-paginated-view [pageSize]="'A4'" *ngIf="model" class="Grid-grid-column">
<div pageContent class="row">
<div class="col col-lg-7">
<h4>{{currentUser?.firstName}} {{currentUser?.lastName}}</h4>
</div>
<div class="col text-right">
<input type="file" accept="image/*" (change)="readUrl($event)">
<img [src]="url" (change)="readUrl($event)" height="128" style="cursor: pointer">
</div>
</div>
<div pageContent class="Unit-unit-unitGroup"
*ngFor="let personalData of model.personalData; let id = index">
<div pageContent [ngClass]="{ 'isCatActive': selectedCategory === category.PersonalData}">
<ng-container *ngIf="selectedCategory === category.PersonalData" clickOutside (clickOutside)="removeClick()">
<ul>
<li class="fa fa-plus addIconTop" (click)="openDialog()"></li>
<li class="fa fa-plus addIconBottom" (click)="openDialog()"></li>
<li class="fa fa-trash deleteIconRight" (click)="deleteCategory(index)"></li>
<li class="fa fa-arrow-down moveIconDown"></li>
<li class="fa fa-arrow-up moveIconTop"></li>
</ul>
</ng-container>
<div pageContent class="col-md-12" (click)="setCategory(category.PersonalData)">
<div class="row height">
<div class="col-md-4 col-sm-6 text-right tLine"></div>
<h3 class="first-template-paragraphTitle Paragraph-paragraph-title height">
<div class="Text-text-wrapper">
<div class="Text-Text-text">{{'category.PersonalData' | translate}}</div>
</div>
</h3>
</div>
</div>
<div pageContent class="container-fluid">
<ng-container>
<app-personal-data [personalData]="personalData" [model]="model" [id]="id">
</app-personal-data>
</ng-container>
</div>
</div>
</div>
<!-- Career Component -->
<ng-container *ngFor="let careers of model.careers" class="Unit-unit-unitGroup">
<div pageContent class="col-md-12">
<div class="row height">
<div class="col-md-4 col-sm-6 text-right tLine"></div>
<h3 class="first-template-paragraphTitle Paragraph-paragraph-title height">
<div class="Text-text-wrapper">
<div class="Text-Text-text">{{'category.Career' | translate}}</div>
</div>
</h3>
</div>
</div>
<div class="container-fluid" pageContent>
<ng-container *ngFor="let careerObj of careers.subCategories; let i = index">
<app-career [careerObj]="careerObj" [id]="i" [career]="careers" [model]="model"></app-career>
</ng-container>
<ng-container *ngFor="let emptyObj of careers.emptySubContents; let iEmpty = index">
<app-empty-object [emptyObj]="emptyObj" [iEmpty]="iEmpty" [model]="model" [isFromCareer]="true"></app-empty-object>
</ng-container>
</div>
</ng-container>
<!--Education Component-->
<ng-container *ngFor="let education of model.education" class="Unit-unit-unitGroup">
<div pageContent [ngClass]="{ 'isCatActive': selectedCategory === category.Education}">
<ng-container *ngIf="selectedCategory === category.Education" clickOutside (clickOutside)="removeClick()">
<ul>
<li class="fa fa-plus addIconTop" (click)="openDialog()"></li>
<li class="fa fa-plus addIconBottom" (click)="openDialog()"></li>
<li class="fa fa-trash deleteIconRight" (click)="deleteCategory(index)"></li>
<li class="fa fa-arrow-down moveIconDown"></li>
<li class="fa fa-arrow-up moveIconTop"></li>
</ul>
</ng-container>
<div pageContent class="col-md-12" (click)="setCategory(category.Education)">
<div class="row height">
<div class="col-md-4 col-sm-6 text-right tLine"></div>
<h3 class="first-template-paragraphTitle Paragraph-paragraph-title height">
<div class="Text-text-wrapper">
<div class="Text-Text-text">{{'category.Education' | translate}}</div>
</div>
</h3>
</div>
</div>
<div pageContent class="container-fluid">
<ng-container *ngFor="let educationObj of education.subCategories; let i = index" class="col-md-12">
<app-education [educationObj]="educationObj" [id]="i" [education]="education" [model]="model"></app-education>
</ng-container>
</div>
</div>
</ng-container>
<!-- Skills Component-->
<ng-container *ngFor="let skills of model.skills" class="Unit-unit-unitGroup">
<div pageContent [ngClass]="{ 'isCatActive': selectedCategory === category.Skills}">
<ng-container clickOutside *ngIf="selectedCategory === category.Skills" (clickOutside)="removeClick()">
<ul>
<li class="fa fa-plus addIconTop" (click)="openDialog()"></li>
<li class="fa fa-plus addIconBottom" (click)="openDialog()"></li>
<li class="fa fa-trash deleteIconRight" (click)="deleteCategory(index)"></li>
<li class="fa fa-arrow-down moveIconDown"></li>
<li class="fa fa-arrow-up moveIconTop"></li>
</ul>
</ng-container>
<div pageContent class="col-md-12" (click)="setCategory(category.Skills)">
<div class="row height">
<div class="col-md-4 col-sm-6 text-right tLine"></div>
<h3 class="first-template-paragraphTitle Paragraph-paragraph-title height">
<div class="Text-text-wrapper">
<div class="Text-Text-text">{{'category.Skills' | translate}}</div>
</div>
</h3>
</div>
</div>
<div pageContent class="container-fluid">
<ng-container *ngFor="let skillObj of skills.subCategories; let i = index" class="col-md-12">
<app-skills [skillObj]="skillObj" [id]="i" [skills]="skills" [model]="model"></app-skills>
</ng-container>
</div>
</div>
</ng-container>
</app-paginated-view>
</div>
This is the CSS
.A4 {
width: 595px;
height: 842px;
padding: 25px 25px;
position: relative;
}
This is the json
{
"personalData": [
{
"firstName": "Max",
"lastName": "Muster",
"email": "max.musterman@outlook.com",
"birthday": "2020-09-25T00:00:00.000Z",
"telephone": "0123456789",
"job": "Freelancer",
"country": "Germany",
"postalCode": 12345,
"city": "None",
"title": 2,
"gender": 0,
"street": "Musterman 12",
"state": "",
"status": 1,
"showBirthday": true
}
],
"skills": [
{
"subCategories": [
{
"languages": [
{
"name": "languages.de",
"rate": 5
},
{
"name": "languages.al",
"rate": 1
},
{
"name": "languages.en",
"rate": 5
},
{
"name": "languages.fr",
"rate": 4
},
{
"name": "languages.it",
"rate": 4
}
],
"pcKnowledge": [
{
"_id": "5f5ca07e4dba443f786ea7ae",
"name": "Word"
},
{
"_id": "5f5ca07e4dba443f786ea7af",
"name": "Adobe Photoshop"
},
{
"_id": "5f5fd46bb21df2444c39f317",
"name": "Test"
},
{
"_id": "5f5fd46bb21df2444c39f318",
"name": "Excel"
},
{
"_id": "5f5fd46bb21df2444c39f319",
"name": "Ja"
},
{
"_id": "5f72339552009b4244391972",
"name": "Powerpoint"
}
],
"skillsOffer": [
{
"_id": "5f4a4e2d718d33092df2c327",
"name": "Angular"
},
{
"_id": "5f4a4e2d718d33092df2c327",
"name": "Java"
},
{
"_id": "5f4a4e2d718d33092df2c327",
"name": "Typescript"
},
{
"_id": "5f4a4e2d718d33092df2c327",
"name": "html"
},
{
"name": "Javascript"
}
],
"driveLicenses": [
{
"_id": "5f5ca07e4dba443f786ea7ac",
"name": "B"
},
{
"_id": "5f5ca07e4dba443f786ea7ad",
"name": "C"
},
{
"_id": "5f5f204faa5d0205180bd581",
"name": "B"
}
],
"name": "",
"qualifications": ""
}
]
}
]
}
And this is the Paginated view class for adding new page and splitting pages
<!-- display: none style will any child that does not have #pageContent local variable defined -->
<div class="content-wrapper" #contentWrapper style="display: block">
</div>
<div class="paginated-view" #paginatedView>
</div>
export class PaginatedViewComponent implements AfterViewInit {
@Input() pageSize: "A3" | "A4" = "A4";
@ViewChild("paginatedView") paginatedView: ElementRef<HTMLDivElement>;
@ViewChild("contentWrapper") contentWrapper: ElementRef<HTMLDivElement>;
@ContentChildren(PageContentDirective, { read: ElementRef })
elements: QueryList<ElementRef>;
constructor(private changeDetector: ChangeDetectorRef ) {}
ngAfterViewInit(): void {
this.updatePages();
// when ever childs updated call the updatePagesfunction
this.elements.changes.subscribe((el) => {
this.updatePages();
});
}
updatePages(): void {
// clear paginated view
this.paginatedView.nativeElement.innerHTML = "";
// get a new page and add it to the paginated view
let page = this.getNewPage();
this.paginatedView.nativeElement.appendChild(page);
let lastEl: HTMLElement;
// add content childrens to the page one by one
this.elements.forEach((elRef) => {
const el = elRef.nativeElement;
// if the content child height is larger than the size of the page
// then do not add it to the page
if (el.clientHeight > page.clientHeight) {
return;
}
// add the child to the page
page.appendChild(el);
// after adding the child if the page scroll hight becomes larger than the page height
// then get a new page and append the child to the new page
if (page.scrollHeight > page.clientHeight) {
page = this.getNewPage();
this.paginatedView.nativeElement.appendChild(page);
page.appendChild(el);
}
lastEl = el;
});
this.changeDetector.detectChanges();
// bring the element in to view port
// lastEl.scrollIntoView({ behavior: "smooth", block: "nearest" });
}
getNewPage(): HTMLDivElement {
const page = document.createElement("div");
page.classList.add("page");
page.classList.add(this.pageSize);
return page;
}
}
@Directive({
// tslint:disable-next-line: directive-selector
selector: "[pageContent]"
})
export class PageContentDirective {
}