Reputation: 95
I am trying to add product images on clicking the add button in screen and to remove using delete button. These should be loaded dynamically when user clicks add or delete button. But when I dynamically inject html and bind click event it's not working. On clicking it, function is not calling. I have simplified the code below. HTML file:
<div class="product_images">
<div class="imageHeading">
<p>
Images
</p>
</div>
<div class="kt-form__group">
<div class="row">
<div class="col-lg-2 imageLabel">Main Image</div>
<div class="col-lg-3 imageLabel">Choose Image</div>
<div class="col-lg-2 imageLabel">Image</div>
<div class="col-lg-2 imageLabel">Actions</div>
</div>
</div>
<div class="imagesContainer" [innerHtml]="containerToAdd | sanitizeHtml">
</div>
</div>
Ts file
// Angular
import { Component, OnInit, ElementRef, ViewChild, ChangeDetectionStrategy, OnDestroy, ChangeDetectorRef } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
// Material
import { SelectionModel } from '@angular/cdk/collections';
import { MatPaginator, MatSort, MatSnackBar, MatDialog, MatRadioButton } from '@angular/material';
import { ProductManagementService } from '../../../../../core/e-commerce/_services/product-management.service';
import { ToastrService } from 'ngx-toastr';
import { ViewEncapsulation } from '@angular/core';
@Component({
selector: 'kt-product-edit',
templateUrl: './product-edit.component.html',
styleUrls: ['./product-edit.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class ProductEditComponent implements OnInit {
previewUrl : any = "/assets/media/images/noimage.jpg";
containerToAdd : string = "";
constructor(
private products: ProductManagementService,
private router: Router,
private route: ActivatedRoute,
private toastr: ToastrService,
private cdr: ChangeDetectorRef,
private FB: FormBuilder,
) {
}
ngOnInit() {
this.addImage();
}
addImage(){
this.containerToAdd = `
"<div class="kt-form__group image-container container-1">
<div class="row">
<div class="col-lg-2"><input type="checkbox" /></div>
<div class="col-lg-3"><input type="file" accept="image/*" (change)="imagePreview($event)" /></div>
<div class="col-lg-2"><img [src]="previewUrl" class="prod_image" /></div>
<div class="col-lg-2">
<span class="deleteElement" (click)="deleteImage()">
Del
</span>
</div>
</div>
</div>"`;
}
deleteImage() {
console.log("deleteImage");
}
}
When I click that span with that click event, deleteImage() function is not calling.
Upvotes: 1
Views: 6555
Reputation: 275
i think it helps and you would add some code in your favour:
html:
<div class="product_images">
<div class="imageHeading">
<p>
Images
</p>
</div>
<div class="kt-form__group">
<div class="row">
<div class="col-lg-2 imageLabel">Main Image</div>
<div class="col-lg-3 imageLabel">Choose Image</div>
<div class="col-lg-2 imageLabel">Image</div>
<div class="col-lg-2 imageLabel">Actions</div>
</div>
</div>
<div class="imagesContainer" #elementRef>
</div>
</div>
ts:
@ViewChild("elementRef", { static: true }) deletableItem: ElementRef<
HTMLDivElement
>;
containerToAdd: any;
previewUrl: any;
constructor(private sanitizer: DomSanitizer, private renderer: Renderer2) {}
ngOnInit() {
this.addImage();
}
ngAfterViewInit() {}
addImage() {
let span: HTMLSpanElement = this.renderer.createElement("span");
this.renderer.addClass(span, "deleteElement");
this.renderer.listen(span, "click", () => {
console.log("I am going to delete you");
});
span.innerHTML = "Del";
let divHoldsSpan: HTMLDivElement = this.renderer.createElement("div");
this.renderer.addClass(divHoldsSpan, "col-lg-2");
this.renderer.appendChild(divHoldsSpan, span);
let image: HTMLImageElement = this.renderer.createElement("img");
this.renderer.addClass(image, "prod_image");
image.src = this.previewUrl;
let divHoldsImage: HTMLDivElement = this.renderer.createElement("div");
this.renderer.addClass(divHoldsImage, "col-lg-2");
this.renderer.appendChild(divHoldsImage, image);
let imageInput: HTMLInputElement = this.renderer.createElement("input");
imageInput.type = "file";
imageInput.accept = "image/*";
this.renderer.listen(imageInput, "change", event => {
// console.log("YOUR FILE,SIR:",e.target.files);
for (let index = 0; index < event.target.files.length; index++) {
let reader = new FileReader();
const fileToUpload = event.target.files[index];
reader.onload = (e: any) => {
image.src = e.target.result;
};
reader.readAsDataURL(event.target.files[index]);
}
});
let divHoldsImageInput: HTMLDivElement = this.renderer.createElement("div");
this.renderer.addClass(divHoldsImageInput, "col-lg-3");
this.renderer.appendChild(divHoldsImageInput, imageInput);
let checkboxInput: HTMLInputElement = this.renderer.createElement("input");
checkboxInput.type = "checkbox";
let divHoldsCheckbox: HTMLDivElement = this.renderer.createElement("div");
this.renderer.addClass(divHoldsCheckbox, "col-lg-2");
this.renderer.appendChild(divHoldsCheckbox, checkboxInput);
let divRow: HTMLDivElement = this.renderer.createElement("div");
this.renderer.addClass(divRow, "row");
this.renderer.appendChild(divRow, divHoldsCheckbox);
this.renderer.appendChild(divRow, divHoldsImageInput);
this.renderer.appendChild(divRow, divHoldsImage);
this.renderer.appendChild(divRow, divHoldsSpan);
let divKtForm = this.renderer.createElement("div");
this.renderer.addClass(divKtForm, "kt-form__group");
this.renderer.addClass(divKtForm, "image-container");
this.renderer.addClass(divKtForm, "container-1");
this.renderer.appendChild(divKtForm, divRow);
this.renderer.appendChild(this.deletableItem.nativeElement, divKtForm);
}
deleteImage() {
console.log;
}
Upvotes: 1
Reputation: 236
You are binding to the innerHtml so any angular syntax in the html you are using for binding is not going to work as it is not a compile angular template. So your click binding is invalid. A simple *ngIf should be good.
<div class="product_images">
<div class="imageHeading">
<p>
Images
</p>
</div>
<div class="kt-form__group">
<div class="row">
<div class="col-lg-2 imageLabel">Main Image</div>
<div class="col-lg-3 imageLabel">Choose Image</div>
<div class="col-lg-2 imageLabel">Image</div>
<div class="col-lg-2 imageLabel">Actions</div>
</div>
</div>
<div class="imagesContainer" [innerHtml]="containerToAdd | sanitizeHtml">
<div class="kt-form__group image-container container-1" *ngIf="addImage">
<div class="row">
<div class="col-lg-2">
<input type="checkbox" />
</div>
<div class="col-lg-3">
<input type="file" accept="image/*" (change)="imagePreview($event)" />
</div>
<div class="col-lg-2"><img [src]="previewUrl" class="prod_image" /></div>
<div class="col-lg-2">
<span class="deleteElement" (click)="deleteImage()">
Del
</span>
</div>
</div>
</div>
</div>
</div>
export class MyComponent{
previewUrl : any = "/assets/media/images/noimage.jpg";
public addImage = false
constructor(
private products: ProductManagementService,
private router: Router,
private route: ActivatedRoute,
private toastr: ToastrService,
private cdr: ChangeDetectorRef,
private FB: FormBuilder) {
}
ngOnInit() {
this.addImage();
}
addImage(){
this.addImage = true;
}
deleteImage() {
this.addImage = false
console.log("deleteImage");
}
}
<div class="product_images">
<div class="imageHeading">
<p>
Images
</p>
</div>
<div class="kt-form__group">
<div class="row">
<div class="col-lg-2 imageLabel">Main Image</div>
<div class="col-lg-3 imageLabel">Choose Image</div>
<div class="col-lg-2 imageLabel">Image</div>
<div class="col-lg-2 imageLabel">Actions</div>
</div>
</div>
<div class="imagesContainer">
<div class="kt-form__group image-container container-1" *ngFor="let image of images; let index = i">
<div class="row">
<div class="col-lg-2">
<input type="checkbox" />
</div>
<div class="col-lg-3">
<input type="file" accept="image/*" (change)="imagePreview($event, image)" />
</div>
<div class="col-lg-2"><img [src]="previewUrl" class="prod_image" /></div>
<div class="col-lg-2">
<span class="deleteElement" (click)="deleteImage(i)">
Del
</span>
</div>
</div>
</div>
</div>
</div>
export class MyComponent{
previewUrl : any = "/assets/media/images/noimage.jpg";
public images = []
constructor(
private products: ProductManagementService,
private router: Router,
private route: ActivatedRoute,
private toastr: ToastrService,
private cdr: ChangeDetectorRef,
private FB: FormBuilder) {
}
ngOnInit() {
this.addImage();
}
addImage(){
this.images.push({});
}
deleteImage(index: number) {
this.images.splice(index, 1)
console.log("deleteImage");
}
imagePreview($event, image){
image.path = event.value;
}
}
Upvotes: 2