Wednesday 12 February 2014

Sencha Touch: Expense Tracker app development tutorial - Part5

If you haven't read my previous post of this post series. please read first and proceed this post. today we are going to see the about controllers, how we can attach events for the views in controllers and creating utility singleton class in order to store configuration settings for Expense Tracker app.

Utility Singleton Class:

I created an singleton utlity class in order to store app configuration settings and common methods that will be accessed  throught my application. Following are the configurations

debug:  This property will enable debug messages display in console log
costSymbol: the cost symbol that needs to display in price text field
expenseDate: this configuration will store the last searched expense date

These above configurations can be accessed by getter and setter methods.

ExpenseTracker.util.Config.getDebug()
ExpenseTracker.util.Config.getCostSymbol()
ExpenseTracker.util.Config.getExpenseDate()

In addition to that, i have created the following utility methods

getTotalExpenseCategoryPrice(): this method will return the total expense price by category and it accept categoryID as parameter.
getBalanceExpenseCategoryPrice(): this method will return balance expense price from the total expense for category and it accept Total expense price and categoryID as parameters
getTotalCategoryPrice(): this method will return the total price for all the categories
getTotalExpenseByDate(): this method will return the total expense price from start and end date
getBalanceExpenseByDate(): this method will return the balance expense price for start and end date with total expense price.

Source Code:

