titanium alloy onClick parameters - view

first of all: I am practicing with titanium, this are just my first "Hello World" apps to get confident with the framework, so any suggestion would be strongly appreciated.
I have this simple view:
<ScrollView id="grid" dataCollection="pictures">
<View class="single-item" title="{title}" author="{author}" desc="{desc}" onClick="showPic">
<ImageView class="thumb" image="/images/thumb-stock-1.jpg" />
<Label class="title" text="{title} by {author}" />
<Label class="desc" text="{desc}" />
</View>
</ScrollView>
Clicking on each item I call the function showPic() defined in my controller, and that's ok. But I would like to pass some parameters to that function, that are {title}, {author} and {desc}, so that I can handle them and "print" them on a new detail view for each specific item. With TableView it was easy (I just put: event.source -> title, event.source -> author ... inside my controller and I could read that table row data), but with my view that seems not work.
so my questions are:
1) how can I pass that parameters from VIEW: to CONTROLLER showPic()
2) generally speaking, if there is a better view to list some objects and opening each one with a click, just tell me how so that I can learn something more :D (PS: I cannot use tableView because my layout does not fit with this kind view)
---- EDIT: here follows my full code
index.xml:
<Alloy>
<Collection src="pictures"/>
<NavigationWindow id="navGroupWin">
<Window class="container" title="La mia galleria">
<View class="arrow arrow-up"><Label text="UP" /></View>
<ScrollView id="grid" dataCollection="pictures">
<View class="single-item" title="{title}" author="{author}" desc="{desc}" onClick="showPic">
<ImageView class="thumb" image="/images/thumb-stock-1.jpg" />
<Label class="title" text="{title} by {author}" />
<Label class="desc" text="{desc}" />
</View>
</ScrollView>
<View class="arrow arrow-down"><Label text="DOWN" /></View>
</Window>
</NavigationWindow>
</Alloy>
showPic from index.js:
function showPic(event) {
var pic = event.source;
var args = {
title: pic.title,
desc: pic.desc,
author: pic.author
};
var picView = Alloy.createController("detail", args).getView();
if (OS_IOS) {$.navGroupWin.openWindow(picView);}
if (OS_ANDROID) {picView.open();}
}
detail.xml:
<Alloy>
<Window class="container">
<View layout='vertical'>
<Label id="titleLabel"></Label>
<Label id="descLabel"></Label>
<Label id="authorLabel"></Label>
</View>
</Window>
</Alloy>
detail.js
var args = arguments[0] || {};
$.titleLabel.text = args.title || 'Default Title';
$.descLabel.text = args.desc || 'Default desc';
$.authorLabel.text = args.author || 'Default author';
when I click on each item of the index, my source.title, source.author and source.desc seems to be empty, and on the detail window I got back only 'Default' values

I am not sure if you can do this on the view file level.
What I would try is to assign ids to every view element (this is a general technique) and fully deploy all my click listeners inside the controller file, removing all onClick commands from view.
So:
Set id="myview" along with class="single-item" in your View
In your controller try
$.myview.addEventListener('click', function(e){
showPic(e.title, e.author, e.desc)
});

Not sure if it goes wrong somewhere else, but stripped down like this it works:
index.html
<Alloy>
<Window id="test">
<ScrollView id="grid" layout="vertical">
<View class="single-item" width="250" height="250" backgroundColor="blue" title="title" author="author" desc="desc" onClick="showPic">
</View>
<View class="single-item" width="250" height="250" backgroundColor="red" title="red" author="red" desc="red" onClick="showPic">
</View>
<View class="single-item" width="250" height="250" backgroundColor="yellow" title="yellow" author="yellow" desc="yellow" onClick="showPic">
</View>
<View class="single-item" width="250" height="250" backgroundColor="green" title="green" author="green" desc="green" onClick="showPic">
</View>
</ScrollView>
</Window>
</Alloy>
index.js
function showPic(event) {
Ti.API.info(JSON.stringify(event.source));
}
$.test.open();

