Tuesday 11 February 2014

Sencha Touch: Expense Tracker app development tutorial - Part4

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 source code for the remaining view pages in Expense Tracker app.

Add/Edit Category Page:

By clicking Add button in the category listing page, you will be redirected to the add new category page. This page contains two text fields Category Name and Category Price.


By clicking Save button without entering values in text fields, validation messages will be popup in message box. Please refer category model for settings Validation messages in category fields.


By entering valid form details and clicking Save button, confirmation message will be displayed in the popup message box and user will be redirected to the category list page. You can also edit category by clicking items on the category list page. Edit category page also allows to delete category from the category store by clicking delete button.

Source Code:


Ext.define('ExpenseTracker.view.AddCategory', {
    extend: 'Ext.Container',
    alias: 'widget.addcategory',

    config: {

        height: '100%',
        width: '100%',

        items: [{

            xtype: 'formpanel',
            height: '100%',
            itemId: 'addcategoryform',
            layout: {
                type: 'fit'
            },

            items: [{
                xtype: 'hiddenfield',
                itemId: 'id',
                name: 'id'
            }, {

                xtype: 'textfield',
                itemId: 'name',
                label: 'Name',
                labelWrap: true,
                name: 'name',
                required: true,
                placeHolder: 'Enter Category Name'

            }, {

                xtype: 'textfield',
                itemId: 'price',
                label: 'Price',
                labelWrap: true,
                name: 'price',
                required: true,
                placeHolder: 'Enter Price'

            }, {

                xtype: 'button',
                handler: function (button, e) {

                    var formObj = button.up('formpanel');
                    var formData = formObj.getValues();
                    var formTypeAdd = true;

                    if (formData.id === '') { //add form

                        var category = Ext.create('ExpenseTracker.model.Category', {
                            name: formData.name,
                            price: formData.price
                        });

                    } else { //edit form

                        formTypeAdd = false;
                        var category = Ext.getStore('Categories').getById(formData.id);

                        category.set('name', formData.name);
                        category.set('price', formData.price);
                    }

                    var errs = category.validate();
                    var msg = '';

                    if (!errs.isValid()) {

                        errs.each(function (err) {
                            msg += err.getField() + ' : ' + err.getMessage() + '<br/>';
                        });

                       Ext.Msg.alert('ERROR', msg);
                    } else {

                        if (formTypeAdd) {

                            Ext.getStore('Categories').add(category);

                        }

                        Ext.getStore('Categories').sync();
                        Ext.Msg.alert('SUCCESS', 'Category saved successfully');

                        Ext.Viewport.setActiveItem({
                            xtype: 'tabpanel'
                        });
                    }
                },

                itemId: 'save',
                style: 'position:relative;width:50%;float:left;',
                iconAlign: 'center',
                text: 'Save'

            }, {

                xtype: 'button',

                handler: function (button, e) {

                    var formObj = button.up('formpanel');
                    var formData = formObj.getValues();

                    var id = formData.id;
                    record = Ext.getStore('Categories').getById(id);

                    if (record === null || record === undefined) {
                        Ext.Msg.alert('Error', 'Category remove fails');
                    }

                    //record.phantom = true;

                    Ext.Msg.confirm('DELETE CONFIRM', 'Are you sure you want to delete?', function (btn) {

                        if (btn === 'yes') {

                            Ext.getStore('Categories').remove(record);
                            Ext.getStore('Categories').sync();
                            Ext.Msg.alert('SUCCESS', 'Category removed successfully');

                            Ext.Viewport.setActiveItem({
                                xtype: 'tabpanel'
                            });

                        } // switch

                    }); // confirm()

                },

                hidden: true,
                itemId: 'delete',
                style: 'position:relative;width:50%;',
                iconAlign: 'center',
                text: 'Delete'

            }]

        }, {

            xtype: 'titlebar',
            docked: 'top',
            ui: 'light',
            title: 'Add Category',

            items: [{

                xtype: 'button',

                handler: function (button, e) {
                    Ext.Viewport.setActiveItem({
                        xtype: 'tabpanel'
                    });
                },

                text: 'Back'
            }]
        }]
    }
});

Add/Edit Expense Page:

By clicking Add button in the expenses listing page, you will be redirected to the add new expense page. This page contains five text fields Name, Notes, Category, Date and Price.


By clicking Save button without entering values in text fields, validation messages will be popup in message box. Please refer expense model for settings Validation messages in expense fields.



By entering valid form details and clicking Save button, confirmation message will be displayed in the popup message box and user will be redirected to the expenses list page. You can also edit expense by clicking items on the expenses list page. Edit expense page also allows to delete expense from the expenses store by clicking delete button.

