#HostListener with touch event in directive is preventing the tap event in component (Only in iOS) - angular2-directives

I am trying to write a directive to change colour of a button on "Touchup" and "TouchDown". But when I attach this directive the (tap) event in the component is not getting called. This happens only in iOS. Is there any workarounds for this. Below is my directive and component.
import { Directive, HostBinding, HostListener, ElementRef, Renderer2 } from '#angular/core';
#Directive({
selector: '[btnTch]'
})
export class btnTchDirective {
constructor(private el: ElementRef, private renderer: Renderer2) { }
#HostListener('touch', ['$event'])
toggleColor(event){
if(event.action == "down"){
this.renderer.addClass(this.el.nativeElement, 'pressed');
// this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', "blue");
}else{
this.renderer.removeClass(this.el.nativeElement, 'pressed');
}
}
}
<ActionBar title="Login" actionBarHidden="false"></ActionBar>
<GridLayout columns="*" rows="auto, *, 130" width="100%" height="100%" class="login_bg">
<GridLayout columns="*" rows="*" verticalAlignment="center" horizontalAlignment="center">
<Label text="" style="border-radius:62; width:125; height:125; padding:0;margin-top:100; margin-bottom:10; background-color:white;opacity:0.1"></Label>
<Label text="" style="border-radius:50; width:100; height:100; padding:0;margin-top:100; margin-bottom:10; background-color:white;opacity:0.1"></Label>
</GridLayout>
<StackLayout col="0" row="1" verticalAlignment="center" style="width:80%">
<Label text="Enter Mobile Number"></Label>
<TextField hint="Enter Mobile Number" [(ngModel)]="userNum" style="border-bottom-width:1; border-style:solid; border-color: red; padding:5 0"></TextField>
<Label *ngIf="!genErrs == '' || null || undefined" text="{{genErrs}}"></Label>
</StackLayout>
<StackLayout col="0" row="2">
<Button text="SIGN IN" btnTch (tap)="Auth_for_OTP()"></Button>
<Label marginTop="15" horizontalAlignment="center" text="REQUEST FOR ACCESS" [nsRouterLink]="['/signup']" ></Label>
</StackLayout>
</GridLayout>

Related

Positioning actionbar items on android

I have this code
<template>
<Page>
<ActionBar title="Action Items">
<StackLayout orientation="horizontal">
<Image src="res://icon" width="40" height="40"
verticalAlignment="center" />
<Label text="NativeScript" fontSize="24"
verticalAlignment="center" />
</StackLayout>
<NavigationButton text="Go Back" android.systemIcon="ic_menu_back"
(tap)="onNavBtnTap()">
</NavigationButton>
<ActionItem (tap)="onShare()" ios.systemIcon="9"
ios.position="left" android.systemIcon="ic_menu_share"
android.position="actionBar">
</ActionItem>
<ActionItem (tap)="onDelete()" ios.systemIcon="16"
ios.position="right" text="delete" android.position="popup">
</ActionItem>
</ActionBar>
<ScrollView>
<StackLayout class="home-panel">
<!--Add your page content here-->
<Label textWrap="true" text="Play with NativeScript!"
class="h2 description-label">
{{first}}
</Label>
<Label textWrap="true"
text=" Write code in the editor or drag and drop components to build a NativeScript mobile application."
class="h2 description-label" />
<Label textWrap="true"
text="Scan the QR code with your mobile device and watch the changes sync live while you play with the code."
class="h2 description-label" />
</StackLayout>
</ScrollView>
</Page>
</template>
<script>
export default {
data() {
return {
first: "Once"
};
}
};
</script>
<style scoped>
.home-panel {
vertical-align: center;
font-size: 20;
margin: 15;
}
.description-label {
margin-bottom: 15;
}
</style>
which produces
My question is how come the back button aligned itself left and the others right without explicitly coding left or right?
<NavigationButton text="Go Back" android.systemIcon="ic_menu_back"
(tap)="onNavBtnTap()">
</NavigationButton>
and the other buttons are aligning to the right
<ActionItem (tap)="onShare()" ios.systemIcon="9"
ios.position="left" android.systemIcon="ic_menu_share"
android.position="actionBar">
</ActionItem>
<ActionItem (tap)="onDelete()" ios.systemIcon="16"
ios.position="right" text="delete" android.position="popup">
</ActionItem>
<NavigationButton/> is by default on the left, as it's just calls into the native setNavigationIcon api:
https://developer.android.com/reference/android/widget/Toolbar#setNavigationIcon(android.graphics.drawable.Drawable)
While the other <ActionItem> elements are added with the Menu api:
https://developer.android.com/reference/android/widget/Toolbar#getMenu()
For your other question, you can do the following:
<Label :text="`${first} Play with NativeScript!`" textWrap="true" class="h2 description-label" />
:text makes it a binding, the then you pass in a regular JavaScript string literal.
An alternative would be:
:text="first + ' Play with NativeScript!'"
Both ways should work fine.

Vue warn: Property or method "item" is not defined on the instance but referenced during render