Ext.define('ExpenseTracker.util.Config', {
    singleton: true,     config: {         debug: true,         costSymbol: 'Rs.',         expenseDate: ''     },     constructor: function (config) {         this.initConfig(config);         this.callParent([config]);     },     getTotalExpenseCategoryPrice: function (cat_id) {         var total = 0;         if (cat_id != '') {             Ext.getStore('Expenses').filter('categoryid', cat_id);         }         Ext.getStore('Expenses').each(function (record) {             total += record.get('price');         });         Ext.getStore('Expenses').clearFilter();         return total;     },     getBalanceExpenseCategoryPrice: function (cat_id, cat_price) {         return cat_price - this.getTotalExpenseCategoryPrice(cat_id);     },     getTotalCategoryPrice: function () {         var total = 0;         Ext.getStore('Categories').each(function (record) {             total += record.get('price');         });         return total;     },     getTotalExpenseByDate: function (frDate, toDate) {         Ext.getStore('Expenses').filterBy(function (item) {             var itemdate = item.get('date');             itemdate = Ext.Date.format(itemdate, 'Y-m-d');             //console.log(itemdate);             if (itemdate >= frDate && itemdate <= toDate) {                 return true;             }         });         var total = 0;         Ext.getStore('Expenses').each(function (record) {             total += record.get('price');         });         Ext.getStore('Expenses').clearFilter();         return total;     },     getBalanceExpenseByDate: function (frDate, toDate, totalprice) {         Ext.getStore('Expenses').filterBy(function (item) {             var itemdate = item.get('date');             itemdate = Ext.Date.format(itemdate, 'Y-m-d');             //console.log(itemdate);             if (itemdate >= frDate && itemdate <= toDate) {                 return true;             }         });         var total = 0;         Ext.getStore('Expenses').each(function (record) {             total += record.get('price');         });         Ext.getStore('Expenses').clearFilter();         return totalprice - total;     } })

Controller

Here is the controller code for the Expense Tracker App. using refs  configuration, you can access all the view components using component itemID. Using control configurations, we can assign events (itemtap, tap) for view components using itemID and attach functions for each events. This functions will be called once the corresponding event gets fired.

onListItemTap: this method will be trigged, when you tap on items in Categories List page.
onListItemTap1: this method will be trigged, when you tap on items in Expenses List page.
onContainerInitialize1: this method will be trigged on loading Add New/Edit Category Form.
onContainerActivate: this method will be trigged on loading Add New/Edit Expense Form.
onContainerActivate1: this method will be trigged on loading Expenses List page.
Ext.define('ExpenseTracker.controller.Controller', {

    extend: 'Ext.app.Controller',
    alias: 'controller.controller',

    config: {

        refs: {
            addCategoryForm: {
                autoCreate: true,
                selector: 'addcategoryform',
                xtype: 'addcategory'
            }
        },

        control: {

            "tabpanel  #categorylist": {
                itemtap: 'onListItemTap'
            },

            "tabpanel  #expenseList": {
                itemtap: 'onListItemTap1'
            },

            "addcategory #addcategoryform": {
                activate: 'onContainerInitialize1'
            },

            "addexpense #addexpenseform": {
                activate: 'onContainerActivate'
            },

            "datepickerfield[itemId=searchfield]": {
                change: 'onPickerChange'
            },

            "tabpanel #expenses": {
                activate: 'onContainerActivate1'
            }
        }
    },

    onListItemTap: function (dataview, index, target, record, e, eOpts) {

        var addcategory = Ext.widget('addcategory');

        var _addcategory = addcategory.query('#addcategoryform')[0];

        _addcategory.setRecord(record);

        _addcategory.query('#delete')[0].setHidden(false);

        Ext.Viewport.setActiveItem(addcategory);
    },

    onListItemTap1: function (dataview, index, target, record, e, eOpts) {

        var addcategory = Ext.widget('addexpense');

        var _addcategory = addcategory.query('#addexpenseform')[0];

        record.data.category = record.data.categoryid;

        //console.log(record);

        _addcategory.setRecord(record);

        _addcategory.query('#delete')[0].setHidden(false);

        Ext.Viewport.setActiveItem(addcategory);
    },

    onContainerInitialize1: function (newActiveItem, container, oldActiveItem, eOpts) {

        var existing = container.down('#price').getLabel();
        existing = existing + ' (' + ExpenseTracker.util.Config.getCostSymbol() + ')';

        container.down('#price').setLabel(existing);

    },

    onContainerActivate: function (newActiveItem, container, oldActiveItem, eOpts) {

        var existing = container.down('#price').getLabel();
        existing = existing + ' (' + ExpenseTracker.util.Config.getCostSymbol() + ')';
        container.down('#price').setLabel(existing);

    },

    onPickerChange: function (picker, value, eOpts) {

        //console.log('call');
        //Ext.getStore('Expenses').clearFilter();
    },

    onContainerActivate1: function (newActiveItem, container, oldActiveItem, eOpts) {

        Ext.getStore('Expenses').clearFilter();

        var formData = ExpenseTracker.util.Config.getExpenseDate();

        if (formData === '') {
            formData = Ext.Date.format(new Date(), 'Y-m');
        }

        var frDate = formData + '-01',
            toDate = formData + '-31';

        //console.log(frDate);console.log(toDate);

        container.down('#searchfield').setValue(new Date(frDate));

        var costSymbol = ExpenseTracker.util.Config.getCostSymbol();

        var totalamount = ExpenseTracker.util.Config.getTotalCategoryPrice();

        var balanceamount = ExpenseTracker.util.Config.getBalanceExpenseByDate(frDate, toDate, totalamount);

        var compSum = container.down('#totalsummary');

        var compHtml = '<div style="float:left;width:100%;">Total Amount<div style="float:right;">' + costSymbol + totalamount + '</div></div><div style="float:left;width:100%;">Balance Amount: <div style="float:right;">' + costSymbol + balanceamount + '</div></div>';

        compSum.setHtml(compHtml);

        Ext.getStore('Expenses').filterBy(function (item) {

            var itemdate = item.get('date');
            itemdate = Ext.Date.format(itemdate, 'Y-m-d');

            //console.log(itemdate);

            if (itemdate >= frDate && itemdate <= toDate) {
                return true;
            }
        });
    }
});

Hope, you enjoyed this Post, my final post on this post series will be about building the Expense Tracker App using Phonegap for Android Platform. Hope, see you soon.

No comments:

Post a Comment