Wednesday, 16 October 2013

Titanium Alloy - Migration with Model Tutorial

Hi Friends,

I am busy with my work. Here I am going to write post about "Migration".

What is Migration?
     A migration is a description of incremental changes to a database, which takes your database from version 1 to version X, with a migration file for each step in the evolution of your database schema. This is helpful to keep different versions of a database in sync. For example, when version 7 of your application is deployed, migrations are able to successfully update the database from versions 1 through 6.

Where I put migration files in my Titanium project?
      In Alloy, migrations are defined by JavaScript files located in the app/migrations folder of the project.

Is there is any naming conversion require for migration files?
     Yes, The file should be named the same as the model JavaScript file prefixed with 'YYYYMMDDHHmmss_' (datetime code followed by an underscore), for example, 20120610049877_movies.js(**your model file name should be movies.js). Alloy applies the migrations from oldest to newest, according to the datetime code at the beginning of the file name.

What are the functions used in migration files for upgrade my db?
     The migration file contains two functions that need to be implemented :  migration.up(migrator)  and migration.down(migrator), where migrator is a special migration object that provides references to the database and table as well as some convenient functions for table operations (see table below). The migration.up function upgrades the database from the previous version, while the migration.down function rolls back the changes to the previous version.

Is migration supports all type of adapters?
    Currently, migrations are only used with the sql sync adapter.

Example Project:
    In this tutorial i am creating simple project you can download source code from following github repository.   AlloyMigrationExample

1. Create simple Alloy project
2. Put you preloaded sqlite db file into asset folder.
3. My sqlite db name is "sampledb.sqlite" and the db has "user_accounts"  table with some preloaded data

We are going to add migration files for add a new table "movies" and insert the preloaded data.

4. In Titanium Studio, Right click on the project --> New --> Alloy Migration -->Enter your migration table name. (No need to add timedate , Titanium Studio add this for you). In this example we enter "movies". Now you can see migration file in app/migrations/20130812093432_movies.js.  (Timedate string will be different ignore it. You can edit timedate string as per your need).

5. Open the 20130812093432_movies.js. file and you can see two function called migration.up and migration.down.  Modify code as follow,

 
migration.up = function(migrator) {
 migrator.createTable({
  columns: {
   id: 'INTEGER PRIMARY KEY AUTOINCREMENT',
   title: 'TEXT',
   subtitle: 'TEXT',
   image: 'TEXT'
  }
 });
};

migration.down = function(migrator) {
 migrator.dropTable("movies");
};


6. migrator.createTable() function

  •     This method used to create table at run time and added into database.
  •      columns: In this field you can define your table columns with type. 
7. Create Another migrator file for insert the preloaded data in movies table.
  • Repeat the Step 4. (Exactly same). Finally you get new migrator file with different time date string.
  • Which means older get executed first. 
  • we get 201308120941308_movies.js  , new migration file open this file and modify it.


 
var products = [];
for (var i = 0; i < 500; i++) {
 if (i%7 === 0) {
  products.push({
   title: 'This is the title',
   subtitle: 'This is the slightly more verbose subtitle',
   image: i%2 ? '/appc.png' : '/alloy.png'
  });
 } else if (i%2) {
  products.push({
   title: 'This is the title with subtitle',
   subtitle: 'This is the slightly more verbose subtitle'
  });
 } else {
  products.push({
   title: 'This is the lonely title'
  });
 }
}

migration.up = function(migrator) {
 for (var i = 0; i < products.length; i++) {
  migrator.insertRow(products[i]);
 }
};

migration.down = function(migrator) {
 for (var i = 0; i < products.length; i++) {
  migrator.deleteRow(products[i]);
 }
};


8. Create model file for movies

  •     Right click on project --> New --> Alloy Model --> Enter Model Name "movies"
  •     Modify the app/Model/movies.js


exports.definition = {
 config: {
  columns: {
   id: 'INTEGER PRIMARY KEY AUTOINCREMENT',
   title: 'TEXT',
   subtitle: 'TEXT',
   image: 'TEXT'
  },
  
  adapter: {
   type: "sql",
   collection_name: "movies",
   idAttribute: 'id',
  }
 }
}; 

Now you can use this model same as other models used in Alloy. You can download working example from github.  Download full working example source code from AlloyMigrationExample

Thanks.

