How to get the native control in RadSideDrawer with nativescript angular2? - angular2-nativescript

I have a RadSideDrawer and I want to apply a directive to a Control that is in the MainContent of the RadSideDrawer.
Here is my Component using a RadSideDrawer.
<RadSideDrawer>
<StackLayout tkDrawerContent class="sideStackLayout">
<StackLayout class="sideTitleStackLayout" backgroundGradient [gradientColors]="['red','blue']">
<Image horizontalAlignment="center" class="avatar" src="res://avatar"></Image>
<Label horizontalAlignment="center" class="name" text="Zeeko"></Label>
<Label horizontalAlignment="center" class="email" text="1519560753#qq.com"></Label>
</StackLayout>
<StackLayout>
<StackLayout orientation="horizontal">
<Label [text]="'fa-file-text' | fonticon" class="fa icon"></Label>
<Label class="side-item-lbl" text="我的简历"></Label>
</StackLayout>
<Label class="side-item-lbl" col="2" row="2" text="已投递"></Label>
</StackLayout>
</StackLayout>
<StackLayout tkMainContent>
<Button text="OPEN DRAWER" (tap)=openDrawer()></Button>
<Label text="欢迎来到主页" textWrap="true"></Label>
</StackLayout>
And here is my directive.
Directive
Then I got unexpected ElementRef in the Directive's ngOnInit method, whoes nativeElement property is undefined.
If you can help me, I'll be very grateful.

You can take a look at the RadSideDrawer sdk angular examples of the nativescript-telerik-ui plugin here.
More specifically you can get the RadSideDrawerComponent in the component code like so:
import { Component, ViewChild, AfterViewInit } from "#angular/core";
import { RadSideDrawerComponent, SideDrawerType } from "nativescript-telerik-ui-pro/sidedrawer/angular";
#Component({
moduleId: module.id,
selector: "tk-sidedrawer-getting-started",
templateUrl: 'getting-started.component.html',
styleUrls: ['getting-started.component.css']
})
export class SideDrawerGettingStartedComponent implements OnInit {
constructor() {
}
#ViewChild(RadSideDrawerComponent) public drawerComponent: RadSideDrawerComponent;
private drawer: SideDrawerType;
ngAfterViewInit() {
this.drawer = this.drawerComponent.sideDrawer;
}
public openDrawer() {
this.drawer.showDrawer();
}
}
Copied from here.

Related

In nativescript-angular how to check whether <ng-content> is empty?

in my nativescript-angular project I have a component like this:
<StackLayout>
<Label *ngIf="ngContentIsEmpty"> ng-content is empty </Label>
<ng-content></ng-content>
</StackLayout>
Now, I would like to display some content if <ng-content> for this component is empty.Is there an easy way to do this?
I've tried this but not work in nativescript:
<StackLayout #wrapper>
<Label *ngIf="wrapper.childNodes.length == 0"> ng-content is empty </Label>
<ng-content></ng-content>
</StackLayout>
Try to this for check ng-content is empty.
Add In Html File:-
<StackLayout *ngIf="ngContentIsEmpty">Content</StackLayout>
<StackLayout #wrapper>
<ng-content></ng-content>
</StackLayout>
In TypeScript File:-
export class MyComponent implements OnInit, AfterContentInit {
#ContentChild('wrapper') wrapper:ElementRef;
public ngContentIsEmpty = false;
ngAfterContentInit() {
this.ngContentIsEmpty= this.wrapper.childNodes.length > 0;
}
}

Disable item in ListView

