On my xml, I have 1 textfield and 1 datepicker. How do I get a datepicker result and storing it result on the textfield?
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="onNavigatingTo">
<StackLayout>
<TextField hint="tanggalprospek" text="{{ tanggalprospek }}" />
<DatePicker day="15" month="5" year="2016" id="date" />
<Button text="Get Tap" tap="{{ getTap }}" />
</StackLayout>
</Page>
Many thanks for your help.. :)
Get the datepicker in the page controller and get the date value of it, then set it to the textfield along with the notifyPropertyChange event. I also use moment.js to have a good date format.
In the xml:
<Button text="Get Tap" tap="getTap" />
In the page controller:
var moment = require("moment");
export function getTap(args) {
var myDatePicker = page.getViewById("date");
var date = moment(myDatePicker.date);
var dateText = date.format("Do MMM [,] H:mm").toString();
page.bindingContext.set("tanggalprospek", dateText);
page.bindingContext.notifyPropertyChange("tanggalprospek", dateText);
}
P/s: I'm using TypeScript
Related
I am learning to make an app in NativeScript (Angular 2). In my item page, I want to have a button so that when I press it, I can change Label into TextView/TextField for editing the information of the item.
I know that I can use editable in TextView but I still want to know if it is feasible to have the button with that functionality. Thank you !!
item.component.html:
<StackLayout>
<Label class="h3" text="Name: {{ item.get_name() }}" textWrap="true">
</Label>
<Label class="h3" text="Credit: {{ item.get_credit() }}"></Label>
<Button class="btn" text="Edit" (tap)="change()"></Button>
</StackLayout>
<!-- After pressing the button -->
<StackLayout>
<TextView class="h3" [text]="item.get_name()" textWrap="true">
</TextView>
<TextView class="h3" [text]="item.get_credit()"></TextView>
<Button class="btn" text="Save" (tap)="change()"></Button>
</StackLayout>
This can be done in many ways, but one common way is by changing visibility of control and binding it to a variable / property in the code behind.
in your component html:
Then on your component ts or code-behind you can handle it in the change method:
class MyComponentSample {
isLabelMode: boolean = true; // Set to true if you want label to show by default or false if TextView as default
change() {
this.isLabelMode = !isLabelMode; // Basically you are toggling the mode here.
}
}
I am trying to create a custom component as described here in order to reuse the action bar and its logic in different places of my app.
Here is what I have setup the component:
/components/header/header.xml
<ActionBar title="Title" class="{{ 'mode' == dark ? 'bg-dark' : 'bg-white' }}" loaded="loaded">
</ActionBar>
/components/header/header.ts
exports.loaded = (args) => {
let page = <Page> args.object;
let pageObservable = new Observable({
'mode' : page.get('mode')
});
page.bindingContext = pageObservable;
}
I then try to use the component calling it like this :
some_view.xml
<Page
xmlns="http://schemas.nativescript.org/tns.xsd"
xmlns:header="components/header">
<header:header mode="dark"/>
<StackLayout>..</StackLayout>
...
</Page>
However, navigating to `some-view.xml' I get the following error:
Calling js method onCreateView failed
TypeError: Cannot read property frame of 'undefined'
File "data...../ui/action-bar/action-bar.js" line: 146
Am I doing something wrong?
Have you succeded in creating a custom component based on ActionBar?
Perhaps the problem is that you are trying to get Page instance in the loaded method in your /components/header/header.ts file. args will return you reference to the ActionBar instead of Page. On other hand while using TypeScript the events should be defined like this export function loaded(args){...}. In the above-given code you are using JavaScript syntax. I am attaching sample code, where has been shown, how to create custom component.
component/action-bar/action-bar.xml
<ActionBar loaded="actionbarLoaded" title="Title" icon="">
<NavigationButton text="Back" icon="" tap="" />
<ActionBar.actionItems>
<ActionItem icon="" text="Left" tap="" ios.position="left" />
<ActionItem icon="" text="Right" tap="" ios.position="right" />
</ActionBar.actionItems>
</ActionBar>
component/action-bar/action-bar.ts
export function actionbarLoaded(args){
console.log("actionbar loaded");
}
main-page.xml
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" xmlns:AB="component/action-bar">
<Page.actionBar>
<AB:action-bar />
</Page.actionBar>
<StackLayout>
<Label text="Tap the button" class="title"/>
<Button text="TAP" tap="{{ onTap }}" />
<Label text="{{ message }}" class="message" textWrap="true"/>
</StackLayout>
</Page>
main-page.ts
import { EventData } from 'data/observable';
import { Page } from 'ui/page';
import { HelloWorldModel } from './main-view-model';
// Event handler for Page "navigatingTo" event attached in main-page.xml
export function navigatingTo(args: EventData) {
// Get the event sender
let page = <Page>args.object;
page.bindingContext = new HelloWorldModel();
}
I am using telerik ui for native script. I need a toggle button at top to open the side menu. but I am not able to call the Showdrawer() as per the docs.
What I need is on button click side menu should open. I tried calling RadSideDrawer.prototype.showDrawer(), but failed.
Is there any other side menu available for Nativescript?
main-page.xml
<Page xmlns="http://www.nativescript.org/tns.xsd" xmlns:drawer="nativescript-telerik-ui/sidedrawer" loaded="pageLoaded">
<Page.actionBar>
<ActionBar>
<android>
<NavigationButton text="Go Back" android.systemIcon="ic_menu_moreoverflow" tap="showSideDrawer" />
</android>
</ActionBar>
</Page.actionBar>
<drawer:RadSideDrawer>
<drawer:RadSideDrawer.mainContent>
<StackLayout>
<Label text="{{ mainContentText }}" textWrap="true" />
</StackLayout>
</drawer:RadSideDrawer.mainContent>
<drawer:RadSideDrawer.drawerContent>
<StackLayout cssClass="drawerContent" style="background-color:white;">
<StackLayout cssClass="headerContent">
<Label text="Header" />
</StackLayout>
<StackLayout cssClass="drawerMenuContent">
<Label text="Item 1" style="color:black;" />
<Label text="Item 2" style="color:black;" />
<Label text="Item 3" style="color:black;" />
<Label text="Item 4" style="color:black;" />
</StackLayout>
</StackLayout>
</drawer:RadSideDrawer.drawerContent>
</drawer:RadSideDrawer>
</Page>
getting-started-model.js
var observableModule = require("data/observable");
var GettingStartedViewModel = (function (_super) {
__extends(GettingStartedViewModel, _super);
function GettingStartedViewModel() {
_super.call(this);
this.set("mainContentText", "SideDrawer for NativeScript can be easily setup in the XML definition of your page by defining main- and drawer-content. The component"
+ " has a default transition and position and also exposes notifications related to changes in its state.");
}
return GettingStartedViewModel;
})(observableModule.Observable);
exports.GettingStartedViewModel = GettingStartedViewModel;
function showSideDrawer(args) {
console.log("Show SideDrawer tapped.");
// Show sidedrawer ...
_super.prototype.showDrawer.call(this);
}
exports.showSideDrawer = showSideDrawer;
main page.js
var viewModelModule = require("./getting-started-model");
function pageLoaded(args) {
console.log("Page loaded");
var page = args.object;
page.bindingContext = new viewModelModule.GettingStartedViewModel();
}
exports.pageLoaded = pageLoaded;
You can take a look at this SDK examples that show the main functionality of the RadSideDrawer. As mentioned by #R Pelzer all you need to do is get the instance of the RadSideDrawer for example by using its id:
import drawerModule = require("nativescript-telerik-ui-pro/sidedrawer");
import frameModule = require("ui/frame");
var sideDrawer: drawerModule.RadSideDrawer = <drawerModule.RadSideDrawer>(frameModule.topmost().getViewById("sideDrawer"));
and call its showDrawer() method:
sideDrawer.showDrawer();
Are you calling the showSideDrawer function from code you didn't post? Are you sure you linked the tap button?
<Button tap="showSideDrawer" text="ToggleDrawer"/>
Maybe you can try to give the sideDrawer an Id and use this code.
var drawer = frameModule.topmost().getViewById("sideDrawer");
drawer.showDrawer();
You are getting undefined because no id was assigned to the drawer so to fix your problem assign an id to the sideDrawer <drawer:RadSideDrawer id="sideDrawer"> then you can call
var frame = require('ui/frame');
var drawer = frame.topmost().getViewById("sideDrawer");
function showSideDrawer(){
drawer.showDrawer(); // i prefer using .toggleDrawerState();
};
In my case, I missed inserting , as a result, there was a missing component when toggleDrawer was being called hence the error "TypeError: Cannot read property 'toggleDrawerState' of undefined".
Try inserting all the body component of the xml file in this might solve the issue.
Happy coding :))
I m bulding an app and i have a problem with rendering the title in the ActionBar after navigating to that page. Since the ActionBar cannot have an id i m using an observable viewModel in wich i set the title property.
-----xml-----
<Page.actionBar>
<ActionBar title="{{ name }}">
</ActionBar>
</Page.actionBar>
-------------
------js-----
exports.pageLoaded = function(args) {
page = args.object;
var navData = page.navigationContext;
viewModel.set("name",navData.name);
page.bindingContext = viewModel;
};
What i have seen so far debugging this problem is that when i close the phone screen and after that open it (refreshing the app) the action bar title will render.
Found the answer (a workaround) ,
<ActionBar>
<ActionItem ios.systemIcon="12" android.systemIcon="ic_menu_search" tap="showSearch" />
<ActionItem android.systemIcon="ic_menu_moreoverflow" tap="logout" text="Logout" android.position="popup" />
<ActionBar.titleView>
<StackLayout orientation="horizontal">
<Label text="{{ name }}" />
<Image src="res://app_icon" />
</StackLayout>
</ActionBar.titleView>
You need to set the title in a different page event, fairly certain you should do this in the navigatedTo event for the page.
For more info on the page navigation events, check out this blog post Nathanael Anderson - FluentReports - page navigating order of events
I using GridView Nativescript to arrange the UI and I want to set css into specific button or label dynamically. How can I find inside label when outside button is trigger and I tried using getViewById method but always get empty result. Isn't got any method to find it ?
var gridview;
exports.onPageLoaded = function (args) {
page = args.object;
gridview = page.getViewById("gridview");
};
exports.onSelectedIndexChanged = function(args){
var totalMatch = 0;
var btn = args.object;
var index = btn.index;
var a = gridview.getViewById("25");
btn.backgroundColor = "red";
btn.color = "white";
};
<GridLayout columns="*,1,*,1,*" rows="auto" borderWidth="1" borderColor="#DBDBDB" borderRadius = "3" >
<Button text="selectALL" index="0" tap="onSelectedIndexChanged" backgroundColor= "red" id ="btnSelectAll" color="white" borderRadius="3" />
<Button text="UnselectAll" index="1" col="2" tap="onSelectedIndexChanged" backgroundColor= "white" id ="btnUnSelectAll" borderRadius = "3" />
<Border col="1" borderWidth="1" borderColor="#DBDBDB" />
<Border col="3" borderWidth="1" borderColor="#DBDBDB" />
</GridLayout>
<gv:GridView items="{{ items }}" verticalSpacing="3" horizontalSpacing="3" colWidth="100" rowHeight="50" padding="3" id="gridview" height="400">
<gv:GridView.itemTemplate>
<GridLayout backgroundColor="#ffffff" style="border-width:3px;border-color:#696969;border-radius:5">
<Button text="{{ Name }}" id="{{ Id }}" index="{{ Index }}" tap="onGridViewItemTap" backgroundColor= "white" color="red" style="background-size:100% 100%;background-repeat:no-repeat;background-image:url('~/images/drawable-hdpi-v4/spt_fiter_checked.png')" borderWidth="1" borderColor="#DBDBDB" borderRadius = "5"/>
</GridLayout>
</gv:GridView.itemTemplate>
</gv:GridView>
After my understanding, what you are trying to do is:
press the button in the GridLayout
trigger the onSelectedIndexChanged function
Access the button with id="25"
Modify the button
First, I would like to point out that it is not recommended to access views by ids, especially when you have a complex UI structure. I would suggest that you use bindings. I am not sure what exactly you would like to modify, so I will assume that you would like to change the background property of the button. In this case, you can bind an Observable object in the code to the background property in the XML. Then in the function onSelectedIndexChanged, you can modify the object in the code by setting a new color. Since it is observable, it will notify all of the listeners for the modification. And in our case - the property in the XML.
Here I am sending you a simple example:
main-page.xml
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="onPageLoaded">
<GridLayout rows="auto,auto" >
<Button text="Click to Change Color" row="0" tap="onSelectedIndexChanged"/>
<Button text="Button" row="1" backgroundColor="{{color}}"/>
</GridLayout>
</Page>
main-page.js
var observable = require("data/observable");
var json={color:'red'};
var changeCss = new observable.Observable(json);
var gridview;
exports.onPageLoaded = function (args) {
page = args.object;
page.bindingContext=changeCss;
};
exports.onSelectedIndexChanged = function(args){
changeCss.set("color","blue");
};
I hope this will give you some directions.