Thursday, 29 August 2013

Android Native Controls Module for Titanium

NativeControls - This module helps to create android native controls in titanium.

My Colleague J.Kabeer given an idea to implement module for missing Android native controls.

Initially we start this module with RadioGroup and later version we will plan to update most of the controls.

Feature:
  • Create android native RadioGroup in titanium
  • You can set the default selectedIndex value to RadioGroup
  • You can add "chage" EventListener to RadioGroup
  • You can get selected RadioButton Object value  using getSelectedIndexValue() Method
  • Define text color by set textColor value
  • Define layoutType by set the layoutType = "horizontal/vertical"
  • Passing radio buttons as array of object in "buttons"  

Usage:
var nativecontrols = require('learnappcelerator.nativecontrols');

var radiogroup = nativecontrols.createRadioGroup({
 width : Ti.UI.SIZE,
 height : Ti.UI.SIZE,
 top : 100,
 left : 10,
 textColor : "",
 selectedIndex : 2,
 layoutType : "vertical",
 buttons : [{
  id : 1,
  text : 'value 11'
 }, {
  id : 2,
  text : 'value 12'
 }, {
  id : 3,
  text : 'value 13'
 }]
});

radiogroup.addEventListener('change', function(e) {
 alert(JSON.stringify(e.result));
 var obj=radiogroup.getSelectedButton();
 Ti.API.info("selected ButtonValue ="+JSON.stringify(obj));
});

win.add(radiogroup);


Screenshots




Version 1.1 -    RadioGroup   - available

Version 1.2 -  AutoCompleteTexBox  - will update soon.

Download:
Module:  https://marketplace.appcelerator.com/apps/6378?759209041

Wednesday, 21 August 2013

Alloy - REST API Json to TableView

Hi,

I am creating simple application for fetching JSON data from REST API and display the data to Table View.

You can download the source code from json2tableview repository

Steps:


1. Create simple alloy Project
2. Modify index.xml

 

 
  
 



3. Modify index.js
function openDetail(e) {
 alert('row index = ' + JSON.stringify(e.index));
 //Ti.API.info('row rowData = ' + JSON.stringify(e.rowData));
 //Ti.API.info('row index = ' + JSON.stringify(e..index));
}

var data = [];

var sendit = Ti.Network.createHTTPClient({

 onerror : function(e) {

  Ti.API.debug(e.error);

  alert('There was an error during the connection');

 },

 timeout : 1000,

});

// Here you have to change it for your local ip

sendit.open('GET', 'https://maps.googleapis.com/maps/api/place/nearbysearch/json?types=hospital&location=13.01883,80.266113&radius=1000&sensor=false&key=AIzaSyDStAQQtoqnewuLdFwiT-FO0vtkeVx8Sks');

sendit.send();

// Function to be called upon a successful response

sendit.onload = function() {

 var json = JSON.parse(this.responseText);

 // var json = json.todo;

 // if the database is empty show an alert

 if (json.length == 0) {
  $.table.headerTitle = "The database row is empty";
 }

 // Emptying the data to refresh the view

 // Insert the JSON data to the table view
 var countries = json.results;
 for ( var i = 0, iLen = countries.length; i < iLen; i++) {

  data.push(Alloy.createController('row', {
   icon : countries[i].icon,
   name : countries[i].name

  }).getView());

  // data.push(row);

  Ti.API.info(countries[i].icon);
  Ti.API.info(countries[i].name);

 }

 $.table.setData(data);
};

$.index.open();

4. Create Alloy Controller row (it create row.xml, row.js, row.tss)
5. Modify row.xml
 

 
  >
  


6. Modify row.js
 
var args = arguments[0] || {};

$.icon.image = args.icon;
$.catID.text = ar

7. Add styles to tss files
index.tss
 
"Window":{
 backgroundColor :"#FFF",
 exitOnClose:true,
 navBarHidden:true
}


row.tss
 
"#icon":{
 left:0,
 height:50,
 width:50
}

"TableViewRow":{
 layout:"horizontal"
}

"Label":{
 color:'#000',
 font:{
  fontFamily:"Ariel",
  fontSize:'20dp',
  fontWeight:'bold'
 }
}



Thanks

Sunday, 11 August 2013

Pinterest Module for Photo sharing - Titanium

Hi.