I have an application written in NativeScript with Angular 2. In it I have a list view like this:
<ListView row="1" [items]="items" (itemTap)="onNavigationItemTap($event)" class="root-drawer-content">
<ng-template let-item="item">
<StackLayout class="root-item-stack-layout">
<Label [text]="item.title" textWrap="true" class="btn btn-primary" [class.btn-active]="item.enabled"></Label>
<StackLayout height="1" class="root-drawer-content"></StackLayout>
</StackLayout>
</ng-template>
</ListView>
How can I force specific item to be disabled? Both visually and in terms of behavior.
You are almost there. As you are using item.enabled property to choose the btn-active class, you can apply the same logic to for disabled(Your custom one e.g change the background color to gray to look disabled) to StackLayout.
<ng-template let-item="item">
<StackLayout class="root-item-stack-layout" [class.enabled]="item.enabled">
<Label [text]="item.title" textWrap="true" class="btn btn-primary" [class.btn-active]="item.enabled"></Label>
<StackLayout height="1" class="root-drawer-content"></StackLayout>
</StackLayout>
</ng-template>
And for the functionality, you can handle that in your .ts file where your manage the itemTap.
(itemTap)="onNavigationItemTap($event)"
public onNavigationItemTap(args) {
const currentItemView = args.view;
const item = currentItemView.bindingContext;
if(item.enabled){
// do your stuff
}

Angular/material autocomplete: options do not render

Angular version: 5.0.0
angular/material version: 5.2.4
I've got this form:
<form #updateForm="ngForm">
<mat-form-field>
<input type="text" matInput [formControl]="studentFormControl [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let student of students" [value]="student">
{{student}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
And I've got this component:
import { FormGroup, FormControl, FormsModule, ReactiveFormsModule } from '#angular/forms';
import { MatInputModule, MatAutocompleteModule, MatFormFieldModule } from '#angular/material';
export class DashboardComponent implements OnInit {
this.studentFormControl = new FormControl();
this.students = ['hi', 'hello'];
...
}
Although the form shows up, the autocomplete box remains dimensionless without options rendered within:
screenshot of input/autocomplete box
It should be noted as well that the form is nested within an ngbModal. Any ideas what could be happening here?
So I'm no expert here, but from what I understand, the autocomplete function requires an observable of sorts, at least if you want to be able to filter results as you type, to be selected. Since you are using an array you need to first turn it into an observable. As your array is loaded immediately you would need to use RXJS's subjects and more specifically the BehaviorSubject.
Once it becomes an observable you can then call it using the asyncpipe on your form.
This is not to say you couldn't have done it with an array and not used the asyncPipe, however that array would have to be loaded in OnInit.
See the example for both
import { Observable, from, Subscription, BehaviorSubject } from 'rxjs';
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormControl, FormsModule, ReactiveFormsModule } from '#angular/forms';
import { MatInputModule, MatAutocompleteModule, MatFormFieldModule } from '#angular/material';
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {
studentFormControl = new FormControl();
studentFormControl1 = new FormControl();
array = ['test','one','two'];
array1=[];
arrayObs: Observable<any>;
arrayBehObs = new BehaviorSubject(this.array);
constructor() { }
ngOnInit() {
this.array1.push('test','one','two');
this.arrayObs = this.returnAsObs();
}
private returnAsObs() {
return this.arrayBehObs.asObservable();
}
}
<form #updateForm="ngForm">
<input type="text" matInput [formControl]="studentFormControl" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let student of arrayObs|async" [value]="student">
{{student}}
</mat-option>
</mat-autocomplete>
<input type="text" matInput [formControl]="studentFormControl1" [matAutocomplete]="auto1">
<mat-autocomplete #auto1="matAutocomplete">
<mat-option *ngFor="let student of array1" [value]="student">
{{student}}
</mat-option>
</mat-autocomplete>
</form>

How to detect clickable label position inside listview xamarin forms

I'm trying to do something like this
Like This
I have Listview with clicked label " Edit " I want when i click this label it's position is detected and display
label at Aliaddress is clicked
I Used TapGestureRecognizer for this but when i google it i fount that selected item doesn't work with TapGesture
This is my xaml
<ListView ItemsSource="{Binding UserAdresses}" SelectedItem="{Binding SelectedAddress}" HorizontalOptions="{Binding HoriRLLR}" RowHeight="{Binding RowHeight}" VerticalOptions="FillAndExpand">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout VerticalOptions="FillAndExpand">
<Label Text="{Binding Country}" TextColor="Orange" FontSize="Large" FontAttributes="Bold"></Label>
<Label Text="{Binding Address}" TextColor="Black" FontSize="Medium"></Label>
<Label Text="{Binding City}" TextColor="Black" FontSize="Medium"></Label>
<Label Text="{translator:Translate Edit}" TextColor="Black" FontSize="Medium">
<Label.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Path=BindingContext.EditAddressesCommand, Source={x:Reference CustomerAdressesPage}}"/>
</Label.GestureRecognizers>
<Label.Effects>
<controls:UnderlineEffect></controls:UnderlineEffect>
</Label.Effects>
</Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
my code
public DelegateCommand EditAddressesCommand => new DelegateCommand(EditAddresses);
public DelegateCommand DeleteAddressesCommand => new DelegateCommand(DeleteAddresses);
private readonly IPageDialogService _dialogService;
private ObservableCollection<CustomerAdressesModel> _userAdresses;
public ObservableCollection<CustomerAdressesModel> UserAdresses
{
get { return _userAdresses; }
set { SetProperty(ref _userAdresses, value);
}
}
private CustomerAdressesModel _selectedAddress;
public CustomerAdressesModel SelectedAddress
{
get { return _selectedAddress; }
set { SetProperty(ref _selectedAddress, value); }
}
private void EditAddresses()
{
_dialogService.DisplayAlertAsync("Test", "Edit Clicked", "Ok");
}
How can i do this and detect the position of clicked label
You can use this: CommandParameter="{Binding .}" inside TapGestureRecognizer
Xaml:
<Label.GestureRecognizers>
<TapGestureRecognizer
CommandParameter="{Binding .}"
Command="{Binding Path=BindingContext.EditAddressesCommand, Source={x:Reference CustomerAdressesPage}}"/>
</Label.GestureRecognizers>
ViewModel:
public ICommand EditAddressesCommand
{
get
{
return new Command<YourModel>((YourModel model) =>
{
//Access your model properties
});
}
}
Hope this may solve your problem.

