Skip to main content

EXTJS Code Style Guide with examples

EXTJS Style Guide:

-familiar and simple to learn
-fast to develop, easy to debug, painless to deploy
-well-organized, extensible and maintainable

Naming conventions for ExtJS application:

1.Class
Class name should be in CamelCased.
Do not use underscores, hyphens, or any other nonalphanumeric character.
eg: MyCustomClass

Classes that are not distributed by Sencha should never use Ext as the top-level namespace.
Class name should be with atleast one unique namespace separated by dot (.).
eg:TopLevelNamespace.MyClassName

The top-level namespaces and the actual class names should be in CamelCased, everything else should be all lower-cased.
//Good
eg:TopNamespace.midlevelnamespace.MyCustomClass
eg:MyModule.view.UserGrid
//Bad
eg:MyCompany.useful_util.Debug_Toolbar 


2.Use Namespaces to Group Related Components

Namespaces should be based on directory structures. Directories should group components into logical modules based on functional business components. This means an administration component that maintains users would have a namespace and components such as:

Directory structure: 
MyModule/controller/UserController.js
MyModule/store/UserStore.js
MyModule/model/UserModel.js
MyModule/view/UserGrid.js
MyModule/view/UserForm.js

Class Names:
MyModule.controller.UserController
MyModule.store.UserStore
MyModule.model.UserModel
MyModule.view.UserGrid
MyModule.view.UserForm

3. EXTJS Components, Controls 

All Components should start with a 3 letter lower case prefix and then Proper case each word after that. (ex: txtFirstName, cboDisplay, dtmStartDate)

Form Panel = frm
Text Field = txt
Combo Box = cbo
Button = btn
Label = lbl
Check Box = chk
Date Field = dtm
Number Field = num
Grid = grd
Tab Panel = tab
Tab Page = pge
Panel = pnl
Container = con
Toolbar = tlb
Paging Toolbar = pgt

Every Sencha component has an itemId that should be the set to the name of the control. Use camelCase for the itemId names. (ex: txtFirstName)
eg: itemId : txtFirstName

4. Variables, Constants, Private variables, Properties, Methods:

A. Variable should always be in camelCased.
eg:
var isGoodName;
var base64Encoder;
var thisIsMyName;
var base64Encoder

B. Constant variable should be in upper-case
eg:
var SALARY = 1000;
var MAX_COUNT = 10;
    var URL = "http://www.mydomain.net/";

C. Private variable should start with underscore ‘_’
eg: var _modelRecord;
var _get = Ext.data.Model.prototype.get;
    var _set = Ext.data.Model.prototype.set;
    var val = _get.apply(this, arguments); // private variable used in thisway

D. Properties should always be in camelCased. Static properties should bein upper-case.
eg1:
Ext.MessageBox.YES = "Yes";
MyCompany.alien.Math.PI = "4.13";
eg2:
/**@property {String} MASK_MESSAGE_SAVING_FORM Mask message for Saving form*/
    MASK_MESSAGE_SAVING_FORM: 'Saving form data, please wait...',

E. Methods:
Method should always be in camelCased. This also applies to acronyms.
eg: 
Acceptable method names:
encodeUsingMd5()
getExtComponentByReference()
getHtml() instead of getHTML()
getJsonResponse() instead of getJSONResponse()
parseXmlContent() instead of parseXMLContent()


5. Common Base Classes with documentation comments
A component that is used as a common ancestor for other components should be placed in a "common" directory. 
eg:
/**
 * @class Common.CommonFunctions  
 * @author Sencha User
 *  
 * This file contains common functionailty that can be useful in
 * any ExtJS application.
 * 
 */
Ext.define('Common.CommonFunctions', {});


6. Method with documentation comments
eg:
/**
 * This will return an ExtJs component based on a reference
 * to that component.  This reference can either be the component
 * itself or the comopnent's id. 
 * @param {String/Object} ref A reference to an ExtJs component, can either be the the components id or the component itself
 * @return {Object}
 */
function getExtComponentByReference(ref){
var component;
if (typeof ref === 'string'){
component = Ext.getCmp(ref);
} else if (typeof ref === 'object'){
component = ref;
} else {
return false;
}
return component;
}

7. Controller Method with documentation comments 
eg:
    /**
     * Function to provide logic to validate a BPM form prior to submitting it.
     * Override this method in your own custom controller to add form specific submit validation.
     * Note:  By default this function will simply call form.isValid() to determine if form is valid.
     * 
     * @returns {boolean} If the form is valid for submit or not
     */
    isBPMFormValidForSubmit: function(){
    return this.getBpmForm().isValid();
    },


8. Global References:
 // Note: Specify where they are used
 var globalPreferedMode = false;
 var globalUserPreferenceArr = [];  // Array used to compare with preference cols of trade grid while applying preferences
 
    
9. Documentation Comments for any user defined config { } at component, controller level 
eg:
/**
* @cfg {Number} headerColumns
* The total number of columns to create in the table for this layout. If not specified, all Components added 
* to this layout will be rendered into a single row using one column per Component. 
*/
headerColumns: 6,

/**
* @cfg {Object/Object[]} headerFields
* A single item, or an array of child Components to be added to this container.
*/
headerFields: [],

/** @readonly */
    isWindow: true,

   /** @cfg {String} title The default window's title */
    title: 'Title Here',

   /** @cfg {Object} bottomBar The default config for the bottom bar */
    bottomBar: {
        enabled: true,
        height: 50,
        resizable: false
    },

