How do I show through *ngIf - nativescript

I want to trigger the *ngIf function through my home.component.ts.
html
<GridLayout class="page">
<GridLayout row="0" rows="*, 2*, *">
<GridLayout width="57%" row="0" horizontalAlignment="center" verticalAlignment="center">
<button (click)="test()" text="testbutton"></button>
</GridLayout>
<GridLayout class="carousel-item-circle" row="1" horizontalAlignment="center" verticalAlignment="center">
<label class="fa carousel-item-icon" text="" textWrap="true"></label>
</GridLayout>
<GridLayout *ngIf="testi" width="49%" row="2" horizontalAlignment="center" verticalAlignment="center">
<Label class="text-color-blue opensans-regular carousel-item-desc" text="Mikrofon zum Sprechen antippen." textWrap="true"></Label>
</GridLayout>
</GridLayout>
ts
public vibrator = new Vibrate();
public testi = true;
constructor(private page: Page) {
// Use the component constructor to inject providers.
}
ngOnInit(): void {
this.page.actionBarHidden = true;
this.page.addCss(".page-content { background: #000000");
}
vibrate(){
this.vibrator.vibrate(2000);
}
test(){
this.testi = !this.testi;
}
It seems so simple but it doesnt work.
Is there something i missed?

You need to make the variable true/false on click
Write in Your HTML file
<button (click)="test()">Click</button>
<span *ngIf="testi">NG IF</span>
Write in Your TS file
First Declare testi as
testi = false
test(){
testi = true;
}
Using *ngIf you can show the element whenever it is true or not empty, if it is false or empty then it will not display element in browser
Hope this will solve your problem, Thanks

NativeScript Button uses tap not click. So in your code test() is never called.
<button (tap)="test()" text="testbutton"></button>
Refer the getting started guide and go through the available UI components to understand the core differences.

Related

Nativescript-Vue ScrollView scrollable height is always 0. My goal is to scroll it to bottom since it's a Chat App

In my Nativescript-Vue application, I have a ListView within a ScrollView, defined as such:
<Page>
<ActionBar :title="friend.name">
<NavigationButton text="Go Back" android.systemIcon="ic_menu_back" #tap="$navigateBack"/>
</ActionBar>
<ActivityIndicator busy="true" v-if="isLoading" />
<StackLayout v-else orientation="vertical" >
<ScrollView ref="scrollLayout" class="scrollLayout" height="90%" orientation="vertical">
<ListView minHeight="90%" ref="listLayout" class="listLayout" for="item in conversations">
<v-template>
<GridLayout columns="*" rows="auto" class="msg">
<StackLayout :class="currentUser.id == item.user_id? 'me' : 'them'" orientation="horizontal" :horizontalAlignment="currentUser.id == item.user_id? 'right' : 'left'">
<Label :text="item.chat" class="msg_text" textWrap="true" verticalAlignment="top" />
</StackLayout>
</GridLayout>
</v-template>
</ListView>
</ScrollView>
<StackLayout height="10%" class="chat-box">
<GridLayout columns="*,auto" style="padding: 5" verticalAlignment="center">
<TextField hint="Enter message..." class="chatTextField" row="0" col="0" v-model="message"></TextField>
<Button row="0" col="1" text="send" #tap="scollToBottom"></Button>
</GridLayout>
</StackLayout>
</StackLayout>
</Page>
I already looked into this question by adding minHeight but it does not work on my case.
This is the method code to scroll to bottom but the scrollableHeight is always 0
scollToBottom() {
this.scrollLayout.nativeView.scrollToVerticalOffset(this.scrollLayout.nativeView.scrollableHeight, false);
console.log(this.$refs.scrollLayout.nativeView.scrollableHeight)
},
Hello I found a solution for this. I use ListView to scroll to the latest chat by using this code: Based on this [link]: https://docs.nativescript.org/vuejs/ns-ui/ListView/scrolling
scollToBottom () {
// in order to avoid race conditions (only on iOS),
// in which the UI may not be completely updated here
// we use this.$nextTick call
this.$nextTick(() => {
const indexToScroll = this.conversations.length - 1;
console.log('Programmatic scrolling to ' + this.conversations[indexToScroll].chat + '... ');
this.$refs.listLayout.nativeView.scrollToIndex(indexToScroll, false);
});
},
That's what I've implemented in my app which is not ideal but it works. I had to add a setTimeout for it to scroll. The messages are again wrapped in a Scroll View:
scrollToBottom() {
setTimeout(() => {
let scroll = this.$refs.scrollLayout.nativeView.scrollableHeight //get the height of the scroll area
console.log("Height changed " + scroll)
this.$refs.scrollLayout.nativeView.scrollToVerticalOffset(scroll, false) //scroll to the last message
}, 1000)
}

