Add searchfield to a sencha touch 2 list MVC

May 17th, 2012

Adding a search field to your sencha touch 2 list is fairly straight forward, there is a good example (list-search) that comes with the sencha touch 2 download. Though to add the searchfield to a list in the MVC style can be a wee bit challenging. Here is a way you can do it! You will need a basic understanding of Sencha Touch 2 and it’s MVC structure.

First we will create a list with the search field. We will place the search field on the bottom toolbar. Like so. (see code below)

Ext.define('App.view.View', {
    extend: 'Ext.List',
    alias:'widget.contactlist',
    fullscreen: true,
    id: 'contactlist',
    config:{
        disableSelection:true,
        store:'Contacts',
        itemTpl:'{first_name} {last_name}',
        items:[{
            xtype:'toolbar',
            docked:'top',
            title:'Contact List'
        },{
            xtype:'toolbar',                                       //  bottom toolbar
            docked:'bottom',
            items:[{
                xtype: 'searchfield',                          //  here is the searchfield
                itemId:'contact_search',
                id:'contact_search',                         //   we will be using this id in the controller
                placeHolder: 'Search Contacts'
            }]
        }]
    }
});

An example Store to populate our list and to use for our search functionality could look as so. (see code below)

Ext.define('App.store.Contacts', {
    extend: 'Ext.data.Store',
    config: {
        model: 'App.model.Contacts',
        autoLoad :true,
        sorters: 'last_name',
        grouper : function(record) {
            return record.get('last_name')[0];
        },

        proxy: {
            type: 'ajax',
            url : 'contacts.json',  //  the json file that holds all our contact info.
            reader: {
                type: 'json',
                rootProperty:'contacts'}
        }
    }
});

An example Model too. (see code below)

Ext.define('App.model.Contacts', {
    extend: 'Ext.data.Model',
    config: {
        fields: [
            {name: 'first_name',  type: 'string'},
            {name: 'last_name',  type: 'string'}
        ]
    }
});

Here is the json that we will be using to populate our list and that we already defined as contacts.json in the Contacts store.(see code below)

{
    "contacts": [
    {
        "first_name": "Brandon",
        "last_name": "Beachy"
    },
    {
        "first_name": "Jair ",
        "last_name": "Jurrjens"
    },{
        "first_name": "Mike",
        "last_name": "Minor"
    }
    ]
}

Then inside your app’s controller we can implement the list-search code that came with the sencha touch 2 download. Take note of this.control() and the functions defined below it. (see code below)

Ext.define('App.controller.Main', {

    extend: 'Ext.app.Controller',
    init: function() {

        this.control({

            '#contact_search':{  //  the id or itemId we gave our searchfield
                scope: this,
                clearicontap: this.onSearchClearIconTap,
                keyup: this.onSearchKeyUp
            }

        });
    },
    onSearchKeyUp: function(field) {
        //get the store and the value of the field
        var value = field.getValue(),
        store = Ext.getCmp('contactlist').getStore();    //  getting the store that drives the contact list

        //first clear any current filters on thes tore
        store.clearFilter();

        //check if a value is set first, as if it isnt we dont have to do anything
        if (value) {
            //the user could have entered spaces, so we must split them so we can loop through them all
            var searches = value.split(' '),
            regexps = [],
            i;

            //loop them all
            for (i = 0; i < searches.length; i++) {
                //if it is nothing, continue
                if (!searches[i]) continue;

                //if found, create a new regular expression which is case insenstive
                regexps.push(new RegExp(searches[i], 'i'));
            }

            //now filter the store by passing a method
            //the passed method will be called for each record in the store
            store.filter(function(record) {
                var matched = [];

                //loop through each of the regular expressions
                for (i = 0; i < regexps.length; i++) {
                              var search = regexps[i],
             didMatch = record.get('first_name').match(search) ||
                                  record.get('last_name').match(search);
                            //if it matched the first or last name, push it into the matches array 

                               matched.push(didMatch);

                         }  //if nothing was found, return false (dont so in the store)               

              if (regexps.length > 1 && matched.indexOf(false) != -1) {
                              return false;
                          } else {
                             //else true true (show in the store)
                             return matched[0];
                            }
            });
        }
    },

    /**
     * Called when the user taps on the clear icon in the search field.
     * It simply removes the filter form the store
     */
    onSearchClearIconTap: function() {
        //call the clearFilter method on the store instance
        Ext.getCmp('contactlist').getStore().clearFilter();
    }

})

Then finally you can tie it all together with your app.js, an example of that could look like this. (see code below)

Ext.application({
     name: 'App',

     controllers: ['Main'],
     stores: ['Contacts'],
     models: ['Contacts'],
     views: ['View'],

      launch: function() {

         Ext.Viewport.add({
             xtype: 'contactlist'
         });

     }
});

Tags: , , , , , ,
Posted in Sencha Touch 2 | View Comments

Developing IBM i Apps for Mobile Devices

September 21st, 2011

Our very own Scott Salisbury had the honor of presenting to OCEAN, A User Group of Southern California, on the nuances of building mobile apps for IBM i. Not sure how long this will be up on their Home page, but here’s the link to OCEAN and the post…details below.

http://www.ocean400.org/

When considering the available technologies needed to bring mobile device solutions to IBM i, developers are faced with a number of questions:

1. What technology choices are available “in the wild” for mobile device programming in general, and what works well with IBM i?
2. Can RPG be used to leverage existing business logic in the mobile arena?
3. What is the learning curve for building these applications?

4. What gotchas or things to consider are lurking when making a commitment to mobile device programming?

Scott Salisbury will explore HTML5 and Javascript technologies now widely in use for mobile device programming and will unpack the above questions and their answers!


About the Speaker:

