In this blog post I will show you how to create your first native cross-platform application using JavaScript, CSS and the NativeScript framework. If this is the first you've heard about NativeScript, please read this blog post and follow us on twitter @NativeScript.
Note: NativeScript is in internal preview state at the moment. If you still do not have access to the bits please request to join the NativeScript Beta group and drop me an email (valentin.stoychev@telerik.com) to make sure that you will be among the first to have access to the fresh bits.
The app source code is available on GitHub. At the end of this article you will be able to understand the following NativeScript concepts:
Create a new NativeScript application
Create pages and navigate between them
Pass parameters between pages
Implement page layout with layout panels
Declare UI elements
Attach events to UI elements
Use ListView
Style using CSS
Consume web services
You have two options to get started with NativeScript. You can use the free open source tools, or you can use our cloud development environment, part of Telerik Platform solution, to skip the installation steps and start coding immediately.
If you want to start with the free open source tooling, you should use NativeScript CLI. Please read this article to set up the dependencies and learn CLI commands. Once you are done with the project creation you can continue from here.
If you want to use Telerik Platform solution, go to http://platform.telerik.com and create a new NativeScript project. More details on project creation are available in this article.
To open the sample application directly in AppBuilder and start editing, you should copy the git clone url of the sample: https://github.com/valentinstoychev/nativescript-samples.git
Then, choose to create a new AppBuilder project from an existing repository. Here is how the screen looks like in AppBuilder:
Now that you have opened the project in AppBuilder, let's look at the project structure.
* Please note that this structure is likely to change for the public beta release of NativeScript, coming early February.
The application files are located in the app folder:
bootstrap.js module is used by the NativeScript (NS) framework to perform any actions that are prior to execution of the application logic. Currently, we just instruct the NS framework to load the app.js file to start the application. You should not modify this file. Here is how the code looks like by default:
require(
"/app"
);
app.js module contains application specific code. Here is the place where you can set application-specific code, such as which page is the starting page of the application. Here is how the code looks like by default:
var
application = require(
"application"
);
application.mainModule =
"/main"
;
application.start();
main.js module contains the interesting part. In the default project, this is the first page of the application. You can check its source code on github - https://github.com/NativeScript/template-hello-world/blob/master/app/main.js
In the tns_modules folder, you will find the implementation of our Application Abstraction Layer (APL). There are located all the modules that give you the cross-platform abstractions for the entire application--layouts, components, device hardware and so on. You don’t need to change them, but you can take a look at the implementation if you are interested. They are also useful for debugging purposes.
These are the important parts of the application. You can ignore the rest of the folders for sake of simplicity.
Let's start with the basics. In the current v0.3, there is no XML declarative way right now to describe the UI. It's coming shortly; we have a working prototype for the UI declaration that we will give to you in the next few days. But for the moment, the way to describe the UI is by using JavaScript code only.
Let's try to create this simple interface:
---
[button]
[label]
---
As you can see, we want to insert a Button element and below it a Label element. In order to do this we will use a StackPanel layout. StackPanel renders its child elements one after another, in either a vertical or horizontal order. The code looks like this:
// Setup the button.
var
btn =
new
button.Button();
btn.text =
"TAP"
;
//Setup the message label.
var
messageLabel =
new
label.Label();
messageLabel.text =
"Label text"
;
// Setup the layout panel
var
panel =
new
stackPanel.StackPanel();
panel.addChild(btn);
panel.addChild(titleLabel);
To add this panel to the page, we will create a new page instance and set its content property to the panel we just created:
// create Page instance and set the StackPanel as its content.
var
page =
new
pages.Page();
page.content = panel;
exports.Page = page;
The next thing I want to show you is how to handle the "click" event of the Button and to update the text of the label.
To do this we are subscribing to the “click” event of the Button element in this way:
btn.on(
"click"
,
function
() {
console.log(
"button click called"
);
messageLabel.text =
"Label text TAPPED"
;
});
The next thing I want to show you is how to navigate to another page. We are using the Frame class methods to perform the navigation. You can see the API reference of the Frame class here: https://github.com/NativeScript/docs/blob/master/ui/frame/Frame.md
page.frame.navigate(
"Page2"
);
“Page2” string in this case specifies the name of the page module to which we want to navigate . You can also create an instance of that module and pass it as an argument like this:
var
page2 =
new
Page2();
page.frame.navigate(page2);
One of the most common scenarios is to pass a parameter from one page to another. This is easy to do in NativeScript. See this implemented in Page2 of the application. Here is the code snippet:
var
navigationEntry = {
moduleName :
"Page3"
,
context : {
param1 :
"param1Value"
}
};
page.frame.navigate(navigationEntry);
To retrieve the parameter you need to declare the following code (see Page3.js):
/*
*
* This is how you can get a parameters passed to the page.
*
*/
page.on(
"navigatedTo"
,
function
(eventData) {
var
param1Value = page.navigationContext.param1;
dialogs.alert(
"The value of param1 is ["
+ param1Value +
"]"
);
});
Here we are attaching to the “navigatedTo” event of the Page to be sure that all the context we need has been created, and we are reading the navigationContext property, which contains all the information that you have passed from the previous page.
CSS is the standard way to style websites and applications. This is why we choose it as a format for styling NativeScript applications. You can see this approach in the application (app.css). For a deep-dive on how to use CSS, read this post: http://developer.telerik.com/featured/styling-native-apps-css/
In Page6 and in Page7 of the sample application, I’m showing how to declare a ListView control and how to use our HTTP module to read data from a web service.
Declaring a ListView is easy. Here is the code needed to declare a ListView with static array and to handle selection:
var
items =
new
Array(1024);
var
listView =
new
listview.ListView();
/*
*
* Set up the view which will be displayed for each ListView item.
*
*/
listView.on(
"itemLoading"
,
function
(args) {
var
label = args.view;
if
(!label) {
label =
new
labelDef.Label();
args.view = label;
}
label.cssClass =
"listViewItemStyle"
;
label.text =
"item "
+ args.index;
});
// attach to the tap event of the listview item
listView.on(
"itemTap"
,
function
(args) {
page.frame.navigate(
"Page7"
);
});
listView.items = items;
To see how to use a web service, please open Page7 and check the source code. There you will see that we have a support for virtualizing arrays, which means that you can bind the ListView to a big list of data, but it is clever and will load the data on-demand as the users scrolls down. This is a more advanced topic and I don’t want to go into too many details now. It deserves a new article and I will make sure to create one in the next few weeks following the release.
Please follow me on twitter @ValioStoychev and let me know if you have any questions about NativeScript.
Valentin Stoychev (@ValioStoychev) for long has been part of Telerik and worked on almost every UI suite that came out of Telerik. Valio now works as a Product Manager and strives to make every customer a successful customer.