AngularJS 4 ng Bootstrap - typeahead: use of [resultTemplate] can only handle a string? - ng-bootstrap

AngularJS 4 ng Bootstrap - typeahead: use of resultTemplate can only handle a string?
I want to do something like
[resultTemplate]="getMyTemplateString()"
But this causes weird broken render of a template.
The example only shows:
[resultTemplate]="rt"
which works.
Is there a way?

Look at the examples. "rt" is a id of a component
<ng-template #rt let-r="result" let-t="term">
<img [src]="'https://upload.wikimedia.org/wikipedia/commons/thumb/' + r['flag']" width="16">
{{ r.name}}
</ng-template>
ng-template #rt
So you can also handle a string.

Related

Angular calendar custom event style

I'm using angular calendar, and I want to customize the events style,for example- to change their shape to square instead of circle.
I tried this code:
<mwl-calendar-month-view [eventTitleTemplate]="customEventsStyle" [locale]="locale" [viewDate]="viewDate" [events]="events" (dayClicked)="dayClicked($event.day)" (eventClicked)="eventClick($event)">
{{ viewDate | calendarDate:(view + 'ViewTitle'):'Es' }}
</mwl-calendar-month-view>
<ng-template #customEventsStyle let-event="event">
<div class="cal-events">
<p style="background-color: brown;">{{event.title}}</p>
</div>
</ng-template>
But it didn't change anything in the style.
I also tried to change the css file in this path:
"../node_modules/angular-calendar/css/angular-calendar.css"
I changed the style of the .cal-month-view .cal-event class, but nothing happend.
I'm new for this issue, I'll be thankful if you could help me.
Thank you
I found it out!
I just added this code into the custom template instead of the div:
<ng-template #customCellTemplate let-day="day">
<mat-list *ngFor="let e of day.events">
<button class="customEvent" (click)="eventClick(e)">
{{e.title}}
</button>
</mat-list>
</ng-template>
<mwl-calendar-month-view [cellTemplate]="customCellTemplate"> ect...
Thanks

Applying CSS classes to custom day template in ng-bootstraps datepicker

So I am using ng-bootstraps datepicker to display some user data for each day. I use custom day template to apply certain CSS classes
<ng-template #customDay let-date>
<div
class="custom-day"
[ngClass]="evaluatePresenceType(date)"
>
{{ date.day }}
</div>
</ng-template>
The thing is this method is being called many times for each day which is less than optimal.
Is there a way to apply CSS class to every day just once, when the datepicker is being rendered and not every time I click anywhere?
When you want to use a custom template day to give some class to "specials days" you has two approach:
Use [ngClass] or [class.myClass]="function(date)" as you
indicate
Use DayTemplateData (see the docs)
Well, the doc is not very clear. The idea is to have a function,e.g.
data=(date: NgbDate, current?: {year: number, month: number})=>
{
//see that futhermore the "date" you has an object
//current with two properties: "year" and "month" that is showing
return this.calendar.getWeekday(date)>=6?'square':null
}
Then you use
<input class="form-control" [dayTemplateData]="data"
[dayTemplate]="customDay" ...>
And your template day pass the "data" using let-data=data
<ng-template #customDay let-date let-data="data" ...>
<span class="custom-day" [ngClass]="data" ...>
{{ date.day }}
</span>
</ng-template>
See that if you only want to apply an unique class your function can return true or null and use [class.myClass]="data"
In the stackblitz, I use the two approach and use two counters to show the improve of this another approach

How to open and hide ng-bootstrap datepicker on custom actions?