Scott Salisbury has spent 25 Years as a technology professional working at all levels of the organization, including software development, project management, software/hardware infrastructure management and senior management.   Scott has worked extensively with IBM i, Unix/Linux and Windows environments and has managed a variety of IT-related departments including programming, networking, telecommunications, project management, technical writing, quality assurance and technology audit.

He has spent the past 10 years focused on web-based technologies including software design and development as well as hardware and network infrastructure concepts.As a consultant, Scott has worked with Coca Cola Enterprises, Union Bank of California, Toyota Logistics, and Kenco Logistics. Scott has written several how-to articles over the years in the technology press.  His work can be seen at MCPressOnline.com and systeminetwork.com.

Tags: , , ,
Posted in AS400 | View Comments

Force an ExtJS textfield to uppercase

May 11th, 2011

To style a textfield to uppercase you only need to add a style to the textfield’s config option.
For example;

                   {
                        xtype:'textfield',
                        fieldLabel:'User ID',
                        itemId:'userid',
                        style:'text-transform: uppercase',
                        listeners:{
                            scope:this,
                            specialkey: function(f,e){
                                if(e.getKey()==e.ENTER){
                                    Ext.Msg.alert('','You typed '+
                                        loginForm.getComponent('userid').getValue().toUpperCase());
                                }
                            }
                        }

                    }

In the example above we used ‘text-transform: uppercase’ in the style config to force uppercase. (as shown on line 5)
This takes care of the visual aspect.
When you access the field in your js you still need to use myField.toUpperCase(); (as shown on line 11)

Jr

Posted in Extjs 3 | View Comments

How to process the Enter key with ExtJS

May 5th, 2011

To use the Enter key on your ExtJS forms, you need to setup a listener on your input fields.

For example:

                    {
                        xtype: 'textfield',
                        fieldLabel:'Password',
                        inputType:'password',
                        listeners:{
                            scope:this,
                            specialkey: function(f,e){
                                if(e.getKey()==e.ENTER){
                                    Ext.Msg.alert('Keys','You pressed the Enter key');
                                }
                            }
                        }

                    }

So in the example above, there is a specialkey listener on the password field. If you press Enter while the password field has focus, the specialkey event will fire, your listener will get control and you can then handle the field and/or the form the same way clicking a button would.

Scott

Posted in Extjs 3 | View Comments

Extend Ext Grid Timeout

February 18th, 2010

In my last post, I showed how to extend the timeout for an Ext.Ajax.request({…}); request.

Extending the timeout for other Ext objects is not so simple. For grids needing information from the server, you will have to use a connection object and reference it in the datastore via an HttpProxy Object. Take a look at this connection object.


  var conn = new Ext.data.Connection({
            url: "/myurl.do",
            method: "POST",
            timeout:180000,
            baseParams:{
                cust: "555",
                state: "TN",
                start: 0
            }
        });

Note that we have extended the timeout to 180000 (3 minutes).

This encapsulates everything about the ajax request, including the timeout value. Now that we have this connection object, we can pass it to basically anything and it will be used in place of the defaults and in our case we our interested in extending the 30 second default timeout for an Ext grid. The connection object is useful elsewhere as well.

Here is an example datastore object that can use the connection object:

var myDataStore = new Ext.data.Store({
    proxy: new Ext.data.HttpProxy(conn),
    reader: new Ext.data.JsonReader({
        root: 'myDataArray',
        totalProperty: 'totalCount',
        fields: [
            {
                name: 'field1'
            },
            {
                name: 'field2'
            }
        ]
    })
});

So in this case, this datastore is is wrapped around a JsonReader for the purpose of loading a grid.

The grid would reference the datastore which references the connection.

Scott

Posted in Extjs 3 | View Comments

Extend Ext JS Ajax Timeout

February 18th, 2010

The default timeout for Ext ajax requests is 30 seconds.   Sometimes that is plenty but other times it’s not nearly enough. 

To extend the timeout duration for  Ext.Ajax.request({…..}); you must add the following statement:

  Ext.Ajax.timeout = 90000; // this changes the 30 second default to 90 seconds

Since Ext.Ajax is a singleton, this only needs to be done once at the top of the js file that you want to extend the timeout for.

So once the above line executes, the Ext.Ajax.requests will allow for a 90 second timeout.  The value is in milliseconds so just add 3 zeros to whatever timeout you want the timeout duration to be:

90000 (90 seconds)

180000 (3 minutes)

Ext.onReady(function(){

                // Extend timeout for all Ext.Ajax.requests to 90 seconds.
                // Ext.Ajax is a singleton, this statement will extend the timeout
                // for all subsequent Ext.Ajax calls.
                Ext.Ajax.timeout = 90000;

                Ext.MessageBox.show({
                    title: "Executing Ajax Call",
                    msg: "Timeout has been extended",
                    buttons: Ext.MessageBox.OK,
                    icon: Ext.MessageBox.INFO
                });

                // Make ajax call.  Timeout is now set to 90 seconds.
                Ext.Ajax.request({
                    url: '/myurl.do',
                    params:{
                        action: "getInfo",
                        cust: "555"
                    },
                    success: function(response) {

                        var returnValue = response.responseText;

                        Ext.MessageBox.show({
                            title: "Customer Info",
                            msg: "Here is your customer info " + returnValue,
                            buttons: Ext.MessageBox.OK,
                            icon: Ext.MessageBox.INFO
                        });

                    },
                    failure: function(response) {
                        Ext.MessageBox.show({
                            title: "Ajax Call Failed",
                            msg: "Your timeout was extended but the call still failed.",
                            buttons: Ext.MessageBox.OK,
                            icon: Ext.MessageBox.ERROR
                        });

                    }
                });
            });

Ext.Ajax API

Scott

Posted in Extjs 3 | View Comments