Recently I have developed new titanium module for photo sharing in "Pinterest". This module helps you to sharing images in pinterest. Currently this module only for android.

Download module from here Pinterest - Android Module

Pinterest Module

Description

This module is used to share the photos in pinterest from titanium.

Accessing the pinterest-android Module

To access this module from JavaScript, you would do the following:
var pinterest = require("learnappcelerator.pinterest");
The pinterest variable is a reference to the Module object.

setClientId("clientId");

This is an required Field. You should login into developer.pinterest.com and register you appname. you can get client ID.

pinterest.setClientId("xxxxxxx"); //replace with your client ID

setDebugMode(flag);

This property is optional. If you want to get error logs in console set this as true.
pinterest.setDebugMode(true);

pinterest.createPinterest()

This method used to create the pinIt button.

Usage

var pinterest = require("learnappcelerator.pinterest");
pinterest.setClientId("xxxxxxx");
pinterest.setDebugMode(true);
var pin1 = pinterest.createPin({
        width: 150,
        height: 90,
        top: 100,
        left: 150,
        imageUrl:"http://placekitten.com/400/300",
        baseUrl:"http://placekitten.com",
        description:"kitten image!"
});
win.add(pin1);

Author

Author Name : M. Prakash
Email : prakashmca.m@gmail.com
Blog : http://www.learnappcelerator.blogspot.com

Screen shots:




Thanks.

Thursday, 18 July 2013

Alloy - RSS Feed Parser

RSS feeds benefit publishers by letting them syndicate content automatically. A standardized XML file format allows the information to be published once and viewed by many different programs. They benefit readers who want to subscribe to timely updates from favorite websites or to aggregate feeds from many sites into one place.

I am creating a simple RSS Reader which get the rss feed from given url and parse the xml data.

And return array of objects which is easy to manipulate in your titanium application.

I am creating sample project in alloy framework.

Download source code from github RSS-Feed-Reader

You can find rss.js  file in /lib directory.

usage of this file is,


 
var rss = require('rss');
var RSS_URL = OS_MOBILEWEB ? '/goirss.xml' : 'http://www.thehindu.com/news/national/tamil-nadu/?service=rss';
// open detail window
function openDetail(e) {
 $.trigger('detail', e);
}

// Refresh table data from remote RSS feed
function refreshRss() {
 rss.loadRssFeed(RSS_URL, {
  success : function(data) {
   var rows = [];
   _.each(data, function(item) {
    rows.push(Alloy.createController('row', {
     articleUrl : item.link,
     title : item.title,
     date : item.pubDate,
     description : item.description
    }).getView());
   });
   $.table.setData(rows);
  }
 });
}

// do initial load of RSS
refreshRss(); 


Thank you.

Friday, 12 July 2013

Alloy - Sqlite CreateTable Example

I created the sample project for createTable into preloaded sqlite database in Alloy Framework

download working example form gist alloySqliteCreateTable

Main logic written in app/controller/index.js



 
function createTable(e) {  
 var db = Ti.Database.open('codeguru');
 if(db){
  db.execute('CREATE TABLE people (name TEXT, phone_number TEXT, city TEXT)');
  var thisName = 'Arthur';
  var thisPhoneNo = '1-617-000-0000';
  var thisCity = 'Mountain View';
  db.execute('INSERT INTO people (name, phone_number, city) VALUES (?, ?, ?)', thisName, thisPhoneNo, thisCity);

  var personArray = ['Paul','020 7000 0000', 'London'];
  db.execute('INSERT INTO people (name, phone_number, city) VALUES (?, ?, ?)', personArray);

  var rows = db.execute('SELECT rowid,name,phone_number,city FROM people');
  while (rows.isValidRow())
  {
    Ti.API.info('Person ---> ROWID: ' + rows.fieldByName('rowid') + ', name:' + rows.field(1) + ', phone_number: ' + rows.fieldByName('phone_number') + ', city: ' + rows.field(3));
    rows.next();
  }
  rows.close();
 }
    alert($.label.text);
}

This is an quick fix for creating table in runtime. And I will working on collection of data inserted through model.js 


 For now, Refer this following repository for bulk updates in sqlite db alloy framework, One way to do bulk updates and deletes with Appcelerator Alloy Collections bulk_update

Thursday, 11 July 2013

JSON object Sorted by Date

Hi,

