Doing it with Forms

7 min read

(For more resources related to this topic, see here.)

The form component

In order to collect and handle data Ext comes with the Ext.form.Panel class. This class extends from the panel so we can place the form in any other container. We also have all the functionality the panel offers, such as adding a title and using layouts.

If we look at the wireframes, we can see that we need to have the functionality of creating, editing, and deleting clients from our database:

We are going to work on this form. As seen in the previous screenshot the form contains a title, a toolbar with some buttons, and a few fields.

One important thing to keep in mind when working with Ext JS is that we should create our components isolated from the other components as much as we can. This way we can reuse them in other modules or even extend them to add new functionality.

First we need to extend from the Form class, so let’s create a JavaScript file with the following code:

Ext.define('MyApp.view.clients.Form',{ extend : 'Ext.form.Panel', alias : 'widget.clientform', title : 'Client form', initComponent : function(){ var me = this; me.callParent(); } });

We need to create the file in the following path:


The previous code doesn’t do much, it’s only extending from the form panel, defining an alias and a title. The initComponent method is empty, but we’re going to create some components for it.

Now let’s create an HTML file, where we can test our new class. We need to import the Ext JS library, our JS file, where our new class is, and wait for the DOM ready event to create an instance of our class:

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Texfield</title> <!-- Importing the Ext JS library --> <script type="text/javascript" src = "../ext-4.1.1a-gpl/ext-all-dev. js"></script> <linkrel="stylesheet" href="../ext-4.1.1a-gpl/resources/css/ext-all. css" /> <script type="text/javascript" src = "MyApp/view/clients/Form.js"></ script> <script type="text/javascript"> Ext.onReady(function(){ Ext.create('MyApp.view.clients.Form',{ width : 300, height : 200, renderTo: Ext.getBody() }); }); </script> <style type="text/css"> body{padding:10px;} </style> </head> <body> </body> </html>

We are creating an instance of the Client form as usual. We have set the width, height, and the place where the form is going to be rendered, in this case the body of our document. As a result we have our form created as shown in the following screenshot:

So far we have an empty form. We can add any of the available components and widgets, let’s start with the textfield property:

Ext.define('MyApp.view.clients.Form',{ extend : 'Ext.form.Panel', alias : 'widget.clientform', title : 'Client form', bodyPadding : 5, defaultType : 'textfield', //Step 1 initComponent : function(){ var me = this; me.items = me.buildItems(); //Step 2 me.callParent(); }, buildItems : function(){ //Step 3 return [{ fieldLabel : 'Name', name : 'name' },{ fieldLabel : 'Contact', name : 'contact' }]; } });

The steps are explained as follows:

  • Step 1: We have defined the default type of component we are going to use. This way we don’t have to define the xtype property every time we want to create textfield.

  • Step 2: We use the items property to add components to our form. We are calling a function that should return an array of components.

  • Step 3: We are defining two textfields. First we set the value of the label for each textfield and then we set name. It’s important to use name if we want to send or retrieve data to our server. Setting the name property will allow us to set and retrieve data to our fields in an easy way.

Using a function to define the items array is a great way to write our code for readability. Also if we would like to extend this class, we can override this method and add more components to our form in the subclass.

With the previous lines of code we have added two textfields to our form as shown in the following screenshot:

Now let’s add the Address field to our form using a textarea property. In order to do that we need to override the default xtype property as follows:

Ext.define('MyApp.view.clients.Form',{ //... buildItems : function(){ return [ //... ,{ xtype : 'textarea', fieldLabel : 'Address', name : 'address' } ]; } });

If we want to define new components we can override the xtype property with the component we need. In this case we are using a textarea xtype, but we can use any of the available components.

The last field in our wireframe is a textfield to collect the phone number. We already defined the default xtype as textfield so we only need to define the name and the label of our new textfield as follows:

Ext.define('MyApp.view.clients.Form',{ //... buildItems : function(){ return [ //... ,{ fieldLabel : 'Phone', name : 'phone' } ]; } });

As a result we have all the required fields in our form. Now if we refresh our browser, we should see something like the following screenshot:

We have our form ready, but if we see our wireframe we can realize that something is missing. We need to add three buttons to the top of the panel.

We already know how to create toolbars and buttons; the following code should be familiar for us:

Ext.define('MyApp.view.clients.Form',{ //... initComponent : function(){ var me = this; me.items = me.buildItems(); me.dockedItems = me.buildToolbars(); //Step 1 me.callParent(); }, buildItems : function(){ //... }, buildToolbars : function(){ //Step 2 return [{ xtype : 'toolbar', docked : 'top', items : [{ text : 'New', iconCls : 'new-icon' },{ text : 'Save', iconCls : 'save-icon' },{ text : 'Delete', iconCls : 'delete-icon' }] }]; } });

In the previous code, we are defining the dockedItems property; we are using the same pattern of defining a function that returns the array of items in the first step.

In the second step we define a function that returns an array of components to be docked. In this case we are only returning a toolbar docked to the top; this toolbar contains three buttons. The first button is for a new client, the second one is to save the current client, and the third button is to delete the current client in the form.

We need to use CSS classes to add an icon to the buttons. The previous code is using three different classes so we need to create them:

<style type="text/css"> .new-icon{background:transparent url(images/page_add.png) 0 0 norepeat !important;} .save-icon{background:transparent url(images/disk.png) 0 0 no-repeat !important;} .delete-icon{background:transparent url(images/delete.png) 0 0 norepeat !important;} </style>

Once we have defined our CSS classes let’s refresh our browser and see our latest changes in action:

We have finished our wireframe, but the form is not doing anything yet. For now let’s just move forward and see what other components we have available.

Anatomy of the fields

Ext JS provides many components to give the user a great experience when using their applications. The following fields are components we can use in a form or outside of the form, for example, we can add a textfield or a combobox to a toolbar, where we place some filters or search options.

Every input field extends from the Ext.Component class; this means that every field has its own lifecycle, events, and also can be placed on any container.

There’s also a class called Ext.form.field.Base that defines common properties, methods, and events across all form fields. This base class also extends from the Ext. form.Labelable and Ext.form.field.Field classes (using mixins).

The Labelable class gives the field the ability to display a label and errors in every subclass such as textfields, combos, and so on.

The Field class gives the fields the ability to manage their value, because it adds a few important methods, such as the getValue and setValue methods to set and retrieve the current value of the field; also this class introduces an important concept, the raw value.

A great example of the raw value is when we pull data from our server and we get a date value in string format, the raw value is in plain text, but the value of the date field should be in a native Date object so that we can work easily with dates and time. We can always use the raw value, but it’s recommended to use the value instead, which in this example is a Date object.


Please enter your comment!
Please enter your name here