Jorge Ramon

  • Home
  • New Here?
  • Articles
    • All
    • Sencha Touch
    • jQuery Mobile
    • ExtJS
  • Books
  • About
You are here: Home / Tutorials / Sencha Touch Tutorials / Writing a Sencha Touch MVC Application

Writing a Sencha Touch MVC Application

August 10, 2011 84 Comments

In this article we will explore one of the approaches we can take to create a Sencha Touch application using the MVC pattern. I will base the tutorial on the Notes Application we created in the Writing a Sencha Touch Application series. Our goal is to build a new version of the Notes Application using Sencha Touch MVC.

The Notes Application allows its users to take notes and store them on the device running the app. The features we built into the app, which we will reproduce in the MVC version, are the following:

  • Ability to create notes
  • Ability to edit existing notes
  • Ability to delete notes
  • Ability to persist notes on the device running the application, across browser sessions

In terms of user interface, the application revolves around two views, the Notes List view and the Note Editor view:

Ready? Let’s get started.

The model-view-controller pattern in Sencha Touch

As of version 1.1.0 of Sencha Touch, the framework’s implementation of the model-view-controller pattern is, in my opinion, incomplete and poorly documented. However, we can still take advantage of it to build high-quality applications.

In general, a Sencha Touch MVC application will consist of one or more views, one or more data models and stores, and one or more controllers. Views have a dual role: they render representations of the data in the models, and capture and transmit user input to the controllers. Controllers will translate the user’s input into changes in the data and/or the behavior of the application. Models represent the application’s data and state.

In Sencha Touch MVC parlance, the mechanism by which views send messages to the controllers is called dispatch, and the controller functions used to handle these messages are called actions.

Let’s apply these concepts to our Notes Application and come up with a tentative design.

The Notes App use cases, MVC style

Based on our requirements list, we can translate our use cases into the following MVC workflows:

  1. When the application launches, the user will be presented with a list of the existing notes, or an empty list if there are no notes saved. This will happen by invoking a controller’s index action, which in turn will render the Notes List view:
  2. When our user needs to create a new note, she will tap the New button in the Notes List view. This will invoke the newnote action in a controller, where a new note will be created and loaded into the Note Editor view:
  3. Similarly, when our user needs to edit a note, she will tap the disclosure button for the given note. This will invoke the editnote action in a controller, causing the note to be loaded into the Note Editor view:
  4. Tapping the Save button in the Note Editor view will invoke a controller’s savenote action, where the note will be saved in notes cache and the Notes List view will be activated:
  5. If our user taps the Trash button in the Note Editor view, the view will invoke a controller’s deletenote action. This action will delete the note loaded in the view and activate the Notes List view:
  6. Tapping the Home button in the Note Editor view will invoke a controller’s canceledit action, which will discard any changes made to the loaded note, and activate the Notes List view:

Notice that I have referred to “a controller” in my descriptions of the use cases. This means that we still don’t know if we will use one or many controllers in the application. We will make this decision in a few minutes.

All right. Now that we have an idea about how we’re going to build the Notes Application, MVC-style, let’s talk about files.

Distributing a Sencha Touch application across multiple files

You should consider distributing your Sencha Touch application’s source code across multiple files. A single source file might be fine for a very small application, however, as the application and the development team grow, you can cut development and maintenance costs by using a multiple-files model.

What we will do for this example is, first, create the right folder structure for the application, and then create the different source files that will contain the application’s components. The folder structure reflects the MVC pattern we will use to build the application:

We have a root folder called app, and under it, folders for the models, views, controllers and data stores. Besides being self-explanatory, it follows Sencha’s recommendation to place models, views and controllers in separate folders. Sencha’s build tools are capable of leveraging this structure to create the application’s namespaces when it’s time to build a production-ready version of the source files.

At this point we have modeled our MVC workflows and created the right folder structure. What do you say about writing some code?

The Note data model

The Note model is the data model that represents a note. Its source goes in the NoteModel.js file, which we will place in the models folder. This is the source:

Ext.regModel('NoteModel', {
    idProperty: 'id',
    fields: [
        { name: 'id', type: 'int' },
        { name: 'date', type: 'date', dateFormat: 'c' },
        { name: 'title', type: 'string' },
        { name: 'narrative', type: 'string' }
    ],
    validations: [
        { type: 'presence', field: 'id' },
        { type: 'presence', field: 'title', message: 'Please enter a title for this note.' }
    ]
});

The Notes data store

The NotesStore is our notes cache. It uses the NoteModel class as its model and it’s configured to use an instance of the Ext.data.LocalStorageProxy class as its proxy. This allows us to save notes across browser sessions. We will place the NotesStore class in the NotesStore.js file, which lives in the stores folder. This is the store’s source:

Ext.regStore('NotesStore', {
    model: 'NoteModel',
    sorters: [{
        property: 'date',
        direction: 'DESC'
    }],
    proxy: {
        type: 'localstorage',
        id: 'notes-app-store'
    },
    getGroupString: function (record) {
        if (record && record.data.date) {
            return record.get('date').toDateString();
        } else {
            return '';
        }
    }
});

NotesApp.stores.notesStore = Ext.StoreMgr.get('NotesStore');

The Main view

As in the first version of the application, the application’s main view will serve as the viewport, hosting the Notes List view and the Note Editor view. This view’s class goes in the MainView.js file, which we will place in the views folder:

