Override a components template in Angular2/4? - javascript

If I detail the problem I'm trying to solve, it will help with my question.
I want to use HTML in the Angular Material tooltip, the current template doesn't enable this functionality:
<div class="mat-tooltip"
[ngClass]="tooltipClass"
[style.transform-origin]="_transformOrigin"
[#state]="_visibility"
(#state.done)="_afterVisibilityAnimation($event)">
{{message}}
</div>
In order to use HTML in the tooltip I'd like to override the template to the following:
<div class="mat-tooltip"
[ngClass]="tooltipClass"
[innerHTML]="message"
[style.transform-origin]="_transformOrigin"
[#state]="_visibility"
(#state.done)="_afterVisibilityAnimation($event)">
</div>
Is this possible? Is there another method I'm overlooking to achieve what I'm looking for?

The html file cannot be changed, however you can access the element from the component.ts file
#ViewChild('dataContainer') dataContainer: ElementRef;
loadData(data) {
this.dataContainer.nativeElement.innerHTML = data;
}
as found in thie SO-answer.

Related

Angular directives inside InnerHTML

I know its not possible to inject angular directive along html code inside inner html, is there any work around it? I'm trying to read the html and the directive from a html file and inject it inside a div, I thought about using component factory and create the component dynamically but the directive in the html file can be anywhere in the code not sure how I can append it to the right place in dom, I don't have much experience working with component factory so please let me know if there is a way.
ngOnInit(): void {
let loading = this.loadingService.addTask();
this.route.paramMap
.take(1)
.subscribe(params => {
let page: string = params.get("page") || "";
if (page) {
this.trainingService.getPageContent(page)
.take(1)
.subscribe(res => {
this.content = res;
this.loadingService.completeTask(loading);
})
}
else {
this.loadingService.completeTask(loading);
}
},
error => {
this.notificationService.error("Error retrieving training page", error);
this.loadingService.clearAllTasks();
})
here is my template
<div [innerHtml]="content"></div>
here is an html page example that should be injected (this is an external html page file)
<div class="row">
<div class="col-md-12">
<div class="panel panel-default b">
<div class="panel-body">
<div class="row">
<!--the directive-->
<sa-azure-media-player [source]="the link"></ss-azure-media-player>
</div>
</div>
</div>
</div>
</div>
There isn't a way to do this. The workaround would be to change the way you inject html. Instead of injecting as html, write a sub-component, give it the right info (as an [json-]object!), and off you go.
In case you do not have control of the incoming info (in your case html), you are forced to mould it into an object, so you can use it in angular.
In a recent project I had to have text content that might contain iframes (iframes don't work well in angular). The solution was to parse and save the content in the backend as a JSON-object containing text- and iframe-parts in the right order (that cost some time, unfortunately). Once I got hold of it in Angular, I could inject the texts and iframes of the JSON-object by using typescript. And, of course, do the right thing for the right element.
So, in case you have control over the incoming info (be it html or whatever kind of identifiable object), that's where you should change the procedure (and make full use of the angular MVC-stuff). In case you do not have control over that, please provide some more details as to what needs to be done and what the cicumstances are.

angular ngFor call javascript

I having HTML code like this
<div class="owl-carousel owl-theme owl-loaded">
<div class="owl-stage-outer">
<div class="owl-stage" *ngFor="let product of products; let i=index;">
<div class="owl-item">
<carouselFixture [stream]="product.stream" *ngIf="product.viewModelType == 'ProductSummary'" ></carouselFixture>
</div>
</div>
</div>
This is working fine. The problem I face is when the new product is added immediately it has to be shown in the owl carousel... actually it is loading but wrongly as shown in the image below
So to solve the problem we need to call the below add function in ngFor
$('#add').on('click', function () {
var html = '<div class=\"item\"><carouselFixture
[stream]="product.stream" *ngIf="product.viewModelType ==
'ProductSummary'" ></carouselFixture></div>';
console.log(html);
owl.trigger('add.owl.carousel', [html, 0])
.trigger('refresh.owl.carousel');
});
Can anyone tell me how to call this 'add' function...
AngularDart doesn't allow for dynamic components to be added to the page using pure html like that. This is for security, and performance reasons. It doesn't actually put the full angular engine in the page at runtime.
It does have other ways of doing this tho. The easiest is to add another entry onto the list and it will be displayed in the for loop.
The other possibility is to use the ComponentFactory to add it to the page https://webdev.dartlang.org/api/angular/angular/ComponentFactory-class
I'm not sure what owl is doing exactly in its call, but you could add the html without the angular component and use the component factory to insert it in the right place after owl does it's thing.

Bind Data to Template Defined in <script> Tag in AngularJS

I am trying to bind data to angular template. But I'm facing the following issue.
I am using $templateCache to retrieve the template but I cannot find data into the template.
$templateCache.get('q1.index.html');
Now, I am also trying to do $compile($templateCache.get('q1.index.html')); but I am getting Error: [jqLite:nosel] http://errors.angularjs.org/1.3.14/jqLite/nosel error.
Can someone please let me know what I am doing wrong & how can I resolve it.
You need to use this format for your <script> tag
<script type="text/ng-template" id="templateId.html">
<p>This is the content of the template</p>
</script>
then somewhere else you can retrieve with $templateCache
$templateCache.get('templateId.html')
Or via ng-include
<div ng-include="'templateId.html'"></div>

Dashlet edit button in titlebar not showing correctly

I am trying to create a simple Alfresco dashlet with an edit button enabled on the title bar. Unfortunately, I can not figure out how to get the edit button to actually display on the title bar.
Here is what I have so far:
dashlet desc file (.desc.xml)
<webscript>
<shortname>Sample</shortname>
<description>Displays a Sample dashlet</description>
<family>dashlet</family>
<url>/mycompany/components/dashlets/sample-dashlet</url>
</webscript>
My main freemarker template file (.ftl)
<script type="text/javascript">
//<![CDATA[
var sampleDashlet = new MyCompany.dashlet.SampleDashlet("${args.htmlid}").setOptions({
"componentId": "${instance.object.id}",
"siteId": "${page.url.templateArgs.site!""}",
"title": "${msg("header")}"
}).setMessages(${messages});
new Alfresco.widget.DashletResizer("${args.htmlid}", "${instance.object.id}");
var editDashletEvent = new YAHOO.util.CustomEvent("onDashletConfigure");
editDashletEvent.subscribe(sampleDashlet.onConfigClick, sampleDashlet, true);
new Alfresco.widget.DashletTitleBarActions("${args.htmlid}").setOptions({
actions: [{
cssClass: "edit",
eventOnClick: editDashletEvent,
tooltip: "${msg("dashlet.edit.tooltip")?js_string}"
}]
});
//]]>
</script>
<div class="dashlet-1">
<div> Test </div>
</div>
It seems as if the problem must be in my configuration somewhere, but I can't find it. Can anyone point me in the right direction, please?
If you want a working example of a very simple dashlet that is set up to be configurable in this way, see http://code.google.com/p/alfresco-get-latest-document. This blog post sets up the basic functionality: http://ecmarchitect.com/archives/2012/05/08/1592. And this blog post expands on that to make the initial dashlet configurable: http://ecmarchitect.com/archives/2012/05/15/1599.
In comparing your FTL with mine, I'm wondering if your div classes/id need to follow this pattern:
<div class="dashlet getlatestdoc">
<div id="getlatestdoc_title" class="title">
${title}
</div>
Otherwise, how will the edit button know where to render itself?
As Jeff suggests, you need to include a <div> element for the dashlet's title bar in your markup with an appropriate value for the class attribute, as follows
<div class="dashlet dashlet-1">
<div class="title">Title</div>
<div class="body">Body content</div>
</div>
When the Alfresco.widget.DashletTitleBarActions instance that your inline JavaScript code creates gets instantiated it will look for a child <div> with the class title and will add the actions there.
I also added a dashlet class to the parent div, which is required for the default dashlet styles to be applied.

Appending HTML to end of body using javascript

I have several templates for faceboxes (lightbox) that I need at different points of the application. These are stored in different partials and files.
I will initialize different javascript functions in accordance to which ones I need. The question is, what is the best way to append the external HTML page into my body using javascript?
Since you tagged the question with it, here's a jQuery solution.
$("body").append("text");
Remember that the parameter can also be a DOM element. So you can do this :
var p = $("<p/>").text("a paragraph");
$("body").append(p);
the easy way with jQuery is:
$('#result').load('test.html');
<div id="result"><!--/ Hold My Data! /--></div>
obviously you can change #result with body
Also you can try some templates library..
Like handlebar and underscore..
and append in the el provided by backbone.js
Suppose you want to append this html in your template, then you can use the below code according to your application
Consider the code
Example 1:
rowData += '<div style="width: 130px;">'+param1+'</div>';
rowData += '<div style="width: 130px;">'+param2+'</div>';
$('#ID').html(rowData);
and please make sure that the js should be include in that file.
Here is the information of variable used above:
row data - the html that you want to append,
param- if you want to show the value of java script variable on browser dynamically,
#ID- ID of the div in which you want to append this html
example 2:
Consider the following HTML:
<h2>Hello World</h2>
<div class="user">
<div class="inner">Hi</div>
<div class="inner">Bye</div>
</div>
You can create content and insert it into several elements at once:
$( ".inner" ).append( "<p>Lorem Ipsum</p>" );

Categories