Currently I am using:
ng-bootstrap 1.0.0-alpha.24
angular/core 4.0.0
bootstrap 4.0.0-alpha.6
I wanted to ask if someone knows how to autoclose the datepicker
when the focus is lost or another datepicker is opened.
Also i wanted to now if it is possible to close the datepicker in the component code with typescript.
It would be nice if someone could provide a working plunker or a code snippet.
My actual implementation:
<div class="input-group">
<input class="rect-border full-width"
placeholder="YYMMDD"
[(ngModel)]="selectedDate"
ngbDatepicker
#datePickerInput="ngbDatepicker"
(keydown.arrowup)="incrementDate()"
(keydown.arrowdown)="decrementDate()"
(ngModelChange)="validate('modelChanged')"
(blur)="validate(null)"
[disabled]="disabled"
[ngClass]="{'input-required': required, 'normal-color': valid, 'picker-disabled': disabled}">
<div class="input-group-addon rect-border"
(click)="disabled ? true : datePickerInput.toggle()"
[ngClass]="{'picker-button-disabled': disabled}">
<img src="assets/img/calendar-icon.svg" class="datpickerToggle"/>
</div>
</div>
Plunker: ng-bootstrap team demo
I have searched a long time and I am also pretty new to angular and these things.
Thank you for your help!
Update:
Possible solution:
There were a lot of good solutions provided.
I also found out by myself that I could use the class NgbInputDatepicker
to close the datePicker (I always used NgbDatepicker, so it didn't work).
#ViewChild('datePickerInput') datePicker: NgbInputDatepicker;
this.datePicker.close();
you can open and close your datepicker from your html itself
for eg:
<div class="input-group">
<input class="rect-border full-width"
placeholder="YYMMDD"
[(ngModel)]="selectedDate"
ngbDatepicker
#datePickerInput="ngbDatepicker"
(keydown.arrowup)="incrementDate()"
(keydown.arrowdown)="decrementDate()"
(ngModelChange)="validate('modelChanged')"
(blur)="validate(null)"
[disabled]="disabled"
[ngClass]="{'input-required': required, 'normal-color': valid, 'picker-disabled': disabled}">
<div class="input-group-addon rect-border"
(click)="disabled ? true : datePickerInput.toggle()"
[ngClass]="{'picker-button-disabled': disabled}">
<img src="assets/img/calendar-icon.svg" class="datpickerToggle"/>
</div>
</div>
<div (click)="datePickerInput.open()"></div>
<span (click)="datePickerInput.close()"></span>
and also there are many functions which you can use in your html. some are close(), isOpen(), manualDateChange(), open(), toggle(), validate() etc. You can refer it in this plunkr http://plnkr.co/edit/G1b6fFrtVZwEz4lsou8n?p=preview
In typescript you can simply define a variable datepickerVisibility and then in your template use *ngIf to show or hide your datepicker component. Here is a demo code:
Template: <datepicker *ngIf="datepickerVisibility" [ngModel]="date"> </datepicker>
Component: private datepickerVisibility: boolean = false;
// Show the datepicker
showDatepicker() {
this.datepickerVisibility = true;
}
Edit:
Therefore you could use jQuery. Add the jQuery js into your index.html and in your typescript component use jQuery as follows:
declare let jQuery: any;
#Component({
moduleId: module.id,
selector: 'test',
templateUrl: 'template.html',
styleUrls: ['test.css'],
})
export class TestComponent {
constructor() {}
public toggleDatepicker() {
jQuery("#datepicker01").toggle();
}
}
And in your template file just add the id datepicker01 to your datepicker div
<div id="datepicker01" ...>
I was looking for a solution to this issue, but in a scenario where the datepicker is wrapped in a custom component and has to expose a function a parent component can call to toggle the datepicker. The answers provided are great and will work for most use case, but not mine, as I didn't want to add a jQuery dependency and calling toggle from the HTML isn't an option.
Here's how I solved it.
I added a ViewChild reference to the datepicker input in the *.component.ts file
#ViewChild('d', {static: true}) d;
that matches the datepicker identifier in the HTML file
<input (dateSelect)="dateSelected($event)" class="form-control" (focus)='d.toggle()' placeholder="yyyy-mm-dd" name="d"
[ngModelOptions]="{standalone: true}" [(ngModel)]="date" ngbDatepicker #d="ngbDatepicker">
and called the toggle function within a method exposed by the component
toggle() {
this.d.toggle();
}
That way, another component can call the toggle() function exposed by this component to toggle the datepicker like so:
In HTML
<app-custom-datepicker #date></app-custom-date-picker>
In .ts file
#ViewChild('date', {static: true}) date;
.
.
.
this.date.toggle();

Angular 2 + Semantic UI , component encapsulation breaks style

I'm using Angular2 with Semantic UI as a css library. I have this piece of code:
<div class="ui three stakable cards">
<a class="ui card"> ... </a>
<a class="ui card"> ... </a>
<a class="ui card"> ... </a>
</div>
the cards are rendered nicely with a space between and such.
like this: refer to cards section in the link
since the cards represent some kind of view I thought of making a component out of it, so now the code is:
<div class="ui three stakable cards">
<my-card-component></my-card-component>
<my-card-component></my-card-component>
<my-card-component></my-card-component>
</div>
but now the style is broken, there is no space between them anymore.
Is there any nice way of fixing this ?
the first thing I thought of doing is this:
my-card-component OLD template:
<a class="ui card">
[some junk]
</a>
|||
VVV
my-card-component NEW template:
[some junk]
and instantiating like:
<my-card-component class="ui card"></my-card-component>
or like:
<a href="?" my-card-component></a>
but this is not satisfactory since I want to be able to pass in an object and the component would automatically set the [href]=obj.link.
in AngularJS 1.0 there was a replace: true property which does excatly what i need, is there a similar thing in Angular2 ?
There is no replace=true in Angular2. It is considered a bad solution and deprecated in Angular 1.x as well.
See also Why is replace deprecated in AngularJS?
Use an attribute-selector instead of a tag-selector in your component or directive.
Just change
#Directive({ ..., selector: "my-card-component"})
to
#Directive({ ..., selector: "a[my-card-component]"})
and use it like
<a my-card-component class="ui card"> ... </a>
You might also adjust the encapsulation strategy http://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html but I think the default emulated should be fine in your case.
Solved it using #GünterZöchbauer Answer together with #HostBinding('href')
so now the code is:
template:
---------
[some junk]
component:
----------
#Component({
selector: 'a[my-card-component].ui.card',
templateUrl: 'urlOfSomeJunk.html',
directives: []
})
export class ProblemCardComponent {
#Input()
obj: MyObject;
#HostBinding('attr.href') get link { return this.obj.link; }
}
instantiating:
--------------
<a class="ui card" my-card-component [obj]="someBindingHere"></a>
that way the href is automatically bound to obj.link and I can rest in piece.

Handlebars.js pass html in expression

Handlebar template
<div>
{{contentText}}
</div>
JS
var contentText = {contentText: "<table><tr><td>Some Data<\/td><\/tr><\/table>"}
Handle bars render displays the HTML as string rather than rendering the HTML.
Where am I going wrong ?
From the fine manual:
Handlebars HTML-escapes values returned by a {{expression}}. If you don't want Handlebars to escape a value, use the "triple-stash", {{{.
So if you want to put contentText straight into the template as-is then you want:
<div>
{{{contentText}}}
</div>
in your template.
Demo: http://jsfiddle.net/ambiguous/f7LJ5/

Resources