NotesApp.views.MainView = Ext.extend(Ext.Panel, {
    fullscreen: true,
    layout: 'card',
    cardSwitchAnimation: 'slide',
    initComponent: function () {

        Ext.apply(NotesApp.views, {
            notesListView: new NotesApp.views.NotesListView({ notesStore: NotesApp.stores.notesStore }),
            noteEditorView: new NotesApp.views.NoteEditorView()
        });

        this.items = [
            NotesApp.views.notesListView,
            NotesApp.views.noteEditorView
        ]

        NotesApp.views.MainView.superclass.initComponent.call(this);

        this.on('render', function () {
            NotesApp.stores.notesStore.load();
        });
    }
});

The Notes List view

We will use an instance of the NotesListView class to render the list of cached notes and allow the user to start the “new note” and “edit note” workflows. Its file, NotesListView.js, goes in the views folder. This is the source:

NotesApp.views.NotesListView = Ext.extend(Ext.Panel, {

    notesStore: Ext.emptyFn,
    notesList: Ext.emptyFn,

    layout: 'fit',

    initComponent: function () {

        this.newButton = new Ext.Button({
            text: 'New',
            ui: 'action',
            handler: this.onNewNote,
            scope: this
        });

        this.topToolbar = new Ext.Toolbar({
            title: 'My Notes',
            items: [
                { xtype: 'spacer' },
                this.newButton
            ]
        });

        this.dockedItems = [this.topToolbar];

        this.notesList = new Ext.List({
            store: this.notesStore,
            grouped: true,
emptyText: '
<div style="margin: <span class=;">5px;">No notes cached.</div>
<pre>
</pre><pre>',
            onItemDisclosure: true,
itemTpl: '
<div class="list-item-title">{title}</div>
</pre><pre>' +
                            '<div class="list-item-narrative">{narrative}</div>'

        });

        this.notesList.on('disclose', function (record, index, evt) {
            this.onEditNote(record, index);
        }, this),

        this.items = [this.notesList];

        NotesApp.views.NotesListView.superclass.initComponent.call(this);
    },

    onNewNote: function () {
        Ext.dispatch({
            controller: NotesApp.controllers.notesController,
            action: 'newnote'
        });
    },

    onEditNote: function (record, index) {
        Ext.dispatch({
            controller: NotesApp.controllers.notesController,
            action: 'editnote',
            note: record
        });
    },

    refreshList: function () {
        this.notesList.refresh();
    }
});

Let’s pause here and examine a few details.

While the initComponent() function should be very familiar to you, things become interesting when we look at the helper functions onNewNote() and onEditNote(). These functions will allow us to signal the view’s controller that the user executed either the “new note” or “edit note” commands. The newnote or editnote controller actions will be invoked in response to these commands.

How does the view send these signals to the controller? Well, it’s pretty simple. Remember what I said earlier about dispatch? Every application gets a default instance of the Dispatcher class, which you can use to send requests to specific actions in a given controller. Invoking Ext.Dispatcher.dispatch() or its shorthand, Ext.dispatch(), will find the desired controller and call the correct controller action.

You should pass the controller and action arguments to the dispatch() function. And you can also pass any other parameters that the controller might need to execute the action correctly. For example, in the onEditNote() function we also pass the record corresponding to the note the user needs to edit.

The third function, refreshList(), will allow this view’s controller to re-render the list of notes in the view after the list has been modified.

OK, we already dispatched a couple of messages to a controller that does not exist. How about we create it?

How many controllers does a Sencha Touch MVC application need?

I don’t think they make rules for this. It depends on the application. I know that the Notes App is small: three simple views and six actions. It looks like one controller is enough for this one.

Let’s create the NotesController.js file in the controllers folder, and add the following code to it:

Ext.regController('NotesController',{

    'index': function (options) {

    },

    'newnote': function (options) {

    },

    'editnote': function (options) {

    },

    'savenote': function (options) {

    },

    'deletenote': function (options) {

    },

    'canceledit': function (options) {

    }
});

NotesApp.controllers.notesController = Ext.ControllerManager.get('NotesController');

Starting to make more sense now? As you can see, the controller has the actions we have discussed. This is where we need to implement our use cases. But, before we do it, let’s work on the last view.

The Note Editor view

We will use an instance of the NoteEditorView class to give our users the ability to edit and delete notes. This class goes in the NoteEditorView.js file, in the views folder:

NotesApp.views.NoteEditorView = Ext.extend(Ext.form.FormPanel, {

    initComponent: function () {

        this.backButton = new Ext.Button({
            text: 'Home',
            ui: 'back',
            handler: this.backButtonTap,
            scope: this
        });

        this.saveButton = new Ext.Button({
            text: 'Save',
            ui: 'action',
            handler: this.saveButtonTap,
            scope: this
        });

        this.trashButton = new Ext.Button({
            iconCls: 'trash',
            iconMask: true,
            handler: this.trashButtonTap,
            scope: this
        });

        this.topToolbar = new Ext.Toolbar({
            title: 'Edit Note',
            items: [
                this.backButton,
                { xtype: 'spacer' },
                this.saveButton
            ]
        });

        this.bottomToolbar = new Ext.Toolbar({
            dock: 'bottom',
            items: [
                { xtype: 'spacer' },
                this.trashButton
            ]
        });

        this.dockedItems = [this.topToolbar, this.bottomToolbar];

        NotesApp.views.NoteEditorView.superclass.initComponent.call(this);
    },

    backButtonTap: function () {
        Ext.dispatch({
            controller: NotesApp.controllers.notesController,
            action: 'canceledit'
        });
    },

    saveButtonTap: function () {
        Ext.dispatch({
            controller: NotesApp.controllers.notesController,
            action: 'savenote'
        });
    },

    trashButtonTap: function () {
        Ext.dispatch({
            controller: NotesApp.controllers.notesController,
            action: 'deletenote'
        });
    },

    items: [{
        xtype: 'textfield',
        name: 'title',
        label: 'Title',
        required: true
    }, {
        xtype: 'textareafield',
        name: 'narrative',
        label: 'Narrative'
    }]
});

