Bergin
Bergin

Reputation: 187

HTML Binding from pipe in Angular 8

transform(value, type, headerSelectArray = [], valueToBeSelected, hasAction = false, functionName) {
        try {
            if (type === '_field') {
                return value;
            } else if (type === '_select_attribute') {
                let options;
                options = (`<select ` + `(click)="updateStatus()"` + `>`);
                headerSelectArray.forEach(element => {
                    options += `<option value="` + element.key + `" selected="` + (element.key === valueToBeSelected) + `" >` + element.label + `</option>`;
                });
                options += `</select>`;
                return this.sanatize.bypassSecurityTrustHtml(options);
            }

        } catch (e) {
            console.log('Error--', e);
        }
    }

This is my pipe function which returns html content based on some conditions. I am binding the data using the innerHtml property in my component.html section.

The issue I am facing is that the Click event is not binded with html. Click here

Upvotes: 0

Views: 3123

Answers (3)

Alex Biro
Alex Biro

Reputation: 1237

So you are trying to render HTML based on some parameters, right? In Angular, components do exactly that, and you shouldn't hack pipes to do that. Pipes are to create simple text values from data, see https://angular.io/guide/pipes

So just take the parameters that you pass in to your pipe, create a component instead of the pipe, and pass those params to the new component.

Also, whenever you manually create an html string, and then add it to the DOM via innerHtml, you misuse angular, the whole point of angular that you don't explicitly manipulate the DOM.

The click handler doesn't work, because the (click)="updateStatus() is not standard HTML and if you pass it with innerHtml the browser will not know what you are talking about. This click handler syntax only works inside an angular template, which you can have with a component.

Upvotes: 1

Wisely D Cruizer
Wisely D Cruizer

Reputation: 1149

You need to add this piece of code in your ngAfterViewChecked() function

ngAfterViewChecked (){
 if(this.elementRef.nativeElement.querySelector('.my-select')){
  this.elementRef.nativeElement.querySelector('.my-select').addEventListener('click', this. updateStatus.bind(this));
 }
} 

and in your constructor

 constructor(private elementRef:ElementRef){ }

and modify your code by adding an id attribute to your select

 transform(value, type, headerSelectArray = [], valueToBeSelected, hasAction = false, functionName) {
    try {
        if (type === '_field') {
            return value;
        } else if (type === '_select_attribute') {
            let options;
            options = (`<select class=`"my-select"` ` + `(change)="updateStatus()"` + `>`);
            headerSelectArray.forEach(element => {
                options += `<option value="` + element.key + `" selected="` + (element.key === valueToBeSelected) + `" >` + element.label + `</option>`;
            });
            options += `</select>`;
            return this.sanatize.bypassSecurityTrustHtml(options);
        }

    } catch (e) {
        console.log('Error--', e);
    }
}

Upvotes: 1

vcode
vcode

Reputation: 453

Inside the @component set encapsulation: ViewEncapsulation.None

@Component({
  selector: "component-selector",
  templateUrl: "./x.component.html",
  styleUrls: ["./x.component.css"],
  encapsulation: ViewEncapsulation.None
})

Upvotes: 0

Related Questions