Writing a Sencha Touch MVC Application

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: '</pre>
<div style="margin: <span class=;">5px;">No notes cached.</div>
<pre>
<pre>',
            onItemDisclosure: true,
itemTpl: '
<div class="list-item-title">{title}</div>
<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.

Comments

  1. Ted says

    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!!

    • says

      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.

      • Don says

        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.

        • Brad Swardson says

          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.

  2. urchin says

    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!

  3. Rando says

    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.

  4. Nilesh Chavan says

    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

  5. says

    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

  6. Xilon says

    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!

  7. pablo says

    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.

  8. Kurt says

    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!

  9. Xilon says

    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!

    • says

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

      • John Uri says

        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

      • Xilon says

        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!

  10. max says

    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 ???

  11. max says

    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 :(

  12. josh says

    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

  13. says

    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 )

  14. max says

    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?

  15. IDDQD says

    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”

    • says

      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.

  16. IDDQD says

    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();”

  17. Xilon says

    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

  18. dcoder405 says

    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

    • says

      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.

  19. bagusflyer says

    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

    • says

      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.

  20. sam says

    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????

  21. Haritha says

    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’

    • says

      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.

  22. AK says

    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

  23. John says

    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

    • says

      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.

  24. Brad Swardson says

    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!

  25. says

    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!

  26. says

    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!

  27. prabu says

    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..

  28. Jay Champaneria says

    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

  29. says

    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: http://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

    • says

      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.

  30. renuka says

    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.

  31. Ammar Hussain says

    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

  32. Andre Duarte says

    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.

  33. Ingrid Silapan says

    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. :)

  34. Sanu says

    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?

    • says

      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.

  35. mohan says

    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.

  36. Jerome Gaynor says

    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?

  37. Torstein Olsen says

    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.

    • says

      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.

      • Torstein Olsen says

        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

  38. Narasimha Sanapala says

    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.

  39. Mangesh says

    Hello Jorge,

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

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

  40. Sur007 says

    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?

  41. Sruthi says

    hi,

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

Leave a Comment

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