Nativescript RadListView not visible on iOS - nativescript

I have created an component with RadListView and placed on few pages in my application. The RadListView is inside an Panel, and the visibility of the RadListView is controlled using the Panel header. The functionality works appropriately on Android, however, on iOS(iPhone 5s iOS 11.1) the RadListView is not visible.
I have tried wrapping the RadListView with GridLayout, however, that doesn't work.
Version information: nativescript-ui-listview: ^3.5.1, tns-core-modules: ^3.4.1
Component code:
<StackLayout xmlns:lv="nativescript-ui-listview">
<GridLayout rows="*" columns="auto, *, auto" verticalAlignment="top" onTap="EntityHeaderTap" class="entity-header">
<Image row="0" col="0" width="23" src="res://detail_Employee" verticalAlignment="center"/>
<StackLayout row="0" col="1" orientation="horizontal" verticalAlignment="center" marginLeft="10">
<Label id="entityLabel" text="Employee" fontSize="15" verticalAlignment="center" color="#706e77"/>
</StackLayout>
<Image id="entityArrow" row="0" col="2" width="14" src="res://arrow_u" verticalAlignment="center" />
</GridLayout>
<StackLayout id="entityContent" visibility="collapse" class="entity-content">
<lv:RadListView id="employeeListView" items="{{ Employees }}" itemTap="EmployeeItemTap" visibility="{{ Employees ? 'visible' : 'collapsed' }}" selectionBehavior="None" separatorColor="transparent" height="100%">
<lv:RadListView.itemTemplate>
<GridLayout columns="*, 17" rows="50" class="{{ IsLast ? 'entity-item-last' : 'entity-item' }}">
<StackLayout col="0" verticalAlignment="center" marginLeft="5">
<Label text="{{ FullName ? FullName : '' }}" textWrap="true" fontSize="14" color="#4B4F63"/>
<Label text="{{ OrganisationName ? OrganisationName : '' }}" visibility="{{ OrganisationName ? 'visible' : 'collapsed' }}" textWrap="true" fontSize="12" color="#706e77"/>
</StackLayout>
<Image col="1" src="res://arrow_r" width="6" verticalAlignment="center"></Image>
</GridLayout>
</lv:RadListView.itemTemplate>
</lv:RadListView>
<StackLayout visibility="{{ Employees ? 'collapsed' : 'visible' }}">
<Label text="No record found" fontSize="14" padding="5" margin="0 5" color="#aeafb7" />
</StackLayout>
</StackLayout>
</StackLayout>
Implementation
<GridLayout rows="auto, auto, *, auto">
<ScrollView row="3" visibility="{{ selectedTabIndex == 2 ? 'visible' : 'collapsed' }}">
<GridLayout rows="auto, auto, auto, auto, auto, auto, *" columns="*, *" class="tab-container" paddingBottom="15">
....
<SearchComponent:EmployeePanel row="3" colSpan="2" marginTop="15" />
</GridLayout>
</ScrollView>
</GridLayout>

The thing is that StackLayout does not have predefined size and will take the space needed for its children component. In this case, the RadListView is also lacking a predefined size (height="100%" but the parent stack layout is measured with infinity).On iOS, the native control behind the list view needs a size to measure and occupy.
So as a possible solution try to either provide a size (for the container or directly to the RadListView) or use GridLayout with rows="*" to take all available space and then set row="0" to your RadListView
For example something like this:
<GridLayout rows="auto, 500" xmlns:lv="nativescript-ui-listview">
<GridLayout row="0" rows="*" columns="auto, *, auto" verticalAlignment="top" onTap="EntityHeaderTap" class="entity-header">
<Image row="0" col="0" width="23" src="res://detail_Employee" verticalAlignment="center"/>
<StackLayout row="0" col="1" orientation="horizontal" verticalAlignment="center" marginLeft="10">
<Label id="entityLabel" text="Employee" fontSize="15" verticalAlignment="center" color="#706e77"/>
</StackLayout>
<Image id="entityArrow" row="0" col="2" width="14" src="res://arrow_u" verticalAlignment="center" />
</GridLayout>
<lv:RadListView row="1" id="employeeListView" items="{{ Employees }}" itemTap="EmployeeItemTap" visibility="{{ Employees ? 'visible' : 'collapsed' }}" selectionBehavior="None" separatorColor="transparent" height="100%">
<lv:RadListView.itemTemplate>
<GridLayout columns="*, 17" rows="50" class="{{ IsLast ? 'entity-item-last' : 'entity-item' }}">
<StackLayout col="0" verticalAlignment="center" marginLeft="5">
<Label text="{{ FullName ? FullName : '' }}" textWrap="true" fontSize="14" color="#4B4F63"/>
<Label text="{{ OrganisationName ? OrganisationName : '' }}" visibility="{{ OrganisationName ? 'visible' : 'collapsed' }}" textWrap="true" fontSize="12" color="#706e77"/>
</StackLayout>
<Image col="1" src="res://arrow_r" width="6" verticalAlignment="center"></Image>
</GridLayout>
</lv:RadListView.itemTemplate>
</lv:RadListView>
</GridLayout >
Or instead of explicitly setting DP you can use the star symbol to take all space available
rows="auto, *"