im getting below error while i'm iterate CartItem.
Property or method "item" is
not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property
why this error is showing and how can i solve this.
[Note : this is a nativescript vue project]
<ListView
v-for="(item, index) in cartItems"
:key="index"
height="1000"
class="listCard"
>
<v-template>
<GridLayout
rows="auto"
columns="auto,*3,auto"
backgroundColor="white"
class="innerList"
>
<StackLayout orientation="horizontal" col="0" row="0">
<Button>
<FormattedString>
<Label
class="fa fas"
:text="'fa-trash' | fonticon"
fontSize="30"
></Label>
</FormattedString>
</Button>
<Image :src="item.imageUrl" height="80" width="auto"></Image>
</StackLayout>
<StackLayout col="1" row="0">
<Label
:text="item.title"
textWrap="true"
class="font-weight-bold"
color="#333333"
></Label>
<Label :text="item.color" color="#999999"></Label>
<Label :text="'USD ' + item.price" color="red"></Label>
</StackLayout>
<StackLayout orientation="horizontal" col="2" row="0">
<Button
text="-"
#tap="onDecriment(index)"
class="operatorButton operatorBox"
marginRight="0"
/>
<Label
class="operatorLabel operatorBox"
:text="item.quantity">
</Label>
<Button
text="+"
#tap="onIncrement(index)"
class="operatorButton operatorBox"
marginLeft="0"
/>
</StackLayout>
</GridLayout>
</v-template>
</ListView>
I don't see any error in your code but can you try using for instead of v-for. I see in this example, Listview is being using with for.
As per docs: If a v-for is used on a <ListView> a warning will be printed to the console, and it will be converted to the **for** property. you can read more about Listview with for here
<ListView
for="(item, index) in cartItems"
:key="index"
height="1000"
class="listCard"
>
....

Nativescript-vue Video Player loading complete callback not working

I am building native mobile app using nativescript-vue and using Nativescript-videoplayer plugin .Well the player working well but loadingComplete callback function is not working.
<template>
<Page >
<ActionBar title="test">
<StackLayout orientation="horizontal"
ios:horizontalAlignment="center"
android:horizontalAlignment="left">
<Image src="res://icon" width="30" height="30" stretch="aspectFill" />
</StackLayout>
</ActionBar>
<StackLayout>
<VideoPlayer ref="player" :src="video.file" autoplay="true" height="300" #loadingComplete="videoCompleted" #finished="videoFinished" loop="false" />
</StackLayout>
</Page>
</template>
<script >
export default {
props:['video'],
data() {
return {
}
},
methods:{
videoCompleted(){
console.log('Loading Completed');
},
videoFinished(){
console.log('Video finished');
}
}
}
</script>
loadingComplete was changed to playbackReady and the other handler attaches to finishedEvent
<VideoPlayer
#playbackReady="videoCompleted"
#finishedEvent="videoFinished"
/>
The demo is quite outdated, but the documentation looks mantained.

nativescript-youtubeplayer toggle fullscreen in nativescript-vue app

I'm trying to do a fullscreen in youtube player from the plugin triniwiz/nativescript-youtubeplayer in my nativescript-vue application on android device but I'm unable to achieve so.
I have following code:
<template>
<Page actionBarHidden="true" class="page" >
<GridLayout orientation="vertical" width="100%" height="100%" columns="*" rows="*,auto">
<StackLayout col="0" row="0" backgroundColor="#f8f8f8">
<StackLayout backgroundColor="#44557f">
<Label :text="name" class="font-weight-bold"
color="#FFFFFF" padding="15" fontSize="20" textWrap="true"></Label>
</StackLayout>
<ScrollView orientation="vertical" height="100%">
<ScrollView orientation="vertical">
<StackLayout class="home-panel">
<YoutubePlayer ref="player" :src="videoLink.substring(17)" apiKey="**********" isFullScreen="true"/>
</StackLayout>
</ScrollView>
</ScrollView>
</StackLayout>
</GridLayout>
</Page>
</template>
<script>
export default {
props: ['videoLink','name','id'],
mounted() {
let player = this.$refs.player
player.toggleFullscreen();
}
}
</script>
But I'm getting an error stating
toggleFullscreen() not found
When you access an element via Ref, the return value will be a Vue element. You should access the nativeView to gain access to the actual element.
<script>
export default {
props: ['videoLink','name','id'],
mounted() {
let player = this.$refs.player.nativeView;
player.toggleFullscreen();
}
}
</script>

Tabview not showing data in first tab in nativescript-vue

I have place a Tabview in my component with 2 tabs. In the first i'm loading some data from an API and render a ListView with data. In the other tab i'm showing some other data.
The data from the API is not showing when the component is first show, I have tab press the tab 2 and then tab 1 and the data is then shown.
<template>
<Page class="page">
<TabView :selectedIndex="selectedIndex"
#selectedIndexChange="indexChange">
<TabViewItem title="Tab 1">
<StackLayout orientation="vertical">
<ListView height="90%" class="list-group"
for="item in allCategories">
<v-template>
<StackLayout class="list-group-item"
orientation="horizontal">
<Image :src="item.imageURL"
stretch="aspectFill" class="categoryImage"
width="75" height="75">
</Image>
<Label class="categoryText"
:text="item.element.groupText"/>
</StackLayout>
</v-template>
</ListView>
</StackLayout>
</TabViewItem>
<TabViewItem title="Tab 2">
<Label text="Content for Tab 2" />
</TabViewItem>
</TabView>
</Page>
</template>
created: function () {"url").then(result => {
result.data.forEach(element => {
var imageURL = element.image.imageURL;
this.allCategories.push({element, imageURL })
});
}, error => {
console.log(error);
});
},
I want the data to be show when the component is first show because the tab 1 is marked as the showing tab. Any ideas?
Here is an example in the playground: https://play.nativescript.org/?template=play-vue&id=9Fk7AS&v=10
The answear is in the issue I commited for the repository in github: https://github.com/nativescript-vue/nativescript-vue/issues/515
Just change:
<TabView :selectedIndex="selectedIndex" #selectedIndexChange="indexChange">
To:
<TabView>