Source Code:


Ext.define('ExpenseTracker.view.AddExpense', {
    extend: 'Ext.Container',
    alias: 'widget.addexpense',

    config: {

        items: [{

            xtype: 'titlebar',
            docked: 'top',
            ui: 'light',
            title: 'Add Expense',

            items: [{

                xtype: 'button',
                handler: function (button, e) {

                    Ext.Viewport.setActiveItem({
                        xtype: 'tabpanel',
                        activeItem: 1
                    });

                },

                text: 'Back'

            }]

        }, {

            xtype: 'formpanel',
            height: '100%',
            itemId: 'addexpenseform',

            items: [{

                xtype: 'hiddenfield',
                itemId: 'id',
                name: 'id'

            }, {

                xtype: 'textfield',
                itemId: 'name',
                label: 'Name',
                labelWrap: true,
                name: 'name',
                required: true,
                placeHolder: 'Enter Name'

            }, {

                xtype: 'textfield',
                itemId: 'notes',
                label: 'Notes',
                labelWrap: true,
                name: 'notes',
                placeHolder: 'Enter Notes'

            }, {

                xtype: 'selectfield',
                itemId: 'category',
                label: 'Category',
                labelWrap: true,
                name: 'category',
                required: true,
                displayField: 'name',
                store: 'Categories',
                valueField: 'id'

            }, {

                xtype: 'textfield',
                itemId: 'price',
                label: 'Price',
                labelWrap: true,
                name: 'price',
                required: true,
                placeHolder: 'Enter Price'

            }, {

                xtype: 'datepickerfield',
                label: 'Date',
                name: 'date',
                required: true,
                placeHolder: 'dd/mm/yyyy',
                dateFormat: 'd/m/Y',

                picker: {

                    useTitles: true,
                    slotOrder: [
                        'day',
                        'month',
                        'year'
                    ],

                    yearFrom: 2013
                }

            }, {

                xtype: 'button',

                handler: function (button, e) {

                    var formObj = button.up('formpanel');
                    var formData = formObj.getValues();
                    var formTypeAdd = true;

                    if (formData.id === '') { //add form

                        var expense = Ext.create('ExpenseTracker.model.Expense', {

                            name: formData.name,
                            notes: formData.notes,
                            categoryid: formData.category,
                            price: formData.price,
                            date: formData.date
                        });

                    } else { //edit form

                        formTypeAdd = false;

                        var expense = Ext.getStore('Expenses').getById(formData.id);

                        expense.set('name', formData.name);
                        expense.set('notes', formData.notes);
                        expense.set('categoryid', formData.category);
                        expense.set('price', formData.price);
                        expense.set('date', formData.date);

                    }

                    var errs = expense.validate();
                    var msg = '';

                    if (!errs.isValid()) {

                        errs.each(function (err) {
                            msg += err.getField() + ' : ' + err.getMessage() + '<br/>';
                        });

                        Ext.Msg.alert('ERROR', msg);

                    } else {

                        if (formTypeAdd) {
                            Ext.getStore('Expenses').add(expense);
                        }

                        Ext.getStore('Expenses').sync();
                        Ext.Msg.alert('SUCCESS', 'Expense saved successfully');

                        Ext.Viewport.setActiveItem({
                            xtype: 'tabpanel',
                            activeItem: 1
                        });
                    }
                },

                itemId: 'add',
                style: 'position:relative;float:left;width:50%',
                text: 'Save'

            }, {

                xtype: 'button',

                handler: function (button, e) {

                    var formObj = button.up('formpanel');
                    var formData = formObj.getValues();

                    var id = formData.id;
                    record = Ext.getStore('Expenses').getById(id);

                    if (record === null || record === undefined) {
                        Ext.Msg.alert('Error', 'Expense remove fails');
                    }

                    //record.phantom = true;

                    Ext.Msg.confirm('DELETE CONFIRM', 'Are you sure you want to delete?', function (btn) {

                        if (btn === 'yes') {

                            Ext.getStore('Expenses').remove(record);
                            Ext.getStore('Expenses').sync();
                            Ext.Msg.alert('SUCCESS', 'Expense removed successfully');
                            Ext.Viewport.setActiveItem({
                                xtype: 'tabpanel',
                                activeItem: 1
                            });

                        } // switch

                    }); // confirm()
                },

                hidden: true,
                itemId: 'delete',
                style: 'position:relative;width:50%',
                text: 'delete'

            }]
        }]
    }
});

I hope, you enjoyed this post. My next post will be about controllers, how we can attach events to the views in controller and finally explaining about creating utility singleton class for configuration settings. Hope, see you soon ...

No comments:

Post a Comment