Book Image

Ext JS 4 Web Application Development Cookbook

By : Andrew Duncan, Stuart Ashworth
Book Image

Ext JS 4 Web Application Development Cookbook

By: Andrew Duncan, Stuart Ashworth

Overview of this book

<p>Ext JS 4 is Sencha’s latest JavaScript framework for developing cross-platform web applications. Built upon web standards, Ext JS provides a comprehensive library of user interface widgets and data manipulation classes to turbo-charge your application’s development. Ext JS 4 builds on Ext JS 3, introducing a number of new widgets and features including the popular MVC architecture, easily customisable themes and plugin-free charting. <br /><br /><em>Ext JS 4 Web Application Development Cookbook</em> works through the framework from the fundamentals to advanced features and application design. More than 130 detailed and practical recipes demonstrate all of the key widgets and features the framework has to offer. With this book, and the Ext JS framework, learn how to develop truly interactive and responsive web applications.<br /><br />Starting with the framework fundamentals, you will work through all of the widgets and features the framework has to offer, finishing with extensive coverage of application design and code structure.<br /><br />Over 110 practical and detailed recipes describe how to create and work with forms, grids, data views, and charts. You will also learn about the best practices for structuring and designing your application and how to deal with storing and manipulating data. The cookbook structure is such that you may read the recipes in any order.<br /><br />The <em>Ext JS 4 Web Application Development Cookbook</em> will provide you with the knowledge to create interactive and responsive web applications, using real life examples.</p>
Table of Contents (19 chapters)
Ext JS 4 Web Application Development Cookbook
Credits
About the Authors
About the Reviewers
www.PacktPub.com
Preface
Index

Accessing components with component query


Ext JS 4 introduces a new helper class called Ext.ComponentQuery , which allows us to get references to Ext JS Components using CSS/XPath style selector syntax. This new class is very powerful and, as you will find out, is leveraged as an integral part of the MVC architecture system.

In this recipe we will demonstrate how to use the Ext.ComponentQuery class to get references to specific components within a simple application. We will also move onto exploring how this query engine is integrated into the Ext.Container class to make finding relative references very easy.

Finally we will look at adding our own custom selector logic to give us fine-grain control over the components that are retrieved.

Getting ready

We will start by creating a simple application, which consists of a simple Ext.panel.Panel with a toolbar, buttons, a form, and a grid. This will form the basis of our examples as it has a number of components that we can query for.

var panel = Ext.create('Ext.panel.Panel', {

    height: 500,
    width: 500,
    renderTo: Ext.getBody(),
    layout: {
        type: 'vbox',
        align: 'stretch'
    },
    items: [{
        xtype: 'tabpanel',
        itemId: 'mainTabPanel',
        flex: 1,
        items: [{
            xtype: 'panel',
            title: 'Users',
            id: 'usersPanel',
            layout: {
                type: 'vbox',
                align: 'stretch'
            },
            tbar: [{
                xtype: 'button',
                text: 'Edit',
                itemId: 'editButton'
            }],
            items: [{
                xtype: 'form',
                border: 0,
                items: [{
                    xtype: 'textfield',
                    fieldLabel: 'Name',
                    allowBlank: false
                }, {
                    xtype: 'textfield',
                    fieldLabel: 'Email',
                    allowBlank: false
                }],
                buttons: [{
                    xtype: 'button',
                    text: 'Save',
                    action: 'saveUser'
                }]
            }, {
                xtype: 'grid',
                flex: 1,
                border: 0,
                columns: [{
                    header: 'Name',
                    dataIndex: 'Name',
                    flex: 1
                }, {
                    header: 'Email',
                    dataIndex: 'Email'
                }],
                store: Ext.create('Ext.data.Store', {
                    fields: ['Name', 'Email'],
                    data: [{
                        Name: 'Joe Bloggs',
                        Email: '[email protected]'
                    }, {
                        Name: 'Jane Doe',
                        Email: '[email protected]'
                    }]
                })
            }]
        }]
    }, {
        xtype: 'component',
        itemId: 'footerComponent',
        html: 'Footer Information',
        extraOptions: {
            option1: 'test',
            option2: 'test'
        },
        height: 40
    }]
});

How to do it...