Related

What is Repeater.itemsLayout property for? How and in what cases to use it?

This works as expected (without <Repeater.itemsLayout> and wrapped by <StackLayout>):
<GridLayout columns="auto, *" rows="auto">
<Label text="Some Text" row="0" col="0" backgroundColor="orange"/>
<StackLayout row="0" col="1" backgroundColor="green">
<Repeater items="{{ items }}">
<Repeater.itemTemplate>
<Label text="{{ $value }}"/>
</Repeater.itemTemplate>
</Repeater>
</StackLayout>
</GridLayout>
And this as NOT expected (with <Repeater.itemsLayout> and without wrapping by <StackLayout>):
<GridLayout columns="auto, *" rows="auto">
<Label text="Some Text" row="0" col="0" backgroundColor="orange"/>
<Repeater items="{{ items }}">
<Repeater.itemsLayout>
<StackLayout row="0" col="1" backgroundColor="green"/>
</Repeater.itemsLayout>
<Repeater.itemTemplate>
<Label text="{{ $value }}"/>
</Repeater.itemTemplate>
</Repeater>
</GridLayout>
Following code works because you are wrapping your Repeater in StackLayout and assiging it row and column and that is required as well if your putting that inside a GridLayout.
<GridLayout columns="auto, *" rows="auto">
<Label text="Some Text" row="0" col="0" backgroundColor="orange"/>
<StackLayout row="0" col="1" backgroundColor="green">
<Repeater items="{{ items }}">
<Repeater.itemTemplate>
<Label text="{{ $value }}"/>
</Repeater.itemTemplate>
</Repeater>
</StackLayout>
</GridLayout>
If you do not want to wrap inside a StackLayout, you should assign row="0" col="1" to Repeater.
Now comes to your question, that use of Repeater.itemsLayout, it gets or set the items layout of the Repeater. Default value is StackLayout with orientation="vertical".
So if you have a usecase where you want all the items in Repeater align horizontally, you should use following code.
<ScrollView row="0" col="0" orientation="horizontal">
<Repeater items="{{ items }}">
<Repeater.itemsLayout>
<StackLayout orientation="horizontal" />
</Repeater.itemsLayout>
<Repeater.itemTemplate>
<Label text="{{ $value }}" />
</Repeater.itemTemplate>
</Repeater>
</ScrollView>
We can set row and col properties for Repeater tag. Like so:
<GridLayout columns="auto, *" rows="auto, *">
<Label text="Some Text" row="0" col="0"/>
<Repeater row="1" items="{{ items }}">
<Repeater.itemsLayout>
<StackLayout orientation="horizontal" />
</Repeater.itemsLayout>
<Repeater.itemTemplate>
<Label text="{{ $value }}"/>
</Repeater.itemTemplate>
</Repeater>
</GridLayout>
Answer can be found here: https://github.com/NativeScript/NativeScript/issues/6554#issuecomment-438167999

Nativescript inner StackLayout