Many of them asking how to sort my json objects based on date. And writing many lines of code, sometimes get tired to sort the json object. Here I found simple function to sort your json object based on date.

Not only date you can sort json object based on any attribute by writing custom sort function in your code.

Let me explain how to create custom sort function in java script.

You can download the sample app source code from git repository Sort Json by Date

Example JSON object:
 
var latestOffers=[
          {id: '1', date: '20 Dec 2012, 8:00 am', text:'item1'},
          {id: '2',  date: '29 Jun 2012, 5:47 pm', text:'item2'},
          {id: '3', date: '15 May 2013, 6:40 pm', text:'item3'}         
        ]; 

Now I write sortbydate() function


function sortbydate(a, b) {
    // change the < condition to > for reverse the sort.
    // here you can add your own sorting condition 
    // eg,   return a.id < b.id;   //its sort your object based on id.
    return new Date(a.date).getTime() < new Date(b.date).getTime();
}

Now you can call the Array.sort() with your sortbydate function.


 
latestOffers.sort(sortbydate);
Ti.API.info('sorted json array ==='+ JSON.stringify(latestOffers));


Thanks

Alloy Framework - Use Preloaded Sqlite Database

Most of time you may need to use the preloaded db in your application.

We are going to see How to use preloaded SQLite Database in Alloy framework in titanium.

Download the source code from git repository  AlloySqlitedb

1. Open the Titanium Studio  (I am using 3.1.1)
2. create New Alloy Mobile Project  (refer the Link for creating New Alloy Project)
3. Put your sqlite database file into app/assets folder. (I am using myapp.sqlite)
4.create collections object in alloy.js file.

 
Alloy.Collections.fighters = Alloy.createCollection('fighters');

5.create model file "fighters.js" in app/model directory.

 
exports.definition = {
  config:{
   
   adapter:{
    "type":"sql",
    "collection_name":"fighters",
    "db_file": "/myapp.sqlite",
    "db_name": "fighters",
    "idAttribute": "id",
    "remoteBackup":false
   }
  }
}

6.Modify index.xml file in app/views/ directory - create Table View.

 

    
        
        
            
        
    


7. Create controller index.js file in app/controller directory

 
var fighters = Alloy.Collections.fighters;
var counter = 1;

function showId(e) {
 if (e.row.model) {
  //alert(e.row.model);
  var detailObj=fighters.get(e.row.model);
  var win=Alloy.createController('detail',{"$model":detailObj});
     win.getView().open();
 }
}

function addTestFighter(e) {
 // create the test fighter model
 var model = Alloy.createModel('fighters', {
  name: 'Name ' + counter,
  nickname: 'Nickname ' + counter
 });
 counter++;

 // add model to the collection and save it to sqlite
 fighters.add(model);
 model.save();

 // let's refresh so we can see the ids coming from the 
 // autoincrement field in the sqlite database in the 
 // row click alerts
 fighters.fetch();
}

fighters.fetch();

$.index.open();

8. Create layout for row.xml in app/views directory

 

 
  


9. Create controller row.js in app/controller directory

 
// Attach the bound model ($model) to the row so 
// we can access it in a click event.
if ($model) {
 $.row.model = $model.toJSON();
}


10. Create layout for for detail.xml in app/views directory

 

 
  
   
    >
  >
 >




11. Create controller detail.js in app/controller directory.

 
var args=arguments[0]||{};
if(args.$model){
 Ti.API.info('model ='+JSON.stringify(args.$model));
 var dataJson=args.$model.toJSON();
}else{
 alert('data not passed');
}

12. Finally add the styles to your layouts in app/styles

a. index.tss

 
"Window": {
 backgroundColor: '#fff',
 navBarHidden: true,
 exitOnClose: true
}

"#title": {
 top: 0,
 height: '50dp',
 width: Ti.UI.FILL,
 color: '#fff',
 backgroundColor: '#a00',
 font: {
  fontSize: '36dp',
  fontWeight: 'bold'
 },
 textAlign: 'center'
}

"#table": {
 top: '50dp',
 bottom: 0
}

b.row.tss

 
"#row": {
 height: '60dp',
 backgroundColor: '#fff'
}

"Label": {
 height: Ti.UI.SIZE,
 width: Ti.UI.SIZE
}

"#name": {
 top: '7dp',
 left: '7dp',
 font: {
  fontSize: '24dp',
  fontWeight: 'bold'
 }
}