The main method of the Ext.ComponentQuery class is the query method. As we have mentioned, it accepts a CSS/XPath style selector string and returns an array of Ext.Component (or subclasses of the Ext.Component class) instances that match the specified selector.

  1. Finding components based on xtype: We generally use a component's xtype as the basis for a selector and can retrieve references to every existing component of a xtype by passing it in to the query method. The following snippet will retrieve all Ext.Panel instances:

    var panels = Ext.ComponentQuery.query('panel');
  2. Just like in CSS we can include the concept of nesting by adding a second xtype separated by a space. In the following example, we retrieve all the Ext.Button instances that are descendants of an Ext.Panel instance:

    var buttons = Ext.ComponentQuery.query('panel button');

    Note

    If you have custom classes whose xtypes include characters other than alphanumeric (for example, a dot or hypen) you cannot retrieve them in this way. You must instead query the xtype property of the components using the following syntax:

    var customXtypeComponents = Ext.ComponentQuery.query('[xtype=—My.Custom.Xtype—'];

  3. Retrieving components based on attribute values: Along with retrieving references based on xtype, we can query the properties a component possesses to be more explicit about which components we want. In our sample application we have given the Save button an action property to distinguish it from other buttons. We can select this button by using the following syntax:

    var saveButton = Ext.ComponentQuery.query('button[action="saveUser"]');

    This will return all Ext.Button instances that have an action property with a value of saveUser.

  4. Combining selectors: It is possible to combine multiple selectors into one query in order to collect references to components that satisfy two different conditions. We do this by simply comma separating the selectors. The following code will select all Ext.Button and Ext.form.field.Text component instances:

    var buttonsAndTextfields = Ext.ComponentQuery.query('button, textfield');
  5. Finding components based on ID: A component's id and itemId can be included in a selector by prefixing it with the # symbol. This syntax can be combined with all the others we have seen so far but IDs should be unique and so should not be necessary. The following code snippet will select a component with an ID of usersPanel:

    var usersPanel = Ext.ComponentQuery.query('#usersPanel');
  6. Retrieving components based on attribute presence : One useful feature of the component query engine is that we can select components based on an attribute simply being present, regardless of its value. This can be used when we want to find components that have been configured with specific properties but don't know the values they might have. We can demonstrate this with the following code that will select all Ext.Component that have the property extraOptions .

    var extraOptionsComponents = Ext.ComponentQuery.query('component[extraOptions]');
  7. Using Components' Member Functions: It's also possible to execute a component's member function as a part of the selection criteria. If the function returns a truthy result then that component will be included (assuming the other criteria is met) in the result set. The following code shows this in action and will select all text fields who are direct children of a form and whose isValid method evaluates to true:

    var validField = Ext.ComponentQuery.query('form > textfield{isValid()}');

How it works...

The Ext.ComponentQuery is a singleton class that encapsulates the query logic used in our examples. We have used the query method, which works by parsing each part of the selector and using it in conjunction with the Ext.ComponentManager class. This class is responsible for keeping track of all the existing Ext.Component instances, and is used to find any matching components.

There's more...

There is one other method of the Ext.ComponentQuery class to introduce and a further four methods that are part of the Ext.container.AbstractContainer class.

Evaluating a component instance's type

The component query class allows us to evaluate a component reference we already have to find out if it matches a certain criteria. To do this we use the is method, which accepts a selector identical to the ones that the query method accepts and will return true if it does match. The following code determines if our main Ext.Panel (referenced in the panel variable) has an xtype of panel.

var isPanel = Ext.ComponentQuery.is(panel, 'panel');

Ext.container.AbstractContainer ComponentQuery methods

There are four methods available in the Ext.container.AbstractContainer class (which all container classes extend from; for example panels), which utilizes the component query engine and allow us to query using that component as the root. These methods are query, child, up and down. The query method is identical to the query method available in the Ext.ComponentQuery class but uses the container instance as the root of the query and so will only look for components under it in the hierarchy.

The up and down methods retrieve the first component, at any level, either above or below the current component in the component hierarchy that matches the selector passed in.

Finally, the child method retrieves the first direct child of the current instance that matches the selector.

Using and creating the pseudo-selectors

Pseudo-selectors allow us to filter the retrieved result array based on some criteria that may be too complex to represent in a plain selector. There are two built-in pseudo-selectors: not and last. These can be added to a selector using a colon. The following example shows a selector that will retrieve the last text field.

var lastTextfield = Ext.ComponentQuery.query('textfield:last');

It is very simple for us to create our own custom pseudo-selectors; we will demonstrate how to add a pseudo-selector to retrieve components that are visible.

We start by creating a new function on the Ext.ComponentQuery.pseudos object called visible, which accepts one parameter that will contain the array of matches found so far. We will then add code to loop through each item, checking if it's visible and, if it is, adding it to a new filtered array. We then return this new filtered array.

Ext.ComponentQuery.pseudos.visible = function(items) {
    var result = [];

    for (var i = 0; i < items.length; i++) {

        if (items[i].isVisible()) {
            result.push(items[i]);
        }
    }

    return result;
};

We can now use this in a selector in the same way as we did before. The following query will retrieve all visible components:

var visibleComponents = Ext.ComponentQuery.query('component:visible');

See also

  • The recipes about MVC in Chapter 12, Advanced Ext JS for the Perfect App make use of component queries extensively.