Sunday 9 February 2014

CRUD Operation using Sencha Touch and ASP.Net MVC Web API

In this article I am going to explain and demonstrate how to create a simple ASP.Net MVC Web API and Sencha touch app together to perform create, read, update and delete functionality in SQL Server database.

This is basically a small app which demonstrates step by step creation of MVC Web API and Sencha Touch app.

To create this application we need following required pieces:

·         SQL express

·         Microsoft Visual Studio 2010 or 2012 for (ASP.Net MVC Web API)

·         Sencha Architect

To proceed with the application, let’s first create the following table (Students) in your database (Studentdb) in my case.

CREATE TABLE [dbo].[Students](

      [StudentId] [int] IDENTITY(1,1) NOT NULL,

      [Name] [varchar](20) NOT NULL,

      [Email] [varchar](50) NULL,

      [Address] [varchar](100) NULL,

      [Age] [int] NULL,

      [Country] [varchar](50) NULL,

 CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED

(

      [StudentId] ASC

))

 

GO

Insert some record in the table, so that we can free from database part and focus towards our application. Script given below to insert dummy records.

declare @Name varchar(50), @Email varchar(50), @Address varchar(50) = 'Allahabad', @Age int = 22, @Country varchar(50) = 'India'

declare @i int = 1

while(@i <= 105)

begin

      set @Name = 'Rohit' + ' '+ Convert(varchar,@i)

      set @Email = 'rohit'+ Convert(varchar,@i)+'@gmail.com'

      INSERT INTO [StudentDb].[dbo].[Students]

           ([Name]

           ,[Email]

           ,[Address]

           ,[Age]

           ,[Country])

     VALUES

           (@Name,

            @Email,

                  @Address,

                  @Age,

            @Country)

    set @i = @i + 1

end

go

 

·         Open Microsoft Visual Studio 2012 

·         Select New Project

·         Select Web from the Installed Templates

·         Select ASP.NET                 MVC4 Web Application

·         Select Web API from the Select a template option

·         Click OK.

Add the following Modal classes (Student and StudentContext) in your Model folder:

    public class Student

    {

        public int StudentId { get; set; }

        public string Name { get; set; }

        public string Email { get; set; }

        public string Address { get; set; }

        public int Age { get; set; }

        public string Country { get; set; }

    }

 

    public class StudentDbContext : DbContext

    {

        public DbSet<Student> Students { get; set; }

    }

Also include Entity framework reference in your project because in this application we are going to use entity framework code first model to add, edit, delete and find records from the database. To include entity framework dll, follow these steps:

Go to Project - Manage NuGet Packages - Enter entity framewrok in the search textbox and search online.

You also have to configure your web.config file for the implementation of this project. Add the connectionStrings element under configuration tag:

 

<connectionStrings>

    <add name="StudentDbContext" providerName="System.Data.SqlClient" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=StudentDb;Integrated Security=true;" />

</connectionStrings>

 

Add a Controller in your project name as StudentController and the edit the controller with following given code and save it.

    public class StudentController : ApiController

    {

        StudentDbContext dbStudent = new StudentDbContext();

 

        public IEnumerable<Student> Get()

        {

            return dbStudent.Students.ToList();

        }

 

        public Student Get(int id)

        {

            return dbStudent.Students.FirstOrDefault(m => m.StudentId == id);

        }

 

        public HttpResponseMessage Post(Student student)

        {

            dbStudent.Students.Add(student);

            dbStudent.SaveChanges();

 

            return Request.CreateResponse(HttpStatusCode.Created);

        }

 

        public HttpResponseMessage Put(Student student)

        {

            Student studentOriginal = dbStudent.Students.Find(student.StudentId);

            dbStudent.Entry(studentOriginal).CurrentValues.SetValues(student);

            dbStudent.SaveChanges();

 

            return Request.CreateResponse(HttpStatusCode.NoContent);

        }

 

        public HttpResponseMessage Delete(int id)

        {

            Student student = dbStudent.Students.FirstOrDefault(m => m.StudentId == id);

            dbStudent.Students.Remove(student);

            dbStudent.SaveChanges();

 

            return Request.CreateResponse(HttpStatusCode.NoContent);

        }

    }