Angular form input value undefined

I'm trying to get the value of an input field in my first ever Angular form, but it is always undefined, and I can't figure out why. I'm importing FormsModule correctly, and I can reference the form object fine, so I must be missing something obvious.
My components HTML
<form #searchValue='ngForm' class="" (ngSubmit)='submitSearch(searchValue)'>
<div>
<input type="text" name="q" placeholder="search">
</div>
</form>
And my components ts method (Shortened)
import { Component, OnInit } from '#angular/core';
import { FormsModule } from '#angular/forms';
#Component({
selector: 'google-search',
templateUrl: './google.component.html',
styleUrls: ['./google.component.css']
})
export class GoogleComponent implements OnInit {
constructor() { }
ngOnInit() {
}
submitSearch(formData) {
console.log(this.searching);
console.log(formData.value.q);
}
}
Any ideas to why this is?
You need to mark the input with ngModel so angular will know that this is one of form's controls:
<input type="text" ngModel name="q" placeholder="search">
Or you can define the variable first in your component, and then bind the input to it via [(ngModel)] directive:
export class GoogleComponent implements OnInit {
q: string;
submitSearch() {
console.log(this.q);
}
}
<form class="" (ngSubmit)='submitSearch()'>
<div>
<input type="text" name="q" [(ngModel)]="q" placeholder="search">
</div>
</form>
One way binding (just [ngModel]="q") could be enough if you just want to read the value from input.
Some like this should work..
Maybe you want to read about model binding and forms.
html component
<form #searchValue='ngForm' class="some-css-class" (ngSubmit)='submitSearch()'>
<div>
<input type="text" name="q" [(ngModel)]="searchValue" placeholder="search">
<input type="submit" name="btn" placeholder="Submit">
</div>
</form>
In component.ts
import { Component, OnInit } from '#angular/core';
import { FormsModule } from '#angular/forms';
#Component({
selector: 'google-search',
templateUrl: './google.component.html',
styleUrls: ['./google.component.css']
})
export class GoogleComponent implements OnInit {
searchValue: string = '';
constructor() { }
ngOnInit() { }
submitSearch() {
console.log(this.searchValue);
}
}