Monday, June 20, 2016

Sencha Touch Data Store Tips and Tricks

Recently one my friend asked me for some help on Sencha Touch Data store and form our conversation I got an idea for this blog.

Tip 1

If you want to pass extra params to store there are two ways to do that.

1) Pass it in load method.

store.load({
            params: {
                param1 : value1
            }
        });

2) Set it as extra param.

store.getProxy().setExtraParams({
            'param1' : value1,
            'param2': value2
        });

So what's the difference between this two and when to use which.

When you have requirement to add and use params only once. Also every time store load, you want to pass different params you have to use below method.

store.load({
            params: {
                param1 : value1
            }
        });

Params added here are only added once. Next time when you call load method of store, these params are not passed. You can use it for dynamic parameters.

When you have fixed params that you have to pass every time,  a store is loaded. You have to use following method.

store.getProxy().setExtraParams({
            'param1' : value1,
            'param2': value2
        });


This will permanently add those params to the store and it will be passed every time store.load() method is called.


Tip 2

How can you add callback function for store load dynamically. Again there are two ways to do that. If you want to add and use it only once, use following method. 

store.load({
       callback: function(){
              console.log('store is loaded'); 
       }
});

But if you want to wait for store load every time you should use following logic.

store.on({
       load: function(){
              console.log('store is loaded'); 
       },
       scope: this
});

Tricks

1) To reset all the extra params in store use do the following.

store.getProxy().setExtraParams({
});

Just pass the empty object in function and it will clear all previous params.

2) Reset page param in store when using list paging.

You can use currentPage config. store.currentPage = 1

3) Get raw response from of store load.

store.getProxy().getReader().rawData

This will return you all the raw data your API has returned.

Saturday, June 18, 2016

Sencha Touch Create Dropdown Like Standard HTML Control

Recently in one of my project, we have a requirement to create dropdown like standard HTML dropdown with Sencha Touch. See the below screenshot.


As we know in Sencha Touch Selectfield (dropdown)  uses either floating panels and bottom picker to show and choose value from one. So in this blog I am going to mention how to do this. 

First of all following should be our views.

{
    xtype : 'panel',
    height: 40,
    itemId: 'monthSelector',
    id: 'monthSelector',
    style: 'background-color:#ffffff;color: #019297;border-bottom:1px solid #019297;font-size: 12px',
    html: '<div style="height:100%;width:100%;display: table;">$lt;div style="display: table-cell;vertical-align: middle;">Select Month</div><img style="position:relative;float:right;top:10px" height="20" width="20" src="resources/css/images/black-down-arrow.png"/></div>',
    listeners: {
         initialize: function( element ) {
               this.element.on({
                    tap: function( ele ){
                             MyApp.app.getController('MyController').toggleDropDown();
                    }
               });
         }
     }
},

{
xtype: 'dataview',
itemId: 'expenseMonthSelector',
id: 'expenseMonthSelector',
scrollable: false,
style: 'font-size: 12px',
height: 80,
store: {
fields: ['id', 'name','color'],
data: [
{id : 1, name: 'Current Month', color: '#9decf0'},
{id : 2, name: 'Previous Month', color: '#6cd2d6'}
]
},
itemTpl: '<div style="background-color: {color}; color:#000000;height:40px;width:100%;display: table;"><div style="display: table-cell;vertical-align: middle;padding-left: 20px">{name}</div></div>'
}

As you can see above we have one panel with layout look like a dropdown and one dataview which will act like options for the dropdown.

After this we will add our toggleDropDown function to toggle dropdown.

toggleDropDown: function(){
        if(this.getExpenseMonthSelector().isHidden() == true){
            this.getExpenseMonthSelector().show();
        }else{
            this.getExpenseMonthSelector().hide();
        }
},

Above code will simply show hide data view. Hope this helps you.

JavaScript Create Date With TimeZone

Hello,

Recently in one of my project we faced lots of issues regarding in correct dates displayed to users. The problem was TimeZone. A user is in India but he don't know that he has set timezone to USA timezone and hence we get user's device date it was showing wrong date and time.

We asked our users to fix it but as we know end users are always unpredictable they still set the timzone to USA or others and keep complaining us about dates and times.

So here is what we did to fix this issue.

Step 1 : Get User's Current Location

You can use HTML 5 GeoLocation.

if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(gotUserPosition);
}

Step 2 : From the Latitude and Longitude, get user's current timezone using Google API.

function gotUserPosition(position){

     Ext.Ajax.request({
            url: 'https://maps.googleapis.com/maps/api/timezone/json?       location='+ position.coords.latitude +','+position.coords.longitude+'&timestamp='+parseInt(Date.now()/10)+'&key=YOUR_KEY',
            method: 'GET',
            disableCaching: false,
            success: function(response) {
                var result = Ext.decode(response.responseText);
                if(result.status == 'OK'){
                    localStorage.setItem('time_offset',result.rawOffset);
                    localStorage.setItem('timeZoneId',result.timeZoneId);
                }
            },
            failure: function(response) {
             
            },
            scope: this
     });

}

For this you have to create a Google API project and enable timezone API and add your key in stead of YOUR_KEY

As you can see above we are sending user's latitude and longitude to google maps api and getting the result. If result is OK. then we are saving time offset to local storage.

Now this time offset is the offset in number of seconds from UTC time. For example Indian Standard Time is ahead of UTC for 5 hours and 30 minutes. So here my offset will be 19800 seconds which is 5 hours and 30 minutes.

Now use the following logic to create date object.


var utcDate = (new Date()).toISOString();
var offsetHours = parseInt(Number(localStorage.getItem('time_offset'))/60/60);
var offsetMinutes = parseInt(Number(localStorage.getItem('time_offset'))/60%60);

var currentDate = new Date(Date.UTC(Number(utcDate.split('T')[0].split('-')[0]), Number(utcDate.split('T')[0].split('-')[1]) - 1, Number(utcDate.split('T')[0].split('-')[2]), (Number(utcDate.split('T')[1].split(':')[0]) + Number(offsetHours)), (Number(utcDate.split('T')[1].split(':')[1]) + Number(offsetMinutes)),0));

function z(n){return (n < 10? '0' : '') + n;};

var currentDateString = currentDate.getUTCFullYear() + '-' + z(currentDate.getUTCMonth() + 1) + '-' + z(currentDate.getUTCDate());

So above logic about creating UTC date and then adding number of hours and minutes to it to get desired date and time in UTC timezone. So virtually it's UTC date and time but since we added offset it will show you local date and time.

Hope this helps you.