"#nickname": {
 bottom: '7dp',
 left: '14dp',
 font: {
  fontSize: '16dp',
  fonWeight: 'normal'
 }
}

c. detail.tss

 
"Window": {
 backgroundColor: '#fff',
 navBarHidden: true
}
"#name": {
 top: '10dp',
 font: {
  fontSize: '24dp',
  fontWeight: 'bold'
 }
}

"#nickname": {
 top: '10dp',
 font: {
  fontSize: '16dp',
  fonWeight: 'normal'
 }
}

13. Here we go and run the project.


Thanks.

Alloy Animation - builtin library

Titanium alloy framework provide collection of useful animation utilities. To use the animation builtin library, all you need to do is require it with the alloy root directory in your require call. For example:

var animation = require('alloy/animation');
animation.crossFade(view1, view2, 500, finishCallback);



chainAnimate( Titanium.UI.View view, Titanium.UI.Animation[] animations, [function() finishCallback] )
Executes a series of animations on the target view.
crossFade( Titanium.UI.View from, Titanium.UI.View to, Number duration, [function() finishCallback] )
Transitions from one view to another using a cross-fade animation.
fadeAndRemove( Titanium.UI.View from, Number duration, Titanium.UI.View container, [function() finishCallback] )
Fades out a view then removes it from its parent view. 
fadeIn( Titanium.UI.View to, Number duration, [function() finishCallback] )
Fades in the specified view. 
fadeOut( Titanium.UI.View to, Number duration, [function() finishCallback] )
Fades out the specified view. 
flash( Titanium.UI.View view, [Number delay], [function() finishCallback] )
Flashes the target view twice, fading to partially transparent then back to fully-opaque. 
popIn( Titanium.UI.View view, [function() finishCallback] )
Makes the specified view appear using a "pop-in" animation, which combines a fade-in with a slight expanding and contracting animation, to call attention to the new view. 
shake( Titanium.UI.View view, [Number delay], [function() finishCallback] )
Creates a shake animation, moving the target view back and forth rapidly several times.

Example:

1. open Titanium Studio
3. Modify views/index.xml
 

     
        
              
             
4. Modify styles/index.tss
 
".container": {
 backgroundColor:"white"
},
"#square": {
 width: 200,
 height: 200,
 color: "#f00"
} 

"#shakeMe":{
 title:'Shake Me',
 bottom:'100dp'
}


5. Modify controllers/index.js
 
function shakeMe(e) {
    var animation = require('alloy/animation');
    animation.shake($.view2, 500);
}

$.index.open();

6. Run the project and click the button.

Thanks.

Monday, 24 June 2013

Garbage Collector - Titanium Module for Android


Recently I developed an native module called Garbage Collector Module and published in Appcelerator Marketplace.


This module is used to Monitor your android device heap memory and force the garbage collector for free the unused objects.

Using this module we can get following informations,
  • MaxVMHeapSize
  • NativeHeapSize
  • VMHeapSize
  • TotalHeapSize
  • VMAllocatedHeapSize
  • NativeHeapAllocatedSize
  • VMHeapTotalAllocatedSize
  •  VMHeapFreeMemory
  • VMHeapTotalFreeMemory
And Also we have two more public methods called,
  • isOutOfMemoryException()   - we can check the Memory exception before app get crash.
  • callGC() - This method force the garbage collector and release the memory occupied by unused objects.
 Accessing the Garbage Collector Module

To access this module from JavaScript, you would do the following:

var garbagecollector = require("prakash.garbagecollector");

Force Garbage Collector

garbagecollector.callGC(); 

Check MemoryException

garbagecollector.isOutOfMemoryException();  returns true/false

Check Heap Memory Status
garbagecollector.getMaxVMHeapSize();
garbagecollector.getNativeHeapSize();
garbagecollector.getVMHeapSize();
garbagecollector.getTotalHeapSize();
garbagecollector.getVMAllocatedHeapSize();
garbagecollector.getNativeHeapAllocatedSize();
garbagecollector.getVMHeapTotalAllocatedSize();
garbagecollector.getVMHeapFreeMemory();
garbagecollector.getVMHeapTotalFreeMemory(); 

Sample App Screenshot
Module URL :

https://marketplace.appcelerator.com/apps/5834?2036618235