Angular 9: create custom directive that uses other standard directives - html

I am working to a little framework based on Angular/Material 9. I want to create custom directives that apply standard Material directives to their host element. For some UI elements, I prefer to use directives instead of creating custom wrapper components (using ng-content). For example, for buttons, I want use a "custom-button" directive like this:
<button type="button" custom-button>Hello world!</button>
The directive should apply the standard Material directives (and some other attribute, too) for buttons to the host element. The rendered HTML button should be:
<button type="button" custom-button mat-button mat-raised-button color="accent">Hello world!</button>
I know how to set properties/attributes, but obviously the button does not act like a "real" mat-button (it hasn't custom inner elements added by Material, nor the for the ripple effect).
I am pretty new with Angular, so I searched a lot for an answer. But I only found very complicated or outdated solutions (AngularJS). Any help?

Related

Rendering html content in matToolTip (Angular)

I want to bold some contents in the popup. But is not interpreted instead is being displayed among the content
Is there any other way, leaving matToolTip to provide popup over hover in Angular
<button [matTooltip]="help|translate" type="button" mat-button class="button-save" [disabled]="!isInfoAvailable">
<mat-icon>help_outline</mat-icon>
</button>
Expected output
firstname mike
lastname ross
Actual output
<b>firstname <\b> mike <\n>
<b>lastname <\b> ross
I think native Angular Material Tooltips don't allow HTML code, so I suggest you to use an other provider for the Tooltips, there are a lot of those who allows HTML code like ng-bootstrap or tippy.js
I personally suggest you to use Tippy.js, here's the link where you can see how use HTML code on it.
https://atomiks.github.io/tippyjs/#html-content
Hope it helps you.
If you need simple customization (changing background-color, color, font-size...) for the whole tooltip you can read this post otherwise you can read this answer ⬇️
A similar post already exists: Angular 2 Material tooltip with HTML content in angular
What you are looking for is a Popover. And as said, it doesn't exist now and it's not possible with tooltips.
Answer from #jelbourn, Angular member team:
When designing the tooltip we deliberately decided not to support
this. The Material Design spec is rather prescriptive about only text
appearing in tooltips. Rich content also presents a challenge for
a11y.
Source: https://github.com/angular/components/issues/5440#issuecomment-313740211
You can find the feature request for popover here.
Until an official release from Material team you can use an alternative. Here are some examples:
https://github.com/joejordanbrown/popover (documentation here)
https://github.com/ncstate-sat/popover
https://github.com/maxisam/ngx-mat-popover (using Material Menu)
https://ng.ant.design/components/popover/en (ng-zorro lib)

Thymeleaf - get dom element attributes

I create html components with Thymeleaf. Components are declared in separate file:
Declaration of basic button in buttons.html
<div th:fragment="btn-basic" class="btn btn-basic" th:text="${text}" th:classappend="${class}">
Button
</div>
The idea is to provide some type of tool-set for components. Code for using this component will be:
<div th:replace="~{buttons :: btn-basic (text='Button Text', class='button-class')}"></div>
It's working well, but I think about case when button need to have attributes like: onclick="..." or data-customAttr="..." or any other attribute. And here goes the problem:
How to pass attributes to button?
One way is to pass it as parameter of fragment, but it's too ugly.
Is there any way to get attributes of placeholder in fragment? (see example below)
This how I want to call fragment:
<div th:replace="~{buttons :: btn-basic (text='Button Text', class='button-class')}" onclick="..." data-customAttr="..."></div>
and in btn-basic fragment want to get these attributes and attach to it. Something like this:
<div th:fragment="btn-basic" class="btn btn-basic" th:text="${text}" th:classappend="${class}" onclick="..." data-customAttr="...">
Button
</div>
Any ideas?
I had a similar idea, but the question is, if the customizing of a component is as complex as the result, what is the benefit?
Btw. with the Thymeleaf Layout Dialect you can do something like this: https://ultraq.github.io/thymeleaf-layout-dialect/Examples.html#reusable-templates, I favor that, instead of the everything-as-parameter approach.

Why bootstrap uib dropdown won't work with the select element

When I run my angularJS (ver 1.4.9) app without the uib-.. directives, the select works but displays the items already open and the button does nothing.
It won't integrate with the dropdown menu component. All the examples I've seen use the unordered list and list item structure and the bootstrap UI dropdown appears based around the ui and li elements leading to the obvious question - why those elements and not select, option elements.
I would like to keep this: ng-options="e for e in vm.plannedEmployees track by e"
as I know it works and took a week of hacking to find it (though I don't understand it's complexity)
<div class="btn-group" uib-dropdown>
<button class="btn btn-primary" uib-dropdown-toggle>
<span class="caret"></span>
</button>
<select ng-options="e for e in vm.plannedEmployees track by e"
multiple="multiple" ng-model="selectedEmployee"
ng-change="vm.employeeSelectClick(selectedEmployee)">
</select>
</div>
All the examples I've seen use the unordered list and list item structure and the bootstrap UI dropdown appears based around the ui and li elements leading to the obvious question - why those elements and not select, option elements.
The uib-bootstrap project is aimed to port the bootstrap plugins into Angular directives, the bootstrap style defines the Dropdown by using a <ul> and <li> elements and uses CSS that select/target these elements, the uib directives just replace the jQuery code you would use in a non Angular page.
Also, in a UI sense, a select is not the same as a dropdown, in Angular sense, a select is an input that would normally expose an ngModel, uib-dropdown doesn't expose an ngModel (and subsequently, won't allow you to use directives that require it, such an ngChange or ngModelOptions).
That being said, you may want to look at ui-select as an alternative.

Customizing the alert box

<button type="button" onclick="alert('ex.HELLO')">PRESS ME</button>
-------------------------
need help with this
I want to customize the alert box that appears when I press a button, how?
There is no ability to customize the styling or css of an 'alert', the default visuals for this is down to the system/browser interpretation of this.
You can however create your own Modal/Alert (how to here: https://www.w3schools.com/howto/howto_css_modals.asp)
If your site includes Bootstrap, you can just use theirs which offers the ability to customize it with their helper classes and if needed your own CSS. http://getbootstrap.com/javascript/#modals

How to use attribute appendTo in primeNG in component ContextMenu?

I´m trying to use the attribute appendTo in the component ContextMenu, but I want attach the behavior to one element, like a div.
on the element u want to append to add a hashtag #myHashTag
and on the prime element u want to append add:
[appendTo]="myHashTag" <- without the # sign
example:
<div class="recording-control-button" #stopbutton></div>
<p-confirmDialog [appendTo]="stopbutton"></p-confirmDialog>
I'm presuming you're using Angular 2?
Based on the information on the api for primeng context menu here:
PrimeNg context menu
You need to use a Angular 2 template variable, see here:
Angular 2 HTML variables
I try this and it works - [appendTo]="'body or template or any Id'"
For example:
<div #largeModal></div> - define anywhere in html, but in your project
Define this menu primeng in your html
<ng-template let-item="rowData" <p-menu #menu popup="popup" [model]="items"></p-menu> <button type="button" pButton icon="fa fa-list" label="Show" [appendTo]="'largeModal'" (click)="menu.toggle($event)"></button> </ng-template>