Now our MVC Web API part is over. Let’s move towards Sencha touch app (Sencha Architect) where we design our app and interact with the MVC Web API via Model and Store.

 

This is how the main screen of the apps is will look like:

The main screen will show the list of records, a search bar to searching records, an add button on top to add new record. When you tap or click on the list record, it should show the edit screen.

 

 

 

 

 

 

 

·         Open Sencha Architect

·         Select Sencha Touch option as shown in figure below:

Save your project in the MVC Web API application root folder. In the same location where we have created our ASP.Net MVC Web API project.

 

Add a model in a project and configure the model properties as shown below:

Ext.define('MyApp.model.Student', {

    extend: 'Ext.data.Model',

 

    config: {

        idProperty: 'StudentId',

        fields: [

            {

                name: 'StudentId',

                type: 'int'

            },

            {

                name: 'Name'

            },

            {

                name: 'Email'

            },

            {

                name: 'Address'

            },

            {

                name: 'Age',

                type: 'int'

            },

            {

                name: 'Country'

            }

        ],

        proxy: {

            type: 'rest',

            url: '/api/Student'

        }

    }

});

Here I create a Model called Student, using the Ext.data.Model. Here I define what field I wanted to have; now I only needed StudentId, Name, Email, Address, Age and Country. Also added a rest proxy in our model so that it takes care of insert, updates and delete operation.

 

Then we need a Store for this model.

Ext.define('MyApp.store.Student', {

    extend: 'Ext.data.Store',

 

    requires: [

        'MyApp.model.Student'

    ],

 

    config: {

        model: 'MyApp.model.Student',

        storeId: 'Student',

        proxy: {

            type: 'rest',

            url: '/api/Student'

        }

    }

});

The usual culprit, the extend of Ext.data.Store.

Here I define the model to be use for this store, which is Student. The proxy used to define how to handle the data.

 

Now to create a view (List)

Ext.define('MyApp.view.List', {

    extend: 'Ext.dataview.List',

    alias: 'widget.studentlist',

 

    config: {

        store: 'Student',

        itemTpl: [

            '<div>Name: {Name}</div>',

            '<div>Email: {Email}</div>'

        ],

        items: [

            {

                xtype: 'titlebar',

                docked: 'top',

                items: [

                    {

                        xtype: 'textfield',

                        itemId: 'txtSearchText'

                    },

                    {

                        xtype: 'button',

                        action: 'search-student',

                        itemId: 'btnSearch',

                        iconCls: 'search'

                    },

                    {

                        xtype: 'button',

                        action: 'student-add',

                        align: 'right',

                        itemId: 'btnAdd',

                        iconCls: 'add'

                    }

                ]

            }

        ]

    }

});

For listing, we need to use Ext.dataview.List. In the config section, the store is telling the list where to get the data and bind it on the list.

The itemTpl define the HTML template to display the data, each keyword in curly bracket (e.g. {Name}. {Email}) is the field name defined in Model where the Store is link to.

Here I create toolbar because I want to display search textbox and the add button on the top of the screen.

 

Add a view (Form). Since the editing and creating Student screen going to be same, so we can share the same screen.

Ext.define('MyApp.view.Form', {

    extend: 'Ext.form.Panel',

    alias: 'widget.studentform',

 

    config: {

        layout: {

            type: 'fit'

        },

        items: [

            {

                xtype: 'fieldset',

                title: 'Student',

                items: [

                    {

                        xtype: 'textfield',

                        label: 'Name',

                        name: 'Name'

                    },

                    {

                        xtype: 'emailfield',

                        label: 'Email',

                        name: 'Email',

                        placeHolder: 'email@example.com'

                    },

                    {

                        xtype: 'numberfield',

                        label: 'Age',

                        name: 'Age'

                    },

                    {

                        xtype: 'selectfield',

                        label: 'Country',

                        name: 'Country',

                        options: [

                            {

                                text: 'India',

                                value: 'India'

                            },

                            {

                                text: 'Newzeland',

                                value: 'Newzeland'

                            }

                        ]

                    },

                    {

                        xtype: 'textareafield',

                        label: 'Address',

                        name: 'Address'

                    },

                    {

                        xtype: 'hiddenfield',

                        name: 'StudentId'

                    }

                ]

            }

        ]

    }

});