Hello everyone I'm trying to make inner StackLayouts but the second one comes to top of first one so that I can't see the second StackLayout should I handle with css if it is how or is there an other way
Here is my code
<StackLayout orientation="horizontal">
<StackLayout width="500">
<GridLayout columns="50, *" rows="*" width="500" height="50"
verticalAlignment="top">
<Label text="Name" row="0" col="0" backgroundColor="red">
</Label>
<Label text="Fol" row="0" col="1" class="alignRight"
backgroundColor="blue"></Label>
</GridLayout>
</StackLayout>
<StackLayout orientation="horizontal" width="500" height="180">
<Image src="http://lorempixel.com/400/200" width="500" left="10"
top="30">
</Image>
</StackLayout>
</StackLayout>
Thank you
At first I would delete the widths to see how the page is displayed. 500 is a very big value. Only large tablets can support that.
As an example at first I would try this :
<GridLayout columns="auto, auto">
<GridLayout col="0" columns="50, *" rows="*" verticalAlignment="top">
<Label text="Name" row="0" col="0" backgroundColor="red">
</Label>
<Label text="Fol" row="0" col="1" class="alignRight"
backgroundColor="blue"></Label>
</GridLayout>
<Image col="1" src="http://lorempixel.com/400/200" left="10" op="30">
</Image>
</GridLayout>
After you see the two parts align horizontally you can start tweaking the widths

center image in nativescript

After I try NativeScript tutorial "Grocery", I found out that its button quite hard to tap it's because tap area is too small, so I want to increase Image hight by update layout file to the following below. However, image not seem to be in the center (Image Below).
How can I achieve this in NativeScript ?
list.html
<ActionBar title="Groceries">
<ActionItem text="Share" (tap)="share()"
android.systemIcon="ic_menu_share_holo_dark"
ios.systemIcon="9" ios.position="right"></ActionItem>
</ActionBar>
<GridLayout rows="auto, *">
<GridLayout row="0" columns="*, auto" class="add-bar">
<TextField #groceryTextField [(ngModel)]="grocery" hint="Enter a grocery item" col="0"></TextField>
<StackLayout class="delete-container" height="100%" (tap)="add()" col="1" >
<Image src="res://add" stretch="none" horizontalAlignment="center"></Image>
</StackLayout>
</GridLayout>
<ListView [items]="groceryList" row="1" class="small-spacing" [class.visible]="listLoaded">
<ng-template let-item="item">
<GridLayout columns="*, auto">
<Label col="0" [text]="item.name" class="medium-spacing"></Label>
<StackLayout col="1" class="delete-container" height="100%" (tap)="delete(item)">
<Image src="res://delete"></Image>
</StackLayout>
</GridLayout>
</ng-template>
</ListView>
<ActivityIndicator
[busy]="isLoading" [visibility]="isLoading ? 'visible' : 'collapse'"
row="1" horizontalAlignment="center" verticalAlignment="center"></ActivityIndicator>
</GridLayout>
You should check out NS's FlexBox layout.
It is quite useful:
http://docs.nativescript.org/cookbook/ui/layouts/flexbox-layout

nativescript 'this' inside tkListViewHeader (RadListView header directive)