The helper functions saveButtonTap(), trashButtonTap() and backButtonTab() will allow us to signal the controller that the “save note”, “delete note” or “cancel edit” commands were executed by the user. The application will run the savenote, deletenote or canceledit controller actions in response to these commands.

Now that our views are finished, let’s implement the controller actions.

Implementing controller actions

Back in the NotesController class, as we’ve already discussed, the index action will create the Main view and activate the Notes List view:

'index': function (options) {

    if (!NotesApp.views.mainView) {
        NotesApp.views.mainView = new NotesApp.views.MainView();
    }

    NotesApp.views.mainView.setActiveItem(
        NotesApp.views.notesListView
    );
}

The index action will be invoked when the application launches. We will see how this is done when we implement the application’s launch() function.

The newnote controller action will create a new note, load it into the Note Editor view, and activate the view:

'newnote': function (options) {

    var now = new Date();
    var noteId = now.getTime();
    var note = Ext.ModelMgr.create({ id: noteId, date: now, title: '', narrative: '' },
        'NoteModel'
    );

    NotesApp.views.noteEditorView.load(note);
    NotesApp.views.mainView.setActiveItem(
        NotesApp.views.noteEditorView,
        { type: 'slide', direction: 'left' }
    );
}

We need the editnote action to load the selected note into the Note Editor view:

'editnote': function (options) {

    NotesApp.views.noteEditorView.load(options.note);
    NotesApp.views.mainView.setActiveItem(
        NotesApp.views.noteEditorView,
        { type: 'slide', direction: 'left' }
    );
}

The savenote action will save the note in the cache and activate the Notes List view:

'savenote': function (options) {

    var currentNote = NotesApp.views.noteEditorView.getRecord();

    NotesApp.views.noteEditorView.updateRecord(currentNote);

    var errors = currentNote.validate();
    if (!errors.isValid()) {
        currentNote.reject();
        Ext.Msg.alert('Wait!', errors.getByField('title')[0].message, Ext.emptyFn);
        return;
    }

    if (null == NotesApp.stores.notesStore.findRecord('id', currentNote.data.id)) {
        NotesApp.stores.notesStore.add(currentNote);
    } else {
        currentNote.setDirty();
    }

    NotesApp.stores.notesStore.sync();

    NotesApp.stores.notesStore.sort([{ property: 'date', direction: 'DESC'}]);

    NotesApp.views.notesListView.refreshList();

    NotesApp.views.mainView.setActiveItem(
        NotesApp.views.notesListView,
        { type: 'slide', direction: 'right' }
    );
}

Next comes the deletenote action. This action will delete the note loaded in the Note Editor and activate the Notes List view:

'deletenote': function (options) {

    var currentNote = NotesApp.views.noteEditorView.getRecord();

    if (NotesApp.stores.notesStore.findRecord('id', currentNote.data.id)) {
        NotesApp.stores.notesStore.remove(currentNote);
    }

    NotesApp.stores.notesStore.sync();
    NotesApp.views.notesListView.refreshList();

    NotesApp.views.mainView.setActiveItem(
        NotesApp.views.notesListView,
        { type: 'slide', direction: 'right' }
    );
}

Finally, the controller’s canceledit action will discard any changes made to the loaded note, and activate the Notes List view:

'canceledit': function (options) {

    NotesApp.views.mainView.setActiveItem(
        NotesApp.views.notesListView,
        { type: 'slide', direction: 'right' }
    );
}

You with me so far? We’re almost done.

Compared to the first version of the app, we’ve moved most of the application’s behavior out of the views, which now deal strictly with UI matters, and into a central location. I can see the MVC version being easier to understand and support.

Now that we have our data store, model, views and controller in place, we’re just missing the piece that will get this whole mechanism going.

Launching the application

We will place our app’s entry point in the app.js file, app folder, together with the index.html and app.css files. We will use app.js to create our application’s instance like so:

var App = new Ext.Application({
    name: 'NotesApp',
    useLoadMask: true,

    launch: function () {
        Ext.dispatch({
            controller: NotesApp.controllers.notesController,
            action: 'index'
        });
    }
});

And that’s it. Makes sense?

As you can imagine, this is not the only approach you can take for incorporating the MVC pattern in a Sencha Touch app. You can go from rolling out your own implementation, to taking full advantage of the framework’s built-in features, which I think are still a work in progress. Either way, you should be able to reach a satisficing solution that makes your application easier to develop and more maintainable.

What do you think?

Download this tutorial’s source: NotesApp-v1.zip

Want To Learn More?

My Sencha Touch books will teach you how to create an application from scratch.

  • Sencha Touch 2 Book
  • Sencha Touch 1 Book

Stay Tuned

Don’t miss any articles. Get free updates in your inbox.



MiamiCoder will never sell your email address.