Here we need to use the Ext.form.Panel, and add the fieldSet, textfield, emailfield, numberfield, selectfield, textareafield and hiddenfield.

We have give name of each fields in order to link the form with the Student Model fields.

 

Add another view (Panel) to add student record.

Ext.define('MyApp.view.Add', {

    extend: 'Ext.Panel',

    alias: 'widget.studentadd',

 

    requires: [

        'MyApp.view.Form'

    ],

 

    config: {

        layout: {

            type: 'vbox'

        },

        items: [

            {

                xtype: 'titlebar',

                docked: 'top',

                title: 'Add Student',

                items: [

                    {

                        xtype: 'button',

                        action: 'back',

                        ui: 'back',

                        text: 'back'

                    }

                ]

            },

            {

                xtype: 'toolbar',

                docked: 'bottom',

                items: [

                    {

                        xtype: 'spacer'

                    },

                    {

                        xtype: 'button',

                        action: 'student-save',

                        ui: 'confirm',

                        iconAlign: 'right',

                        text: 'Add'

                    }

                ]

            },

            {

                xtype: 'studentform',

                itemId: 'studentAddform',

                flex: 1

            }

        ]

    }

 

});

Then create a toolbar, docked it on the top, give it a title “Add Student”, and add a back (action:back) button. Create another toolbar and docked it to bottom and add a save button (action:student-save) on it.

Drag Form component to Add view and click on Link to use it in the Add view. (Below figure)

Add another view (Panel) to update and delete the student record:

Ext.define('MyApp.view.Edit', {

    extend: 'Ext.Panel',

    alias: 'widget.studentedit',

 

    requires: [

        'MyApp.view.Form'

    ],

 

    config: {

        layout: {

            type: 'vbox'

        },

        items: [

            {

                xtype: 'titlebar',

                docked: 'top',

                title: 'Edit Student',

                items: [

                    {

                        xtype: 'button',

                        action: 'back',

                        ui: 'back',

                        text: 'back'

                    }

                ]

            },

            {

                xtype: 'toolbar',

                docked: 'bottom',

                items: [

                    {

                        xtype: 'button',

                        action: 'student-delete',

                        ui: 'action',

                        text: 'Delete'

                    },

                    {

                        xtype: 'spacer'

                    },

                    {

                        xtype: 'button',

                        action: 'student-save',

                        ui: 'confirm',

                        text: 'Save'

                    }

                ]

            },

            {

                xtype: 'studentform',

                itemId: 'studentEditForm',

                flex: 1

            }

        ]

    }

 

});

Then create a toolbar, docked it on the top, give it a title “Edit Student”, and add a back (action:back) button. Create another toolbar and docked it to bottom and add a save button (action:student-save) and delete button (action:student-delete) on it.

Drag Form component to Edit view and click on Link to use it in the Edit view. (Below figure)

 

We’ve got the view ready and model, now what we need is controller to tell how the view works.

 Add a controller (Student)