how to set gridlayout from js from a string of layout defined

I'm trying to set a grid layout as below in xml
layout: `<GridLayout row="0" rows="*, 2*, *">
<GridLayout width="57%" row="0" horizontalAlignment="center" verticalAlignment="center">
<Label class="lobster-regular carousel-item-head" text="Welcome to Payments App" textWrap="true"></Label>
</GridLayout>
<GridLayout class="carousel-item-circle" row="1" horizontalAlignment="center" verticalAlignment="center">
<Label class="fa carousel-item-icon" text="" textWrap="true"></Label>
</GridLayout>
<GridLayout width="49%" row="2" horizontalAlignment="center" verticalAlignment="center">
<Label class="opensans-regular carousel-item-desc" text="Let's see a quick overview of our features." textWrap="true"></Label>
</GridLayout>
</GridLayout>
`,
so i created a scroll view from js and tried to add content to it as below. but its giving stackerror.
also i found that https://play.nativescript.org/?template=play-js&id=sRSad7&v=162 here they implemented same thing. but difficult to understand.
but when i tried the similar thing i'm not able to do so, here is my project link. https://play.nativescript.org/?template=play-js&id=GbN2TT
const myScroll = new ScrollView();
myScroll.orientation = "vertical";
console.log(homeViewModel.layout);
myScroll.content = homeViewModel.layout;
please give me in detail suggestion and answer or alternative to achieve this.
Use UI Builder
const layout = `<GridLayout row="0" rows="*, 2*, *">
<GridLayout width="57%" row="0" horizontalAlignment="center" verticalAlignment="center">
<Label class="lobster-regular carousel-item-head" text="Welcome to Payments App" textWrap="true"></Label>
</GridLayout>
<GridLayout class="carousel-item-circle" row="1" horizontalAlignment="center" verticalAlignment="center">
<Label class="fa carousel-item-icon" text="" textWrap="true"></Label>
</GridLayout>
<GridLayout width="49%" row="2" horizontalAlignment="center" verticalAlignment="center">
<Label class="opensans-regular carousel-item-desc" text="Let's see a quick overview of our features." textWrap="true"></Label>
</GridLayout>
</GridLayout>
`;
const builder = require("tns-core-modules/ui/builder");
const gridLayout = builder.parse(layout);
myScroll.content = gridLayout;

builder.parse() with bindingContext

I have the following code:
private loadSlides(): Promise<any> {
return new Promise((resolve, reject) => {
const component = builder.parse(slideTemplate);
component.bindingContext = {
content: 'HHAHAAHA'
};
resolve(component);
});
}
and this is the value for slideTemplate:
export const slideTemplate: string = `
<GridLayout row="0" rows="*, 2*, *">
<GridLayout width="57%" row="0" horizontalAlignment="center" verticalAlignment="center">
<Label class="lobster-regular carousel-item-head" [text]="content" textWrap="true"></Label>
</GridLayout>
</GridLayout>
`;
Now when I bind the value from my template it only shows empty string.
Why is that so?
You can not use Angular template / binding syntax with builder.parse(...), it's created outside Angular context.
Since you are using bindingContext which is NativeScript Core way of handling data binding, you should use text="{{ content }}"
export const slideTemplate: string = `
<GridLayout row="0" rows="*, 2*, *">
<GridLayout width="57%" row="0" horizontalAlignment="center" verticalAlignment="center">
<Label class="lobster-regular carousel-item-head" text="{{ content }}" textWrap="true"></Label>
</GridLayout>
</GridLayout>
`;
I'm unsure why you may need builder here, I would suggest sticking with Angular components if possible.

How to customize tabview in nativescript?