Tagged With: Sencha Touch Tutorial 84 Comments

Comments

  1. Ted says

    August 11, 2011 at 4:33 PM

    Jorge, thanks for this! One question, and I know it’s been talked about before: Using Ext.Dispatch in the views and specifying a controller/action seems to make the views tightly coupled to the controller. The other school of thought on this is that views should just fire events and not worry about what may be listening for them, thereby keeping them fairly thin. You’d then just listen for whatever events you wanted in your controller(s). I’d love to hear how what you think about these things, because I do notice that your Ext.dispatch way seems to be used most often.

    Thanks again for all of this work! The community appreciates it!!

    Reply
    • Jorge says

      August 11, 2011 at 6:51 PM

      Hey Ted, good to see you here again. 🙂

      I tend to favor firing events from the views. It feels more natural to me, and I feel more in control too. When I use the current implementation of MVC, more often than not, I feel like I have to adapt to the way the tool works instead of the tool adapting to how I work. But there’s nothing wrong with either approach as long as it solves your specific problem.

      I’d love to hear other opinions. I hope more readers leave a note with their thoughts on this.

      Reply
      • Don says

        August 17, 2011 at 2:27 PM

        I totally agree with you Jorge. The views should simply expose events that can be listened for by the controllers. The tight coupling of Ext.Dispatch within the views was my first thought when reading through the post.

        Reply
        • Brad Swardson says

          December 29, 2011 at 7:37 PM

          I think what Ted is referring to in the coupled nature of the design is that the views in the code above specifically target the controller and it’s action within the Dispatch function. This couples the view to the controller such that if you change the controller by say separating it into multiple controllers you would then have to edit the views to point to the new controllers and actions.

          Instead if the view fires an event into the DOM and the controllers listen for specific events no matter where they come from and the view has no idea what will happen with that event, nor does it care. This is the fully decoupled MVC style of coding Ted was referring too. Now, being brand new to Sencha Touch I don’t know how this would be implemented (off to do it now), but I see the point he was making and the response that Jorge provided where this is simply a method he likes to use for his own purposes.

          Great site, great tutorial set and great discussion.

          Reply
          • Jorge says

            December 29, 2011 at 8:51 PM

            Good point. Let us know how it goes for you.

  2. hao says

    August 24, 2011 at 5:55 AM

    Really great posts! Very helpful while I am starting to learn some Sencha Touch.

    Many thanks!

    Reply
  3. urchin says

    September 5, 2011 at 10:43 AM

    Thanks for this great tutorial!

    Do you know whether sencha touch support automatically creating identifiers (primary keys, whatever) for the models? Using a clock timestamp seems a little dangerous for my tastes.

    Thanks!

    Reply
  4. Rando says

    September 10, 2011 at 1:13 PM

    By far the best tuto I ever came across on Sencha MVC. Very useful.

    It would be interesting to get a follow-up post to explain how the event firing alternative (instead of Ext.dispatch) can be implemented.

    Reply
    • Jorge says

      September 10, 2011 at 11:37 PM

      Thank you Rando. As soon as I have some time I will write a version that does not use dispatch.

      Reply
  5. Malk says

    September 16, 2011 at 9:17 AM

    Will this work with Android phones? I cannot get anything up in the emulator?

    Thanks,

    Malk

    Reply
    • Jorge says

      September 16, 2011 at 9:38 AM

      Yes. Please review your emulator’s configuration.

      Reply
      • Malk says

        September 18, 2011 at 7:35 AM

        Hi Jorge, I’ll do that.

        Thanks for the reply. It looks great.

        Cheers,

        Malk

        Reply
  6. Nilesh Chavan says

    September 19, 2011 at 5:29 AM

    Hi Jorge!!!

    Gr8 tutorial. If you have any tutotrial for implementing WCF RESTFul Web service with sencha touch then please post the link or source.

    Thanks for support and help.

    Regards,
    Nilesh

    Reply
    • Jorge says

      September 20, 2011 at 12:57 PM

      Thank you Nilesh. I will try to put together a tutorial with WCF as soon as possible.

      Reply
  7. Aaron Wardle says

    September 20, 2011 at 6:03 PM

    This has to be the best tutorials I have followed so far for Sencha Touch.

    I’m just trying to work out how I can use a tab panel instead of a toolbar at the bottom of the screen, on the my notes view but cannot seem to figure it out.

    Any advice would be great

    Thanks Aaron

    Reply
  8. Romy says

    September 28, 2011 at 2:27 AM

    wow, thank you!

    Reply
  9. leela says

    September 29, 2011 at 12:36 AM

    Hi Jorge,
    Great work. This is the best tutorial. Thanks alottttttt 🙂 🙂

    Reply
  10. Xilon says

    October 10, 2011 at 1:19 PM

    I’ve followed your previous tutorial about writing a sencha touch application and everything worked fine, but when i tried to write it on mvc way it didn’t work……..i get errors like: “Uncaught reference error: Ext is not defined”,”Uncaught reference error: NotesApp is not defined” on all my .js files…….

    Any advice?

    By the way, thanks for all these tutorials, they were really helpful!

    Reply
    • Jorge says

      October 10, 2011 at 2:20 PM

      Make sure that the sencha-touch.js and sencha-touch.css files are in the right directory.

      Reply
      • Xilon says

        October 11, 2011 at 8:09 AM

        Problem solved! My index.html was importing sencha-touch-debug.js instead of sencha-touch.js. Thanks again!

        Reply
  11. pablo says

    October 12, 2011 at 1:46 AM

    Thanks Jorge, best tutorial on MVC that I found for MVC. Should be added to sencha’s blog.
    Love to hear other ways of organizing the code.

    Reply
  12. Kurt says

    November 6, 2011 at 5:16 AM

    Good day!

    Your writing style and tutorial has helped me massively to grasp sencha touch. Keep up the good work!

    Sencha touch should consider making the ‘Notess app’ their hello world example, as their current example is setup poorly according to me.

    Cheers, bookmarked!

    Reply
  13. Xilon says

    November 9, 2011 at 10:51 AM

    Hi! I am building my own mvc based app, following the instructions on this tutorial. I ‘ve succesfully built this NotesApp following the tutorial, but now i can’t make my application work on mvc way. I get this error message: “Uncaught TypeError: Cannot call method ‘setActiveItem’ of undefined” on my controller

    Ext.regController(‘PeopleController’, {

    ‘index’: function (options) {

    if (!PeopleApp.views.MainView) {
    PeopleApp.views.mainView = new PeopleApp.views.MainView();
    }

    PeopleApp.views.mainView.setActiveItem(
    PeopleController.js:9 Uncaught TypeError: Cannot call method ‘setActiveItem’ of undefined
    PeopleApp.views.searchView
    );
    }
    Im pretty sure i’ ve made all the necessary references, i’ ve added all the necessary .js the files on index.html and followed all the steps like in your tutorial. I’m really a beginner on sencha and javascript, and I really apreciate your help even i guess i couldn t explain well the problem i have.

    Thanks!

    Reply
    • Jorge says

      November 9, 2011 at 11:16 AM

      Xilon, based on your comment, I see that the error refers to PeopleApp.views.searchView, while your controller is creating PeopleApp.views.mainView.

      Reply
      • John Uri says

        November 10, 2011 at 12:35 AM

        Hi Jorge,

        I’m also experiencing the same issue as Xilon. The example posted by Xilon seems to replicate your example eg: it is creating MainView and then activating searchView.

        Anyway, looking at that error – isn’t the problem with the if condition or rather
        that PeopleApp.views.mainView is always going to be undefined? The error basically is like a null pointer exception, can’t execute the method ‘setActiveItem’ on a null object.

        Also a noob at this Sencha Touch, so would appreciate any help.

        Thanks

        Reply
        • Jorge says

          November 10, 2011 at 7:45 AM

          Looks like your code needs to create mainView before trying to activate it.

          Reply
      • Xilon says

        November 10, 2011 at 11:50 AM

        Thanks for the reply, but as i tought, the lack of information i gave the previous post didn’t help…..The problem is that my controller is calling the searchView through the mainView.setactiveItem just like your controller is calling notesListView through your mainView.SetActiveItem. What i don’t understand is why your app works but mine doesn’t. And again, I’m pretty sure i didnt forget anything and followed every step of your tutorial.

        Thanks!

        Reply
  14. max says

    November 17, 2011 at 2:44 AM

    ok I completed this MVC Tutorial works fine on browser, but on my phone this goes as far as saying ‘loading my notes..’ then goes blank ???

    Reply
  15. max says

    November 17, 2011 at 3:23 PM

    it doesnt even work in the browser now spent 2 hours still dont know whats going on….. downloaded the zip uploaded on server just states ‘loading my notes…’ then blank 🙁

    Reply
  16. max says

    November 17, 2011 at 4:33 PM

    Uncaught TypeError: Cannot read property ‘id’ of null is what i get in the console….

    Reply
    • Jorge says

      November 18, 2011 at 8:58 AM

      Max, please review the degug output. You should be able to spot where the problem is.

      Reply
  17. raph says

    November 18, 2011 at 8:52 AM

    Thank you for your excellent tutorial.

    Reply
  18. josh says

    November 22, 2011 at 12:19 PM

    Thanks for the tutorial, I would appreciate it if you can do the same using the sencha touch 2.0 package, highlighting the changes and all that. i am sure that yours will be the best resource covering that as i haven’t seen any detailed tutorial on sencha touch like yours. Pleaaaassseeee , it would be greatly appreciated.thanks

    Reply
    • Jorge says

      November 22, 2011 at 12:56 PM

      You’re welcome, Josh. As soon as there’s stable Sencha Touch 2 version, I will begin publishing tutorials for it.

      Reply
  19. Ricardo T Fajardo says

    November 24, 2011 at 4:33 AM

    Hi George. Thank you for this tutorial. I am evaluating ExtJS and Senchatouch as an alternative to Android and XCode Web Apps. Any examples for displaying web magazine like (Wired – for Iphone )

    Reply
  20. max says

    December 9, 2011 at 2:12 PM

    Ok finally got it working it seemed I copied some code incorrectly, however,
    what is the fix for the app crashing after deleting some of the notes & refreshing?

    Reply
    • Jorge says

      December 9, 2011 at 2:57 PM

      Max, I cannot reproduce the crash you mention.

      Reply
  21. IDDQD says

    December 14, 2011 at 5:49 AM

    hello Jorge!
    awesome tutorial, but i found one bug:
    after the start of app, when you have an empty list and if you try to scroll up/down you will get an error in console:
    “Uncaught TypeError: Cannot read property ‘offset’ of undefined”

    Reply
    • Jorge says

      December 14, 2011 at 7:39 AM

      Thanks. I seem to remember seeing this reported as a List bug in the Sencha forum, but I’m not 100% sure. You might want to check in the forum to confirm.

      Reply
  22. IDDQD says

    December 14, 2011 at 10:51 AM

    Alson another bug with add\deleting notes:
    try to repeat this steps:
    run app with empty localstorage – e.g. first time ever.
    add new note, and check the localstorage //all is ok now: 1 new id, 1 new record
    add second note, check the localstorage //error! “notes-app-store” now contain doubled ID of first note!
    delete first one //one of doubled ID is deleted, but 1 is exist
    and now refresh the page – you will get an error
    “Uncaught TypeError: Cannot read property ‘id’ of null”
    error in line “NotesApp.stores.notesStore.load();”

    Reply
  23. Xilon says

    December 16, 2011 at 8:01 AM

    Hello again, I’m having a problem thats bothering me since i ve started working with sencha. On my MVC projects, always when i try to create a new view, when i declare it on MainView, i got this error:

    Ext.apply(SASPhonegap.views, {
    dadosCadastraisView: new SASPhonegap.views.DadosCadastraisView(),
    detalhesHistPagView: new SASPhonegap.views.DetalhesHistPagView()
    Uncaught TypeError : undefined is not a function
    });

    on this case, i got the error when declaring DetalhesHistPagView()

    im pretty sure ive done everything like your tutorial, declared DetalhesHistPagView on index.html, i called it on the file DetalhesHistPagView :

    SASPhonegap.views.DetalhesHistPagView.superclass.initComponent.call(this);

    I’m really desperate about this.

    Thanks

    Xilon

    Reply
  24. dcoder405 says

    December 22, 2011 at 5:36 AM

    Hi
    I’m getting started with Sencha Touch.

    I just download the app and was trying to run it with Sencha Touch 2 and I got error “Uncaught ReferenceError: NotesApp is not defined”. My question is that then your code is incompatible with Sencha Touch 2? Will it only work with ST v 1.1?

    Thanks in advance

    Reply
    • Jorge says

      December 22, 2011 at 9:22 AM

      Hi dcoder405.

      As I said in my articles, the framework version I used is 1.1. Sencha Touch 2 is currently in Developer Preview mode. It’s not stable and it’s not recommended that you build production applications with it. As soon as Sencha Touch v2 is officially released, I will port the code to that version.

      Reply
  25. bagusflyer says

    December 22, 2011 at 9:55 AM

    Great tutorial.

    One question as a newbie, I find you import all js files in index.html. I’m wondering the performance would be affected if those js file are too big. If there any way to only load the js when needed?

    Thanks

    Reply
    • Jorge says

      December 22, 2011 at 10:34 AM

      Thank you! For a production version of the app, you will need to minify the files, and if possible, import them dynamically. There are multiple ways for doing this. You can roll out your own code to import the js as needed, or use one of many libraries out there that allow you to do this. Sencha Touch 2 and ExtJS 4 have built-in facilities for dynamic load, by the way.

      Reply
  26. sam says

    December 23, 2011 at 1:29 AM

    gr88 tutorial indeed……….thanks for it.
    also, i ws building an app wch had a form whose fields i set in the js file………………..bt i am unable to put an image of my choice as a logo in the form……………any leads on how to handle that image directly from the js file in sencha????

    Reply
  27. Haritha says

    December 23, 2011 at 1:19 PM

    i have purchased the pdf and thanks for the gr8 pdf… i tried to execute the MVC application and stuck at this line in the Controllet ‘index’ function.

    if (!NotesApp.views.mainView)
    {
    NotesApp.views.mainView = new NotesApp.views.MainView();
    }
    NotesApp.views.MainView.setActiveItem(NotesApp.views.NotesListView );
    }

    Error i am receiving is

    Object has no method ‘getItemId’

    Reply
    • Jorge says

      December 24, 2011 at 1:26 PM

      Haritha, thank you for buying the book. Please check your source code for typos and other errors. You should also make sure sure that all the app’s files are present in the right folders.

      Reply
  28. AK says

    December 24, 2011 at 8:53 PM

    Hi Jorge,
    I just purchased your book. It is really good. Are there any plans to update the application, to use the new Sencha Touch2.0 (currently in preview mode), since a lot of changes have occurred in 2.0

    Thanks
    AK

    Reply
    • Jorge says

      December 25, 2011 at 9:54 AM

      AK – Thank you for buying the book. Yes, as soon as Sencha Touch 2 is stable, I will update the book. Stay tuned!

      Reply
  29. John says

    December 29, 2011 at 2:30 PM

    Hi I just Paid for the book but was not directed to download…..also tried sending an email but got kicked back. Please inform me of where to download the book I purchased.

    Thank you!

    -John

    Reply
    • Jorge says

      December 29, 2011 at 8:47 PM

      John –

      I just sent you the book via email. I’m sorry you could not download it. Please let me know if you received the message with the book.

      Reply
  30. Brad Swardson says

    December 29, 2011 at 5:05 PM

    Very well written tutorial Jorge. Very well written series of tutorials!

    I am a seasoned Flex/as3 developer making the jump to the mobile realm of HTML5/JS fun and have been really interested in using Sencha Touch. While the file documentation for Sencha Touch is great and the intro tutorials are easy to follow they fail to really show (and explain) the structure of this framework both in a straight manner and using the MVC organization. This tutorial really demystified a lot of the problems I was having with the framework.

    Thank you very much!

    Reply
    • Jorge says

      December 29, 2011 at 8:44 PM

      Thank you Brad. It’s good to know that the tutorials helped you.

      Reply
      • Brad Swardson says

        January 2, 2012 at 7:44 PM

        Definitely!

        Reply
  31. Niko says

    January 11, 2012 at 6:51 PM

    Thanks Jorge for creating such a wonderfully structured tutorial, which is condensed to the absolute right amount of information an developer needs to grasp the concepts behind Sencha Touch and building an own application. I am also looking forward to the update of your book to cover ST 2.
    Cheers!

    Reply
    • Jorge says

      January 11, 2012 at 9:14 PM

      Thank you, Nico.

      Reply
  32. Ross says

    January 15, 2012 at 10:19 AM

    I think you are my new hero! This tutorial is awesome and has helped me understand how the framework is constructed, particularly when using an MVC style approach.

    I haven’t looked extremely deeply into the documentation as of yet, but is it easy to create this application for example, where the notes are stored on a central database which can then be accessed by each user, rather than the notes being personal to them.

    The reason I ask is I am building a social network type application, where users will post messages (sort of like Twitter) which can then be viewed by other users and they can choose to reply etc

    Thanks!

    Reply
  33. Oliver says

    January 25, 2012 at 4:10 AM

    Hi Jorge

    Thank you very much for your tutorial, helped me a lot!
    I tried to load a Nested List instead of a List but somehow it didn’t work. I created an forum post in the sencha forum but maybe you can help me since you wrote the tutorial 🙂

    Here is the link: http://www.sencha.com/forum/showthread.php?176467-MVC-Application-NestedList&p=720699#post720699

    Thank you!

    Oliver

    Reply
  34. prabu says

    February 7, 2012 at 7:52 AM

    Hi..Please help ..
    i get errors like:
    “Uncaught reference error: Ext is not defined”,”Uncaught reference error: NotesApp is not defined” on all my .js files
    Any advice?
    index.html was importing sencha-touch-debug.js only.
    I have no idea about this error..

    Reply
    • Jorge says

      February 7, 2012 at 7:55 AM

      Check your index.html. Make sure you’re importing all the Sencha Touch and application files you need.

      Reply
  35. Jay Champaneria says

    February 12, 2012 at 4:21 AM

    Jorge.

    What a fantastic tutorial. I get most of it except for using Ext.apply(), I can’t figure it out.

    I work for a large utilities company in the uk and are thinking of using sencha touch. We designing a large and complex UI. This will be a mobile application running on android within the rhomobile framework.

    I would compare the application to the iPad Facebook app, but a little more nested and complex. The application will be based on simple forms and card layouts for wizard processes. Some of the wizards will be data driven.

    I’m very keen on using this framework as it frees the developer to get on with developing ux, my concern is how do I break up the app. I share the concerns about the mvc view controller coupling but I agree with yourself, try and work with the technology. We will have approx. 50 views with several sub menus, toolbars and many panels.

    Any advice would be welcome.

    Keep up the posts…. J

    Reply
  36. Sherrie says

    February 14, 2012 at 1:00 PM

    Hi Jorge,

    Your tutorial was great and I was able to do just what you said and have it working. I am attempting to build my own app but I am afraid I am still confused and lost on this. i was wondering if you could take a look at my image examples located here: justawebbie.freehostingcloud.com/sencha-touch-help.html

    I need to achieve a window at startup that is menu based and takes you to different components. I think I have the photo galleries sorted out just now sure how to link to the startup window.

    If you help me out I would so appreciate it. Thank you for your time and energy.

    Take care,
    Sherrie

    Reply
    • Jorge says

      February 14, 2012 at 8:49 PM

      Thank you, Sherrie. I think you could follow the same approach as the tutorial. One “container” view, with a card for the menu (list), and a card for each of the detail views – list of records, pages of info and photos.

      Reply
  37. renuka says

    February 15, 2012 at 9:11 AM

    Hi,

    I have one question.

    i am little bit confused with Sencha Touch app with different devices. Can anyone tell me what should i need to do for image size and font size based on different device using sencha touch?

    I want to create one native app using Sencha Touch and now wondering about different font size and image size based on different device.

    It will be good if anyone can help me.

    Thanks in advance.

    Reply
  38. Ammar Hussain says

    February 20, 2012 at 5:05 AM

    Sir.
    This is a great post.
    I just want to form login page with username and password in which i want to get username and password from database and authenticate it , i also want to use restful webservices plz post a detailed link.
    i m stuck in this for 10 days ago.
    Plz share as soon as possible.
    Ammar Hussain

    Reply
  39. Andre Duarte says

    February 29, 2012 at 11:47 AM

    Thank you for this tutorial, it’s been quite useful in my Sencha Touch learning process.

    But there’s an issue with this code as well as the non-MVC version:

    If I create two notes, delete them and refresh, the app crashes. I tested it on Chrome and Safari with Sencha Touch 1.1.1.

    JS console on chrome says the problem is at line 19-21 of MainView.js at: “NotesApp.stores.notesStore.load();” with the error: “Uncaught TypeError: Cannot read property ‘id’ of null” .

    Any ideas?

    Thanks in advance.

    Reply
  40. Ingrid Silapan says

    March 5, 2012 at 1:47 AM

    I also encountered the error “Uncaught TypeError: Cannot read property ‘id’ of null” on first run of the application. I searched through different forums and one suggested to check out the localstorage because there might be duplicate ids – which according to him was a bug of Sencha’s. I cleared my cache and the app worked. 🙂

    Reply
  41. Sanu says

    March 5, 2012 at 11:11 AM

    your tutorial helped me a lot.since i am a beginner i am facing a problem.I need to store the datas to mysql database using PHP coding.how could it be done?
    Is JSON conversion required?

    Reply
    • Jorge says

      March 6, 2012 at 10:20 AM

      Sanu, I’m glad the tutorial helped you. You will probably need to decode the JSON sent by the application so you can save the data.

      Reply
  42. mohan says

    March 21, 2012 at 2:48 AM

    Hi Jorge,

    Its really good tutorial for start-up in sencha touch. and also i need to know about the core difference between Sencha touch and PhoneGAP frameworks.

    Reply
  43. Jerome Gaynor says

    April 10, 2012 at 5:36 PM

    Hey Jorge,

    Like everyone said, this tutorial was SO clear. I’ve been struggling with MVC and this was the first time I really got it. Thank you so much for that.

    I was excited after reading the tutorial to download the source and start poking around in it. I always find that the best way to learn something like this is to find a great tutorial with a sample app that you totally understand, and then start breaking it, modifying it, adding to it. But unfortunately, it doesn’t seem to work with Sencha Touch 2.0. I’m so bummed out! Do you have any plans to update it?

    Reply
    • Jorge says

      April 10, 2012 at 8:00 PM

      Thank you Jerome. Please see the Sencha Touch 2 version of the tutorials, How to Create a Sencha Touch 2 App, Part 1. Sencha Touch is all MVC. This tutorial explains what’s different.

      Reply
  44. Torstein Olsen says

    April 11, 2012 at 2:53 AM

    Hi.

    I’m working on an app that works in a similar manner to your example. Great example btw.

    Got a problem that I see that you have ignored.

    On creation of a new note, the delete-button should not be visible.

    Have you got ideas on how to change the layout of the form depending on the state of the data?

    F.ex remove the delete-button for new notes, or change the icon/text?

    Thank you for the article.

    Reply
    • Jorge says

      April 11, 2012 at 7:39 AM

      Thank you. I didn’t see the need to hide the delete button. But, yes, it can be done. You can hide it, or remove it from the toolbar entirely. I think there’s a hide() function that you can use.

      Reply
      • Torstein Olsen says

        April 11, 2012 at 8:05 AM

        Thank you for you prompt reply even though this is an old version.

        I’ll look into it, and implement when I convert the apps to 2.0

        Reply
  45. Narasimha Sanapala says

    May 30, 2012 at 2:57 AM

    Hi Jorge!

    Great tutorial. Any tutorial / example for implementing WCF RESTFul Web service with Sencha Touch then please post the link or example.

    Thanks for you support and help.

    Reply
    • Jorge says

      May 30, 2012 at 7:28 AM

      Thank you. I will try to post a WCF example as soon as possible.

      Reply
  46. Mahmut says

    May 30, 2012 at 4:24 PM

    this tutorial beyond perfect. very thanks.

    Reply
  47. Mangesh says

    September 4, 2012 at 1:21 PM

    Hello Jorge,

    Thanks for this wonderful example. I liked your style of explaining.

    What is the link for your latest book on Sencha Touch.

    Reply
    • Jorge says

      September 4, 2012 at 11:00 PM

      Here’s the link to the Sencha Touch Book: jorgeramon.me/sencha-touch-book/

      Reply
  48. vinoth says

    May 22, 2013 at 5:09 AM

    hi , i am newbie in ST V2.2.0.
    i want new updates for this article . can u help me .

    Reply
  49. Sur007 says

    July 18, 2013 at 4:36 AM

    Hi Jorge,
    i have a condition where i want to limit data.For ex. in a view i only want to post 7 data and next data are to be listed on next view respectively. and in the last page i want show some information. How can i do that?

    Reply
  50. Sruthi says

    April 1, 2014 at 9:14 AM

    hi,

    i am new to senchatouch. i downloaded the sample app(contactList) from github. How to run the senchatouch app…

    Reply

Leave a Comment Cancel reply

Your email address will not be published. Required fields are marked *

Free Mobile User Interface Recipes Kit

Free Mobile User Interface Recipes Kit

Sign up to receive my posts via email and get a FREE Mobile User Interface Recipes Kit with mockups packages for three real-world mobile apps. You will save hours of design time when you use the kit to build your own apps.



I will never share your email address.

Get My Books

The beginner's guide to Sencha Touch apps
The beginner's guide to jQuery Mobile apps

Book: How to Build a jQuery Mobile Application

Topics

  • » jQuery Mobile Tutorials
  • » Sencha Touch Tutorials
  • » ExtJS Tutorials
  • » Books
  • » Tools
  • » .Net Tutorials
  • » BlackBerry Tutorials
  • » iOS Tutorials
  • » Node.js Tutorials
  • » Android Training
  • » BlackBerry Training
  • » iOS Training

Search

Contact Me

  •  Email: jorge[AT]jorgeramon.me
  •  Twitter: @MiamiCoder
  •  LinkedIn: Jorge Ramon


Don’t Miss the Free Updates

Receive free updates in your inbox.
Your address is safe with me.

Copyright © 2018 Jorge Ramon · The opinions expressed herein do not represent the views of my employers in any way · Log in