hi i need to toggle individual content in listview when the respective button is clicked in nativescript angular,
i added bellow my code. if anyone know please answer me. thanks in advance
import { Component, OnInit } from "#angular/core";
import { Item } from "./item";
import { ItemService } from "./item.service";
#Component({
selector: "ns-items",
moduleId: module.id,
templateUrl: "./items.component.html",
})
export class ItemsComponent implements OnInit {
items: Item[];
isList = true;
toggle(){
this.isList = !this.isList;
}
constructor(private itemService: ItemService) { }
ngOnInit(): void {
this.items = this.itemService.getItems();
}
}
and here my items.component.html
<ActionBar title="My App" class="action-bar">
</ActionBar>
<StackLayout class="page">
<ListView [items]="items" class="list-group">
<template let-item="item">
<GridLayout columns="auto,auto" width="210" height="210" >
<Label [text]="item.name" col="0"
class="list-group-item" visibility="{{isList ? 'visible' : 'collapse'}}"></Label>
<Button [text]="isList ? 'hide' : 'Show'" col="1" (tap)="toggle()"></Button>
</GridLayout>
</template>
</ListView>
</StackLayout>
here problem is when i click the button all the labels are toggle. so i need to generate the variable dynamically. i m very beginner so anyone can help me?
thank in advance.
Guess you have modified the starter template. So if you want hide label on particular list item, try this.
Add visible property to item.ts
export class Item {
id: number;
name: string;
role: string;
visible: boolean;
}
Set value to visible in your item.service.ts. It will be like below.
{ id: 1, name: "Ter Stegen", role: "Goalkeeper", visible: true },
{ id: 3, name: "Piqué", role: "Defender", visible: true },
Your list template should be
<template let-item="item">
<GridLayout class="list-group-item" columns="*,auto">
<Label col="0" [text]="item.name" [visibility]="item.visible ? 'visible' : 'collapse'"></Label>
<Button class="btn" col="1" [text]="item.visible ? 'Hide' : 'Show'" (tap)="toggle(item)"></Button>
</GridLayout>
</template>
And finally the toggle method will be,
ngOnInit(): void {
this.items = this.itemService.getItems();
}
toggle(item: Item) {
item.visible = !item.visible;
}
Related
Good day,
I having problem in angular-nativescript shared code project.
the model and components works fine but the output is not as i expected
i think the problem is in my view(Homecomponent.tns.html)
I have an angular model contains list of object(products) inside a object(ProductGroup) here is structure
product group:
export class ProductGroup {
public groupName : string;
public products : ProductItem[];
}
ProductItem:
export class ProductItem {
public itemDescription : string;
public remarks : string;
}
i already pre-populate it inside my component ngOnInit
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css'],
})
export class HomeComponent implements OnInit {
public productGroups : ProductGroup[];
ngOnInit() {
///initiate group
this.productGroups = [];
///insert some items for testing
this.productGroups.push
(
{
groupName : "Cars",
products : [
{ itemDescription : "Car", remarks : "" },
{ itemDescription : "Car1",remarks : "" },
{ itemDescription : "Car2",remarks : "" }
]
},
{ groupName : "Trucks",products : [
{ itemDescription : "Truck", remarks : "" },
{ itemDescription : "Truck1",remarks : "" },
{ itemDescription : "Truck2", remarks : ""}]
}
);
//trying to check if it is properly populated
console.log(this.productGroups);
}
}
i already console.log the product groups and it seems populated and should work fine.
but im trying to output all the productItem inside the listview with the header of the group name but the it only output like this
_________________________________________________
Cars
Car
_________________________________________________
Trucks
Truck
_________________________________________________
here is my components.tns.html
<ActionBar>
<ActionItem title="Test"></ActionItem>
</ActionBar>
<StackLayout>
<GridLayout columns="*" >
<ListView [items] = "productGroups">
<ng-template let-group="item" >
<StackLayout>
<Label [text]="group.groupName"></Label>
<StackLayout>
<ListView [items] = "group.products">
<ng-template let-products="item">
<Label [text]="products.itemDescription"></Label>
</ng-template>
</ListView>
</StackLayout>
</StackLayout>
</ng-template>
</ListView>
</GridLayout>
</StackLayout>
Im hoping that my question makes sense to you guys. im just expecting output like this
_________________________________________________
Cars
Car
Car1
Car2
_________________________________________________
Trucks
Truck
Truck1
Truck2
_________________________________________________
Hoping to have someone help me regarding this
thanks for your help in advance
Try nativescript-accordion plugin. If you like all the items to be expanded by default, create an array with all indexes and apply it to selectedIndexes property.
tns plugin add nativescript-accordion
I have created a sample playground for you here. It's working fine on ios.
<GridLayout>
<ListView class="list-group" [items]="productGroups" (itemTap)="onItemTap($event)"
style="height:1250px">
<ng-template let-group="item">
<StackLayout >
<Label [text]="group.groupName"></Label>
<StackLayout>
<ListView [items]="group.products">
<ng-template let-products="item">
<Label [text]="products.itemDescription"></Label>
</ng-template>
</ListView>
</StackLayout>
</StackLayout>
</ng-template>
</ListView>
</GridLayout>
Need grid to be something like this:
card1 card2
card3 card4
...
And to be dynamic
Here is my try:
component:
export class MenusComponent implements OnInit {
public menus: any;
constructor() {
this.menus = [
{
image: 'https://www.ducksdailyblog.com/wp-content/uploads/2018/12/Wooden-Post-Country-Fences-Direction.jpg',
title: 'Jelovnik'
},
{
image: 'https://www.ducksdailyblog.com/wp-content/uploads/2018/12/Wooden-Post-Country-Fences-Direction.jpg',
title: 'Pica'
},
{
image: 'https://www.ducksdailyblog.com/wp-content/uploads/2018/12/Wooden-Post-Country-Fences-Direction.jpg',
title: 'Dorucak'
}
]
}
Here is my try:
<GridLayout columns="*,*" rows="*">
<ListView class="list-group" [items]="menus">
<ng-template let-menu="item" let-i="index" let-odd="odd" let-even="even">
<StackLayout [col]="even ? 0 : 1">
<Label [text]="menu.title"></Label>
<Image height="108" width="100%" [src]="menu.image"></Image>
</StackLayout>
</ng-template>
</ListView>
I need to be able to add mre things inside list view so I assume there should be anoter grid as well. What is the right way to do this? Cards need to be equal and to take whole screen.
Using ListViewStaggeredLayout works for me here is the ref: https://docs.nativescript.org/angular/ui/ng-components/ng-radlistview/item-layouts
I’m new to NativeScript so please excuse me if I’m asking a stupid question. I tried to figure it out using google for days now but had no success.
On the bottom of the app I have some labels with icon font. So what I want to do is to change the label color when clicked.
Screenshot
Here is my app.components.ts
import { Component } from "#angular/core";
import * as dockModule from "tns-core-modules/ui/layouts/dock-layout";
import { TNSFontIconService } from 'nativescript-ng2-fonticon';
import {topmost} from "ui/frame";
import {Page} from "ui/page";
#Component({
selector: "my-app",
template: `
<!-- <ActionBar title="Rupa GIS" class="action-bar" font-size= "7"></ActionBar> -->
<ActionBar title="Rupa GIS" android.icon="res://icon" android.iconVisibility="always" class="action-bar" ></ActionBar>
<!-- Your UI components go here -->
<Page class="pg">
<DockLayout class="formMessag">
<GridLayout class="formMessage1" columns="2*,2*,2*,2*" rows="" dock="bottom" verticalAlignment="bottom" class="mdi" >
<Label class="mdi1" id="dd" [text]="'mdi-map' | fonticon" row="0" col="0" (tap)="onTapMap()" backgroundColor="transparent" verticalAlignment="center" horizontalAlignment="center" ></Label>
<Label class="mdi2" [text]="'mdi-camera' | fonticon" row="0" col="1" (tap)="onTapCam()" backgroundColor="transparent" verticalAlignment="center" horizontalAlignment="center" ></Label>
<Label class="mdi3" [text]="'mdi-info' | fonticon" row="0" col="2" (tap)="onTapInfo()" backgroundColor="transparent" verticalAlignment="center" horizontalAlignment="center" ></Label>
<Label class="mdi4" [text]="'mdi-settings' | fonticon" row="0" col="3" (tap)="onTapSett()" backgroundColor="transparent" verticalAlignment="center" horizontalAlignment="center" ></Label>
</GridLayout>
</DockLayout>
</Page>
`
})
export class AppComponent {
// Your TypeScript logic goes here
// var isSelected = "true";
onTapMap(dd) {
// boolean isSelected = true;
let self = this;
console.log("MAPA");
}
onTapCam() {
console.log("KAMERA");
}
onTapInfo() {
console.log("INFORMACIJE");
}
onTapSett() {
console.log("PODESAVANJA");
}
constructor(private fonticon: TNSFontIconService, private page: Page) {
page.actionBarHidden = true;
}
}
export function pageLoaded() {
console.log("DOBAR DAN!");
}
And here is my app.module.ts
import { NgModule, NO_ERRORS_SCHEMA } from "#angular/core";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { TNSFontIconModule } from 'nativescript-ng2-fonticon';
import { AppComponent } from "./app.component";
#NgModule({
declarations: [AppComponent],
bootstrap: [AppComponent],
imports: [
NativeScriptModule,
TNSFontIconModule.forRoot({
'mdi': 'material-design-icons.css'
})
],
schemas: [NO_ERRORS_SCHEMA],
})
export class AppModule {}
And here is the main.ts
And here is the main.ts
import { platformNativeScriptDynamic } from "nativescript-angular/platform";
import { AppModule } from "./app.module";
platformNativeScriptDynamic().bootstrapModule(AppModule);
How could I make it so that the onTapMap function changes the color of a label? Any advise or guidance would be greatly appreciated.
Thank you!
Srdjan
You can apply class based on tap events -
<Label class="{{ checkYes ? 'redColor' : 'defaultColor'}}" id="dd"
[text]="'mdi-map' | fonticon" row="0" col="0" (tap)="onTapMap()"
backgroundColor="transparent" verticalAlignment="center"
horizontalAlignment="center" ></Label>`
here i've changed the css class impl. -
class="{{ checkYes ? 'redColor' : 'defaultColor'}}"
on tap event make this variable checkYes true or false and in your css file define two classes as -
.redColor {
color:red;
}
.defaultColor {
color:gray
}
and for function onTapMap() -
onTapMap() {
if(this.checkYes)
this.checkYes = false;
else
this.checkYes = true;
}
I have a login button which when clicked will log the user in by making http calls to the server.
While this is happening I want the activity indicator to show up and disable the button and every other thing on the page and just show the activity indicator over it.
Note that I will place time outs and other measures to make sure that the Activity indicator doesn't end up trapping the user.
Also, I do not want the content in the background to disappear. I just want the activity indicator to overlap it.
Here is my ui code which was taken for this SO answer https://stackoverflow.com/a/39124735/4412482
<GridLayout>
<StackLayout>
//page content goes here
</StackLayout>
</StackLayout>
<StackLayout class="dimmer" visibility="{{showLoading ? 'visible' : 'collapsed'}}"></StackLayout>
<GridLayout rows="*" visibility="{{showLoading ? 'visible' : 'collapsed'}}">
<ActivityIndicator busy="true" width="50" height="50" color="#0c60ee"></ActivityIndicator>
</GridLayout>
</GridLayout>
To disable the events to the components you could use isUserInteractionEnabled property, which will disable the whole interaction to the component and then you could show the ActivityIndicator. I am providing sample code below.
app.component.html
<GridLayout rows="*">
<StackLayout row="0" class="p-20">
<Label text="Tap the button" class="h1 text-center"></Label>
<Button text="TAP" (tap)="onTap()" class="btn btn-primary btn-active" [isUserInteractionEnabled]="buttoninteraction" ></Button>
<Label [text]="message" class="h2 text-center" textWrap="true"></Label>
</StackLayout>
<ActivityIndicator row="0" [busy]="acstate" row="1" class="activity-indicator"></ActivityIndicator>
</GridLayout>
app.component.ts
import { Component } from "#angular/core";
#Component({
selector: "my-app",
templateUrl: "app.component.html",
})
export class AppComponent {
public counter: number = 16;
public buttoninteraction = true;
public acstate = false;
public get message(): string {
if (this.counter > 0) {
return this.counter + " taps left";
} else {
return "Hoorraaay! \nYou are ready to start building!";
}
}
public onTap() {
this.counter--;
this.buttoninteraction=false;
this.acstate=true;
}
}
Hope this helps.
I was following this guide to create a a nativescript custom component http://moduscreate.com/custom-components-in-nativescript/ but it's not working for me
I have a folder pages with a folder inside it called main.
main has a couple of files
main.html
<StackLayout
xmlns="http://schemas.nativescript.org/tns.xsd"
xmlns:hello="pages/helllo"
loaded="pageLoaded" >
<hello:hello/>
</StackLayout>
main.component.ts
import { Component, ElementRef, OnInit, ViewChild} from "#angular/core";
import { Page } from "ui/page";
import colorModule = require("color");
var Color = colorModule.Color;
#Component({
selector: "my-app",
templateUrl: "pages/main/main.html",
styleUrls: ["pages/main/main-common.css"]
})
export class MainComponent implements OnInit{
constructor(private page: Page) {
}
ngOnInit() {
this.page.actionBarHidden = true;
}
}
and I also have main-common.css but that's not important to show. I then have another folder inside pages called hello with just one file inside of it
hello.html
<StackLayout width="100%" height="100%" backgroundColorr="red">
<Label class ="h1" text="h1 hello world" color="black"></Label>
<Label class ="h1" text="h1 hello world" color="black"></Label>
<Label class ="h1" text="h1 hello world" color="black"></Label>
<Label class ="h1" text="h1 hello world" color="black"></Label>
<Label class ="h1" text="h1 hello world" color="black"></Label>
<Label class ="h1" text="h1 hello world" color="black"></Label>
<Label class ="h1" text="h1 hello world" color="black"></Label>
<Label class ="h1" text="h1 hello world" color="black"></Label>
<Label class ="h1" text="h1 hello world" color="black"></Label>
<Label class ="h1" text="h1 hello world" color="black"></Label>
<Label class ="h1" text="h1 hello world" color="black"></Label>
</StackLayout>
however the hello component is not showing no matter what i do i am only getting an empty screen. I also tried changing this line xmlns:hello="pages/helllo" in hello.html file to this xmlns:hello="../helllo" but i didn't get anything not even an error. can someone point out what i am doing wrong?
What you are referring as valid in NativeScript Core but won't work in NativeScript + Angular-2.
What you need instead is to create custom component the Angular-2 way.
For demonstration, we can refer to this sample where a custom item component is created. The example is also described in the documentation and it will also show you how to bind data with #Input directive for this component.
Let me guide you through the process.
1.) Create your custom component
using-item-template.component.ts
import { Component, ChangeDetectionStrategy, Input } from "#angular/core";
#Component({
selector: 'item-component',
styleUrls: ["listview/using-item-template/using-item-template.component.css"],
template: `
<StackLayout *ngFor="let element of data.list" class="model">
<Label [text]="element.model" class="name"></Label>
<Label [text]="element.speed +'mph'" class="speed"></Label>
</StackLayout>
`
})
export class ItemComponent {
#Input() data: any; // this way we "pass data" to our item-component
}
#Component({
selector: 'using-item-template',
styleUrls: ["listview/using-item-template/using-item-template.component.css"],
templateUrl: "listview/using-item-template/using-item-template.component.html",
changeDetection: ChangeDetectionStrategy.OnPush
})
export class UsingItemTemplateComponent {
public manufacturers: Array<any>;
constructor() {
var bugatti = [{ "model": "Bugatti Chiron", "speed": "261" }, { "model": "Bugatti Veyron Super Sport", "speed": "268" }];
var mclaren = [{ "model": "McLaren P1", "speed": "211" }, { "model": "McLaren F1", "speed": "242" }];
var jaguar = [{ "model": "Jaguar XJ220", "speed": 217 }];
this.manufacturers = [{ "list": bugatti }, { "list": mclaren }, { "list": jaguar }];
}
}
using-item-template.component.html
<StackLayout exampleTitle toggleNavButton>
<GridLayout rows="50, *" class="example-container">
<Label text="Top Cars" row="0" class="title" textWrap="true" horizontalAlignment="center"></Label>
<ListView [items]="manufacturers" row="1">
<template let-item="item">
<item-component [data]="item" ></item-component>
</template>
</ListView>
</GridLayout>
</StackLayout>
The last but also crucial part is not to forget to declare your ItemComponent in the NgModule!
main.ts
import { ItemComponent } from "./listview/using-item-template/using-item-template.component";
#NgModule({
declarations: [
ItemComponent, // declare the item component
// the other components in your app
],
bootstrap: [AppComponent],
imports: [
.....
],
})
class AppComponentModule { }