/**
* @cfg {String} store (required)
* The key of the store to be used to back this form.
*/ 
store: ''

10. Best Practice : use scope
eg:

getPeople :function(people){
Ext.Ajax.request({
    url: 'people.php',
    method : 'GET',
    params: {
        id: 1,
        name:'test'
    },
    scope: this,
    success: this.onAfterGetPeople
});
},

onAfterGetPeople:  function(response){
        //Dp some stuff
        var jsonData = Ext.decode(response.responseText);
        // process server response here
        this.getDepartments(jsonData,departments);
},
getDepartments : function(departments){
Ext.Ajax.request({
   url: 'departments.php',
   method : 'GET',
   params: departments,
   scope: this,
   success: this.onAfterGetDepartments
});
},
onAfterGetDepartments : function(response){
//DO more work
}


11. Best Practice : Properly indented & optimized code
eg:
segmentContactModule :function(segButton,button,pressed){

var contactListStore = Ext.getStore('ContactListStore').
contactView      = this.getContactView(),
contactList      = contactView.query('#listContactItemsId')[0],
contactDetailView= this.getContactDetailView(),
selectedRecords  = contactList.getSelection(),
buttonText = button.getText();

contactListStore.clearFilter();

if(pressed) {
if(contactListStore.getCount() == 0){
 contactDetailVIew.setActiveItem(0);
}else{

if(selectedRecords.length>0){
this.contactListItemEvent(null,null,null,selectedRecords[0]);
}else{
contactDetailView.setActiveItem(0);
}
}
}
else{
if(selectedRecords.lenght>0){
this.contactListItemEvent(null,null,null,selectedRecords[0]);
}
}
} // end of method


12. Best Practice: Always code for readability

eg:
if(!this.isReadable()){
this.refactorWith({
properIndentation : true,
optimizedCodeReadability: true

});
}else{
this.beHappy();
}


13. Best Practice: Return type of method
eg:
testSomeVal : function(someVal){
return (someVal <=2); //add braces for readability
}

14. Best Practice: 
Lazy initialization - add items/views only when necessary
Lazy rendering - save browser some time
Reuse things - save developer time

15. Best Practice : Two rules for "this"
When a function is executed via a var reference, the default execution context("this") is "window".
eg:
var myFn = function(){
console.log(this);
};
myFn();

When a function is  executed via a object key, the execution context("this") is "object".
eg:
var member = {
name: 'Eric',
   getName: function(){
console.log(this);    
}
};
member.getName();

Mixing:
eg:
var getName = member.getName;
getName();

eg:
var member1 = {
name: 'Eric',
   getName: function(){
console.log(this);    
}
};
var member2 = {
name: 'Bob',
   getName: member1.getName
};
member2.getName();


Comments

Post a Comment

Popular posts from this blog

ExtJS - Grid panel features

What can we do with ExtJS GridPanel? I have to develop a lot of applications in my web app and I see that grid component of ExtJS may fit in. However, I am not aware of what all things I can do with the - off the shelf available framework pieces - available plug-ins in the marketplace and - custom development through my own developers This is a typical question that we hear from the business users who wants to design an application by keeping the framework’s capability in perspective. In this article I have tried to put the list of stuff you can do with grid and hopefully that shall enable you to take advantage of the beauty of ExtJS. Pre-requisites This article assumes that you are familiar with basics of ExtJS What are the available options? In this section I will be taking you through some of the commonly seen usage of ExtJS grid panel. While covering all the capabilities of grid may not be possible, I am sure it will be helpful for the business users who want to

Ext4 Apply Store Filtering

In extjs4.1: There are many way for store filtering . Some of code i give here Filtering by single field: store . filter ( 'eyeColor' , 'Brown' );   Alternatively, if filters are configured with an  id , then existing filters store may be  replaced by new filters having the same  id . Filtering by single field: store . filter ( "email" , /\.com$/ );   Using multiple filters: store . filter ([ { property : "email" , value : /\.com$/ }, { filterFn : function ( item ) { return item . get ( "age" ) > 10 ; }} ]);   Using  Ext.util.Filter  instances instead of config objects (note that we need to specify the root config option in this case): store . filter ([ Ext . create ( ' Ext.util.Filter ' , {   property : "email" , value : /\.com$/ , root : 'data' }),   Ext . create ( ' Ext.util.Filter ' , {   filterFn : function ( item ) {   return item . get ( &

EXT JS 4: EMPTY VALUE IN A COMBOBOX

EXT JS 4: EMPTY VALUE IN A COMBOBOX Often, in an Ext JS combobox, it is difficult to go back to an empty value once you have selected an item, particularly if “forceSelection” is set to true.  Here is my roundup of alternative solutions found from around the web… 1. Override beforeBlur The solution from   http://www.sencha.com/forum/showthread.php?182119-How-To-Re-Empty-ComboBox-when-forceSelection-is-Set-To-TRUE  overrides beforeBlur on the combbox to clear out lastSelection.  Here is a copy of the override from the thread: 1 2 3 4 5 6 7 8 9 10 11 12 13 Ext.create( 'Ext.form.field.ComboBox' , {      ...      allowBlank: true ,      forceSelection: true ,      beforeBlur: function (){          var value = this .getRawValue();          if (value == '' ){              this .lastSelection = [];          }          this .doQueryTask.cancel();         this .assertValue();      } }); Or to apply the o