I'm using the TKListViewHeaderDirective of teleriks RadListView in nativescript like so:
<GridLayout columns="*" rows="*" tkToggleNavButton>
<RadListView *ngIf="!loading" row="3" col="0" [items]="nodes" ...>
<ng-template tkListItemTemplate let-node="item">
<!-- list item -->
</ng-template>
<ng-template tkListViewHeader>
<GridLayout columns="*" rows="auto, auto, auto">
<GridLayout row="0" col="0" columns="40,*,40">
<Button class="fa action-item" row="0" col="0" [text]="'fa-sort-amount-asc' | fonticon" ios.position="right" android="actionBar" style="background-color:#c9c9ce;;"></Button>
<SearchBar row="0" col="1" #searchInput hint="Search" (submit)="search(searchInput.text)" (clear)="search('')" (textChange)="search(searchInput.text)"></SearchBar>
<Button class="fa action-item" row="0" col="2" [text]="'fa-th' | fonticon" ios.position="right" android="actionBar" style="background-color:#c9c9ce;"></Button>
</GridLayout>
<StackLayout row="1" col="0">
<Label text="Hello world"></Label>
<Label [text]="currentNode.name"></Label>
<Label [text]="nodes?.length ? nodes.length : 0"></Label>
</StackLayout>
<StackLayout row="2" col="0" *ngIf="!nodes?.length" class="list-group">
<!-- some contents -->
</StackLayout>
<StackLayout row="3" col="0" *ngIf="currentNode?.name !== '/'" class="list-group">
<!-- some contents -->
</StackLayout>
</GridLayout>
</ng-template>
</RadListView>
</GridLayout>
it seems like two things go wrong here:
this seems to be missing here (the *ngIf should show one of the StackLayouts in specific cases but does not
The GridLayout (does not have any effect if I change it to StackLayout) inside the list header shows only one child element
According to the docs: http://docs.telerik.com/devtools/nativescript-ui/Controls/Angular/ListView/header-footer
There is an issue on github concerning this: https://github.com/telerik/nativescript-ui-feedback/issues/207

Very strange behaviour when trying to replicate a table using a Listview and GridLayout

I am trying to replicate a table using a ListView. Displaying the table's cell content works fine but when I add another GridLayout wrapped in a StackLayout above the Listview the Listview doesn't get displayed at all... Any idea why this might be happening? I tried as well to add the table headers to the ListView using nsTemplateKey but still get the same issue where the headers show but no table body content. When I remove the top GridLayout containing the headers the Listview's content displays perfectly as it should for some reason...
my code:
//headers
<StackLayout class="m-b-10">
<GridLayout rows="*" columns="*, *, *" *ngIf="stockTakeDetailList.length > 0 && !product">
<Label row="0" col="0" text="Name"></Label>
<Label row="0" col="1" text="Qty"></Label>
<Label row="0" col="2" text="Action"></Label>
</GridLayout>
</StackLayout>
//listview containing the table body
<StackLayout *ngIf="stockTakeDetailList.length > 0 && !product">
<ListView [items]="stockTakeDetailList">
<template let-captureItem="item" let-i="index">
<GridLayout rows="*" columns="*, *, *">
<Label row="0" col="0" class="list-group-item" textWrap="true" [text]="captureItem.ProductDetail_Name"></Label>
<Label row="0" col="1" class="list-group-item" [text]="captureItem.Qty"></Label>
<Label row="0" col="2" class="list-group-item font-awesome" text="" (tap)="removeCaptureItem(i)"></Label>
</GridLayout>
</template>
</ListView>
</StackLayout>
Try encapsulating all of the code within a StackLayout:
<StackLayout>
<StackLayout class="m-b-10">
<GridLayout rows="*" columns="*, *, *" *ngIf="stockTakeDetailList.length > 0 && !product">
<Label row="0" col="0" text="Name"></Label>
<Label row="0" col="1" text="Qty"></Label>
<Label row="0" col="2" text="Action"></Label>
</GridLayout>
</StackLayout>
<StackLayout *ngIf="stockTakeDetailList.length > 0 && !product">
<ListView [items]="stockTakeDetailList">
<template let-captureItem="item" let-i="index">
<GridLayout rows="*" columns="*, *, *">
<Label row="0" col="0" class="list-group-item" textWrap="true" [text]="captureItem.ProductDetail_Name"></Label>
<Label row="0" col="1" class="list-group-item" [text]="captureItem.Qty"></Label>
<Label row="0" col="2" class="list-group-item font-awesome" text="" (tap)="removeCaptureItem(i)"></Label>
</GridLayout>
</template>
</ListView>
</StackLayout>
</StackLayout>
Maybe try without the extra stack layouts:
<StackLayout>
<StackLayout class="m-b-10">
<GridLayout rows="*" columns="*, *, *" *ngIf="stockTakeDetailList.length > 0 && !product">
<Label row="0" col="0" text="Name"></Label>
<Label row="0" col="1" text="Qty"></Label>
<Label row="0" col="2" text="Action"></Label>
</GridLayout>
</StackLayout>
<ListView [items]="stockTakeDetailList" *ngIf="stockTakeDetailList.length > 0 && !product">
<template let-captureItem="item" let-i="index">
<GridLayout rows="*" columns="*, *, *">
<Label row="0" col="0" class="list-group-item" textWrap="true" [text]="captureItem.ProductDetail_Name"></Label>
<Label row="0" col="1" class="list-group-item" [text]="captureItem.Qty"></Label>
<Label row="0" col="2" class="list-group-item font-awesome" text="" (tap)="removeCaptureItem(i)"></Label>
</GridLayout>
</template>
</ListView>
</StackLayout>

Resources