Related

I use #if in Svlte Native but it doesn't work

I try out Svelte Native and I try to hide "tags" with booleans. I try this, which works in the normal Svelte framework like:
{#if po.id !== null || po.id !== undefined}
<flexboxLayout flexWrap="wrap" class="v-a-c t-a-c" >
<label text="first" width="70%" backgroundColor="#63c3d0" class="m6"></label>
<label text="second" width="70%" backgroundColor="#63c3d0" class="m6"></label>
<label text="third" width="70%" backgroundColor="#63c3d0" class="m6"></label>
</flexboxLayout>
{:else }
<stackLayout flexWrap="wrap" class="v-a-c t-a-c">
<textField bind:text="{personName}" class="m6 new-person" ></textField>
<button text="add new value" on:tap="{createNewPlayer}" />
</stackLayout>
{/if}
So why it doesn't work? What am I doing wrong?

How to have some pages without bottom navigation?

I want to have bottom navigation in my app as described on this page but I also have a login page which should not have the bottom navigation tabs. So as the user enters the app, he's shown the login page and after login he should get to the first tab of the bottom navigation. The docs do not mention how this would be achieved. How can this be done?
Attempt 1:
app.js
let startPage = 'login/login-page';
if(settings.hasKey('token')){
startPage = 'app-root';
}
application.run({ moduleName: startPage });
This does take me to the login page but then nothing works to get me to app-root or another similar page that could house a BottomNavigation
Attempt 2:
On login page, nothing happens.
app.js
application.run({ moduleName: 'app-root' });
app-root.xml
<Frame defaultPage="login/login-page"></Frame>
login/login-page.js
//send email and password. check if its correct. send user forward on authentication
page.frame.navigate({
moduleName: 'router/router-page',
clearHistory: true
});
router/router-page.xml
<BottomNavigation id="bottomNav" automationText="tabNavigation" selectedIndex="0">
<TabStrip>
<TabStripItem>
<Image src="font://" class="mdi"></Image>
<Label text="Products"></Label>
</TabStripItem>
<TabStripItem>
<Image src="font://" class="mdi"></Image>
<Label text="Gallery"></Label>
</TabStripItem>
</TabStrip>
<TabContentItem>
<Frame id="main" defaultPage="categories/categories-page"></Frame>
</TabContentItem>
<TabContentItem>
<Frame id="gallery" defaultPage="gallery/gallery-page"></Frame>
</TabContentItem>
</BottomNavigation>
//note there's no router-page.js
//is it necessary?
This exact scenario can be found in this post:
https://www.nativescript.org/blog/implementing-a-login-for-nativescript-apps-with-tab-based-navigation
The repo (https://github.com/NativeScript/login-tab-navigation-ng) is using TabView but you can quickly change that to use the newer BottomNavigation instead.
Here's how I finally did it
app.js
application.run({ moduleName: 'app-root' });
app-root.xml
<Page actionBarHidden="true" loaded="onLoaded" xmlns="http://schemas.nativescript.org/tns.xsd">
<Frame id="rootframe" defaultPage="{{ defaultPage }}"></Frame>
</Page>
app-root.js
const Observable = require("#nativescript/core/data/observable").fromObject;
const settings = require("#nativescript/core/application-settings");
exports.onLoaded = function(args){
const page = args.object;
page.bindingContext = Observable({
defaultPage: (settings.hasKey('token')) ? 'router/router-page' : 'login/login-page'
})
}
router/router-page.xml
<Page actionBarHidden="true" loaded="onLoaded" class="page" xmlns="http://schemas.nativescript.org/tns.xsd">
<BottomNavigation id="bottomNav" automationText="tabNavigation" selectedIndex="0" selectedIndexChanged="onSelectedIndexChanged">
<TabStrip>
<TabStripItem>
<Image src="font://" class="mdi"></Image>
<Label text="Products"></Label>
</TabStripItem>
<TabStripItem>
<Image src="font://" class="mdi"></Image>
<Label text="Gallery"></Label>
</TabStripItem>
</TabStrip>
<TabContentItem>
<Frame id="main" defaultPage="categories/categories-page"></Frame>
</TabContentItem>
<TabContentItem>
<Frame id="gallery" defaultPage="gallery/gallery-page"></Frame>
</TabContentItem>
</BottomNavigation>
</Page>

Nativescript Vue: Why does position of code matter in a Dock Layout matter?

Why does this following code produce this result: https://imgur.com/a/lQhLs8o ?
However, if I move the BottomNavigatorBar component to top position before CountryListComponent, it produces the desired result that looks like this: https://imgur.com/a/23z7bb2 ?
<template>
<Page actionBarHidden="true">
<DockLayout height="100%">
// first
<CountryListComponent dock="top">
// second
<BottomNavigationBar dock="bottom" activeColor="pink"
inactiveColor="yellow"
backgroundColor="black"
verticalAlignment="bottom"
#tabSelected="this.changeTab"
row="1">
<BottomNavigationTab title="Fiaarst" icon="icon-29.png" />
<BottomNavigationTab title="Second" icon="icon-29.png" />
<BottomNavigationTab title="Third" icon="icon-29.png" />
</BottomNavigationBar>
</DockLayout>
</Page>
</template>
CountryListComponent
<template>
<StackLayout backgroundColor="blue">
</StackLayout>
</template>
Refer the DockLayout documentation, by default stretchLastChild will be true which means BottomNavigationBar will take entire space if it's last child and vice versa.

how can i create multiline editable textview in nativescript?

i try beloved code but dos't work in android can't get new line
<TextView style="margin-top: 15px" borderColor="#DEDEDE" borderWidth="1"
height="100px" hint="Enter Note" returnKeyType="send" class="input input-border"></TextView>
<Button text="ADD" (tap)="insertNote()"></Button>
Use height attribute without 'px' unit like this :
<TextView style="margin-top: 15px" borderColor="#DEDEDE" borderWidth="1" height="100" hint="Enter Note" returnKeyType="send" class="input input-border"/>
Or give greater value for height in pixel : 200px

How to make tag categories, but if the size is long then it will automatically fall down

How to make tag categories like above, i tried using the code below
<View height="Ti.UI.SIZE" width="Ti.UI.SIZE" layout="horizontal">
<View height="Ti.UI.SIZE" width="Ti.UI.SIZE" right="10dp">
<Label height="Ti.UI.SIZE" width="Ti.UI.SIZE" left="10dp" right="10dp" top="5dp" bottom="5dp" text="Tidak ada layanan pesan antar"/>
</View>
<View height="Ti.UI.SIZE" width="Ti.UI.SIZE" right="10dp">
<Label height="Ti.UI.SIZE" width="Ti.UI.SIZE" left="10dp" right="10dp" top="5dp" bottom="5dp" text="Makan di tempat"/>
</View>
<View height="Ti.UI.SIZE" width="Ti.UI.SIZE" right="10dp">
<Label height="Ti.UI.SIZE" width="Ti.UI.SIZE" left="10dp" right="10dp" top="5dp" bottom="5dp" text="Alkohol Tidak Tersedia"/>
</View>
<View height="Ti.UI.SIZE" width="Ti.UI.SIZE" right="10dp">
<Label height="Ti.UI.SIZE" width="Ti.UI.SIZE" left="10dp" right="10dp" top="5dp" bottom="5dp" text="Tempat duduk di luar"/>
</View>
</View>
The result is
The view is not falling down if the size is too long, but keep filling the blank space of view parent. I dont know how to make it automatically falling down like the first image. Thanks
You have to set a fix height. With that, there is no line break

Resources