How can i dock my Tabview items to the left of the screen like in the image below?
This is how my layout looks like currently.
<TabView dock="left" tabsBackgroundColor="red" selectedIndex="1" selectedColor="#FF0000" iosIconRenderingMode="alwaysOriginal" sdkExampleTitle sdkToggleNavButton>
<StackLayout tabsBackgroundColor="red" *tabItem="{ iconSource: 'res://ic_ham'}" >
</StackLayout>
<StackLayout *tabItem="{title: 'Home'}">
<ns-home></ns-home>
</StackLayout>
<StackLayout *tabItem="{title: 'Bookings'}">
<ns-booking></ns-booking>
</StackLayout>
</TabView>
Resulting layout
It may be a bit of overkill for your needs, but what I've found simplest for us was to change the tab buttons to be fully designable and customizable by disabling the current buttons and the add new tab buttons.
<StackLayout class="grid-tab-view" columns="*,100,100,100,*" ios:rows="auto, auto" android:rows="auto, *">
<label row="0" col="1" class="tab-button" text="Tab1" (tap)="switchTabByIndex(0)" [ngClass]="{'selected': tabSelectedIndex===0}"></label>
<label row="0" col="2" class="tab-button" text="Tab2" (tap)="switchTabByIndex(1)" [ngClass]="{'selected': tabSelectedIndex===1}"></label>
<label row="0" col="3" class="tab-button" text="Tab3" (tap)="switchTabByIndex(2)" [ngClass]="{'selected': tabSelectedIndex===2}"></label>
<TabView colSpan="5" row="1" col="0" #tabView class="tab-view" [(ngModel)]="tabSelectedIndex" (loaded)="onTabsLoaded()" (selectedIndexChanged)="onTabSwitch($event)">
<StackLayout class="tab" *tabItem="{title: 'Tab1'}">
<Label text="tab1 body"></Label>
</StackLayout>
<StackLayout class="tab" *tabItem="{title: 'Tab2'}">
<Label text="tab2 body"></Label>
</StackLayout>
<StackLayout class="tab" *tabItem="{title: 'Tab3'}">
<Label text="tab3 body"></Label>
</StackLayout>
</TabView>
</StackLayout>
And in code:
Add tap event handlers for when button selected and give it a custom selected class (for styling)
Hide the default tab buttons using the tabs loaded event:
onTabsLoaded(): void{
let tabViewElement = <TabView>this.tabView.nativeElement;
if (tabViewElement && tabViewElement.android) {
tabViewElement.android.removeViewAt(0);
} else {
tabViewElement.ios.tabBar.hidden = true;
}
};
and with a bit of css, our result:
Hope this helps, good luck!

Binding Context not working Nativescript

there is no error in console, I've tried many things but cannot understand the actual problem with code. Can anybody help me in this.. and emulator snippets and code below:
home.ts:
enter code here
import {EventData,Observable} from "data/observable";
import {Page} from "ui/page";
var page : Page;
var tempSessions = [
{
id:"0",
title:"session 0"
},{
id:"1",
title:"session 1"
},{
id:"2",
title:"session 2"
}];
export function pageLoaded(args:EventData) {
page = <Page>args.object;
page.bindingContext = new Observable({
sessions:tempSessions
});
}
home.xml:
<Page xmlns="http://schemas.nativescript.org/tns.xsd" load="pageLoaded">
<GridLayout rows="auto,*">
<!--row 0-->
<StackLayout></StackLayout>
<!--row 1-->
<GridLayout rows="auto,*" row="1">
<ListView items="{{ sessions }}">
<ListView.itemTemplate>
<Label text="item"/>
</ListView.itemTemplate>
</ListView>
</GridLayout>
</GridLayout>
</Page>
emulator
I found several issues in your code. The first one is that the page event is called loaded instead load. The second one is that you could use ObservableArray Module, which would auto update the ListView when you push new item in the array. You could review the NativeScript Getting Started Guide
main-page.xml
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded">
<GridLayout rows="auto,*">
<!--row 0-->
<StackLayout row="0">
<Label text="sample text" textWrap="true" />
</StackLayout>
<!--row 1-->
<GridLayout rows="*" row="1">
<ListView row="0" items="{{ sessions }}">
<ListView.itemTemplate>
<StackLayout>
<Label text="{{title}}"/>
</StackLayout>
</ListView.itemTemplate>
</ListView>
</GridLayout>
</GridLayout>
</Page>
main-page.ts
import {EventData,Observable} from "data/observable";
import {ObservableArray} from "data/observable-array";
import {Page} from "ui/page";
var page : Page;
var tempSessions = new ObservableArray();
export function pageLoaded(args:EventData) {
tempSessions.push({
id:"0",
title:"session 0"
});
tempSessions.push({
id:"1",
title:"session 1"
});
tempSessions.push({
id:"2",
title:"session 2"
});
page = <Page>args.object;
page.bindingContext = new Observable({
sessions:tempSessions
});
}

Resources