Reputation: 1184
I am facing a problem, I want to render generated HTML code, into material table with Pipe, but it is not working.
the code looks like this:
pipe.ts
import { Pipe, PipeTransform } from "@angular/core";
import * as _ from "underscore";
@Pipe({ name: "customPipeChecks" })
export class CustomPipeChecks implements PipeTransform {
transform(
elementValue: {},
elementProperty: string,
object: {},
customPipeFunction: any,
defaultValue: string
) {
if (customPipeFunction != null && _.isFunction(customPipeFunction)) {
console.log(customPipeFunction(elementValue, elementProperty, object));
return customPipeFunction(elementValue, elementProperty, object);
} else {
if (defaultValue) {
return defaultValue;
}
return elementValue;
}
}
}
the generated function
private setCustomValueFunction() {
this.customValueFunction = (
elemValue: string,
elemKey: string,
elem: {}
) => {
if (elemKey === "vin") {
elemValue = "<button>zrdzdrz</button>";
}
return elemValue;
};
}
this function generates a HTML string.
the HTML code looks like this :
<td
mat-cell
*matCellDef="let cellData"
class="{{
cellData[colName]
| customPipeChecks: colName:cellData:customCssFunction:' '
}}"
innerHtml="{{
cellData[colName]
| customPipeChecks: colName:cellData:customValueFunction
}}">
</td>
When the app is loaded, it will shown only 'zrdzdrz' only the text (inner HTML of the desired button), without the button (that is suppoused to wrap the text).
Any suggestion?
Best Regards,
Leo
Upvotes: 1
Views: 453
Reputation: 3588
Very interesting question.
Here is a demo at StackBlitz that will fix your problem.
The reason why your implementation doesn't work is because angular is sanitizing the injected HTMl, in order to bypass this, your custom pipe should look like the snippet bellow, where the important part is the usage of DomSanitizer
which will "tell" the framework in explicit manner that you want to inject HTML
that must be rendered.
import { Pipe, PipeTransform } from "@angular/core";
import {
DomSanitizer,
SafeHtml
} from '@angular/platform-browser';
@Pipe({ name: "customPipeChecks" })
export class CustomPipeChecks implements PipeTransform {
constructor(
public sanitizer: DomSanitizer,
) { }
transform() {
return this.sanitizer.bypassSecurityTrustHtml('<button>Button content</button>')
}
}
One more notable point is that in the template you must inject the innerHTML
in the following manner, [innerHTML]
<td mat-cell *matCellDef="let element" [innerHtml]="'someString' | customPipeChecks">
</td>
Upvotes: 2