Ext.define('MyApp.controller.Student', {

    extend: 'Ext.app.Controller',

 

    config: {

        refs: {

            listView: 'studentlist',

            addView: 'studentadd',

            addButton: 'studentlist button[action=student-add]',

            backButton: 'button[action=back]',

            saveButton: 'studentadd button[action=student-save]',

            editView: 'studentedit',

            editButton: 'studentedit button[action=student-save]',

            deleteButton: 'studentedit button[action=student-delete]',

            searchButton: 'studentlist button[action=search-student]'

        },

 

        control: {

            "addButton": {

                tap: 'showAddView'

            },

            "backButton": {

                tap: 'showListView'

            },

            "saveButton": {

                tap: 'addStudent'

            },

            "editButton": {

                tap: 'editStudent'

            },

            "listView": {

                itemtap: 'onItemTapAction'

            },

            "deleteButton": {

                tap: 'deleteStudent'

            },

            "searchButton": {

                tap: 'searchStudent'

            }

        }

    },

 

    showAddView: function (button, e, eOpts) {

 

        var view = this.getAddView() ? this.getAddView() : Ext.create("MyApp.view.Add", { title: 'Add' });

 

        Ext.Viewport.setActiveItem(view);

    },

 

    showListView: function (button, e, eOpts) {

        var view = this.getListView() ? this.getListView() : Ext.create("MyApp.view.List");

 

        Ext.Viewport.setActiveItem(view);

    },

 

    addStudent: function (button, e, eOpts) {

        var addView = this.getAddView();

 

        var form = addView.down('#studentAddform'),

            values = form.getValues(),

            store = Ext.getStore('Student');

 

        store.add(values);

        store.sync();

        form.reset();

 

        this.showListView();

    },

 

    editStudent: function (button, e, eOpts) {

        var controller = this;

        var editView = this.getEditView();

 

        var form = editView.down('#studentEditForm'),

            values = form.getValues(),

            store = Ext.getStore('Student'),

            record = store.getById(values.StudentId);

 

        record.set({

            StudentId: values.StudentId,

            Name: values.Name,

            Email: values.Email,

            Age: values.Age,

            Country: values.Country,

            Address: values.Address

        });

 

        if (record.isValid()) {

            record.save({

                success: function () {

                    store.sync();

                    form.reset();

                    controller.showListView();

                },

                error: function () {

 

                    Ext.Msg.alert("Error", "There are errors with the record!");

                }

            });

        }

        else {

            Ext.Msg.alert("Error", "There are errors with the record!");

        }

    },

 

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

 

        this.showEditView(record.data);

    },

 

    deleteStudent: function (button, e, eOpts) {

        var editView = this.getEditView();

 

        var form = editView.down('#studentEditForm'),

            values = form.getValues(),

            store = Ext.getStore('Student'),

            record = store.getById(values.StudentId),

            recordIndex = store.findExact('StudentId', record.data.StudentId);

        controller = this;

 

        Ext.Msg.confirm(

        "Delete Student",

        "Are you sure want to delete?",

        function (btn) {

            if (btn == 'yes') {

                store.removeAt(recordIndex);

                store.sync();

                controller.showListView();

            }

        }

        );

 

    },

 

    searchStudent: function (button, e, eOpts) {

 

        var listView = this.getListView(),

            searchValue = listView.down('#txtSearchText').getValue(),

            store = listView.getStore();

 

        listView.setScrollToTopOnRefresh(true);

        store.data.clear();

 

        store.getProxy()._extraParams.value = searchValue;

 

        store.loadPage(1, function (records, operation, success) {

            listView.refresh();

            listView.setScrollToTopOnRefresh(true);

        });

    },

 

    showEditView: function (record) {

        var view = this.getEditView() ? this.getEditView() : Ext.create('MyApp.view.Edit');

        var form = view.down('#studentEditForm');

 

        form.setValues(record);

        Ext.Viewport.setActiveItem(view);

    }

 

});

Usual thing again, define a controller with naming convention, then extend the Ext.app.Controller, and define few functions showAddView, showEditView, addStudent, editStudent, deleteStudent, searchStudent, so that we can fire an action.

How to add a reference in controller in Sencha architect?

·         Select controller

·         Add a reference  

·         Enter Reference name

·         Enter Selector name

The given below two figures shows how we can add a reference:

1)

2)

How to add a controller action in Sencha Architect?

The given below three figures show you how can we add a controller action:

·         Select Controller

·         Find Action property

·         Click add(+) button to add an action

1)

2) Select targetType, For example:

targetType: Ext.Button

3) Then choose and event by name, for example:

name: tap

After adding an action configures the following properties of an action:

·         Rename function name and edit controlQuery property of action:

o   For example:

§  fn: searchStudent (name of the function which calls on the click of button)

§  controlQuery: searchButton (name of the reference)

Add a launch method in an application in order to launch a view, as shown in below given figure:

Add the following code on the launch method:

Ext.Viewport.add([

{ xtype: 'studentlist' }

]);

Run an application and test the functionalities:

I’m still very new to Sencha Touch and I’m learning while developing this apps, so I might have mistakes here and there, but hope it helps people that need some example, as how I looking for Sencha Touch MVC example last time.

Thanks for reading this article. I think this will help a lot.

1 comment:

Unknown said...

Thanks you very much.