Showing posts with label EXTJs. Show all posts
Showing posts with label EXTJs. Show all posts

Friday, April 25, 2014

Using Sencha Cmd for ExtJs

                 Sencha Cmd is a cross-platform command line tool that provides many automated tasks around the full life-cycle of your applications from generating a new project to deploying an application to production.
—    More info. @ http://docs.sencha.com/extjs/4.2.0/#!/guide/command

Sencha Cmd Installation:
Sencha Cmd is designed for Sencha Ext JS version 4.1.1a or higher and Sencha Touch version 2.1 or higher.
Steps to install Sencha Cmd:
1. Download and install a Java Run-time Environment or JRE. The JRE version must be at least JRE 6.
2. To build themes using Sass on Windows, download and install Ruby
3. Download and install Sencha Cmd.

Using Sencha Cmd:
Creating/generating the  application structure.
  • The following command is used to generate the app. Structure:
        sencha -sdk /path/to/SDK generate app MyApp /path/to/MyApp
  • You can refer the sencha  guide, for the exact structure generated using Sencha  Cmd.
  • All that is required to build your application is to run the following command:
         sencha app build

Custom Builds:
The following steps need to be followed for custom builds:
  • Add the following code in the html file:

    <!--<x-compile>-->
    <!--<x-bootstrap>-->
    <script src="../extjs/ext-dev.js"></script>
    <!--</x-bootstrap>-->
    <script src="app.js"></script>
    <!--</x-compile>-->
  • Create an output file with .html or .js extension. Suppose we create index.js
  • Use the following command to compile/build the all-classes file:
    sencha  compile  -classpath=app.js,../../extjs/src,(other custom utils/components) page -in=../app.html -out=index.js
  • The above command will generate an all-classes.js file, which has to be included in the app.html file. While including the generated all-classes file, remove the above added code and the includes for extjs library (ext-all.js) and app.js
  • Also, to generate the app-classes file as a compressed file using YUI, use the following command:
    sencha  compile  -classpath=app.js,../../extjs/src,(other custom utils/components) page -yui -in=../app.html -out=index.js
  • The ux components can be added to the ux folder in the source and would be referred from there. Incase you define custom components and do not want to add them as ux, you can add them to the classpath




Wednesday, September 18, 2013

CORS throwing error when withCredentials is true

Cross-Origin Resource Shari (CORS) is a W3C spec that allows cross-domain communication from the browser. Almost most of the mobile app's you develop these days need to use CORS for cross-domain access of the web-services. You can find more information on CORS on : http://www.html5rocks.com/en/tutorials/cors/ .

 I had used CORS in many of my projects. To use CORS in EXTJS/Sencha Touch, you can create the request object as:
 var request = {
                                url: uri,
                                timeout: 120000,
                                useDefaultXhrHeader:false,
                                method: 'GET',
                                withCredentials:true,
                                scope:this
}             
Ext.Ajax.request(request);

While Using CORS and web-services together many a times you need to pass credentials or use the withCredentials attribute/config as indicated above.
But, It gave me an error indicating: "Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true." 

Basically, when you are using Cross Domain along with withCredentials set to "true", the server has to respond with:
Access-Control-Allow-Origin: (the origin url) and not with
Access-Control-Allow-Origin:*
WildCards are not allowed in this case.
So this is what I used on the server side:
headers['Access-Control-Allow-Origin'] = this.req.headers.origin;
Hope this helps!!!...

Monday, February 25, 2013

Disabling editing in a property grid

While using a property grid, for some reason you may need to disable the editing of the property grid. You can add a beforeedit listener and return false to achieve this:

new Ext.grid.PropertyGrid({
   ...
   listeners: {
      'beforeedit':{
         fn:function(){
            return false;
         }
      }// end beforeedit
   },//end listeners
   ...
});


Friday, October 19, 2012

Change Chart Axis properties dynamically

The axis properties can be changed dynamically:

Ext.getCmp('chartid').axes.get("gauge").maximum =  100;

However,this will not be applied. 
For it to be applies the chart has to be re-drawn.

Ext.getCmp('chartid').redraw();

Thursday, October 11, 2012

Nested Grids

It's possible to have a grid inside a row of another grid. i.e Nested Grids.
We can use the existing rowExpander plugin and achieve this:

    plugins:[{
            ptype: 'rowexpander',
            expandOnDblClick :false,
            pluginId: 'rowexpanderplugin',
            rowBodyTpl : ['
'
            ],
            }]

When row is expanded we can render the inner/nested grid into the expanded row:

expandbody : function(rowNode,record, expandbody) {
  //destroy the existing grid if the row was expanded before 
  var grid=Ext.getCmp('rowExpander-'+record.get('id')+'-grid');
  if(!Ext.isEmpty(grid)){
    grid.destroy();
  }
 
  var innerGrid=new Ext.grid.Panel({
     id:'rowExpander-'+record.get('id')+'-grid',
     autoDestroy:true,
     renderTo:'rowExpander-'+record.get('id'),
     ...});
      
  profileRunGrid.getEl().swallowEvent(['mouseover', 'mousedown',
  'click','dblclick', 'onRowFocus']);
}
 
 


Tuesday, October 9, 2012

Global exception handling for data requests

In 3.3x there was the option to register 'global' exception handling by adding a listener to the DataProxy:
Ext.data.DataProxy.addListener('exception', function(proxy, type, action, options, res) {
    if (type === 'remote') {
        Ext.Msg.show({
            title: 'REMOTE EXCEPTION',
            msg: res.message,
            icon: Ext.MessageBox.ERROR,
            buttons: Ext.Msg.OK
        });
    }
});  

In EXTJs 4 we can implement it like this:
Ext.override(Ext.data.proxy.Server, {

        constructor: function(config)
        {
            this.callOverridden([config]);

            this.addListener("exception",  function (proxy,
            response, operation) {
                if (response.responseText != null)
                {
                    Ext.Msg.alert('Error', response.responseText);
                }
            });

        }

});
  

Monday, October 8, 2012

Display Menu with no icons

In EXTJs if we create a menu with no icons there still exists a empty place holder for icons.
We can remove this empty css by updating the css:

.no-icon-menu .x-menu-item-icon { display: none; }
You give the class "no-icon-menu" to the whole Menu, and just add the above css.. :)
 

Friday, October 5, 2012

EXTJS Submit Form on Enter Key Press

Mostly there is a requirement to submit the form data when  the user hits the enter key instead of clicking on the submit button. This can be achieved:

EXTJS4:

                            listeners: {
                                afterRender: function(thisForm, options){
                                    this.keyNav = Ext.create('Ext.util.KeyNav', this.el, {
                                        enter: processLogin,
                                        scope: this
                                    });
                                }

EXTJS3:
                        keys: {
                                key: Ext.EventObject.ENTER,
                                fn: processLogin,
                                scope:this
                            }

EXTJS 4 IE specific styles

In EXTJs 3 or earlier version while defining IE specific styles we had to specify the styles as:
ext-ie {
}

Now in EXTJs 4 we need to specify them as
.x-ie .{
}

Same thing applies for other browser specific styles

Friday, August 17, 2012

EXTJs 4 equivalent of getColumnModel()

Extjs 3 has the method grid.getColumnModel() which will return a column model and then yu can dynamically add/remove columns,etc

How do we achive this in EXTJs 4?

Every column can have an itemId. i.e while configuring the columns:
{
header: 'Column1',
dataIndex: 'data',
width: 100,
itemId: 'column1'
}

To get the column with id:column1 we need to use this: 
var column=grid.getView().getHeaderCt().child('#column1');
now we can use the returned column object like:
column.setVisible(false); //to hide the column

Tuesday, August 14, 2012

EXTJs clearing dirty flags for Form Fields

While working on some requirements, there was a need where in for a form when some values were entered, after taking some actions the entered values of the form were now suppose to be treated as the default values and not the changed values. In-short their dirty flags need to be cleared. (When ever we change a form field its dirty flag is set indicating that is has been modified.)

In order to clear the dirty flags of the fields we need to set the trackResetOnLoad=true for the formPanel.
The form Panel does not have such a config and we need to extend it in order to set this field:

        constructor : function(config) {
                config = config || {};
                config.trackResetOnLoad = true;
                this.callParent([config]);
        },


After this wherever we want to clear the dirty flags of the fields, we would need to use:

     //to clear the dirty flag
     var baseForm=this.getForm();
     baseForm.setValues(baseForm.getValues());

:).. Finally solved!!...

EXTJS 4 debugging

While I was using EXTjs 4.1, there were a couple of changes from 4.0.

I realized that in-case we have any logic in the views and we need to debug it, You will try using a break-point in the developer tools. And when you refresh the page to start debugging the break-point is lost. And this continues and then you cannot debug the app. The code in the controller may be by chance debuggable.

After searching a lot I found that we need to disabled the Loader caching. This is how you would do it your app.js


Ext.Loader.setConfig({
enabled: true,
disableCaching: false
});

Now you shall be able to debug and the break points will not be lost.
Huh!!.. hope this helps some one.

Wednesday, December 28, 2011

Sorting store case-insensitively

The following code can be used to sort data in a store alphanumerically and case-insensitively.


Ext.data.Store.prototype.sortData = function(f, direction){
direction = direction || 'ASC';
var st = this.fields.get(f).sortType;
var fn = function(r1, r2) {
    var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
    // ADDED THIS FOR CASE INSENSITIVE SORT
    if (v1.toLowerCase) {
        v1 = v1.toLowerCase();
        v2 = v2.toLowerCase();
    }
    return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
};
this.data.sort(direction, fn);
if (this.snapshot && this.snapshot != this.data) {
    this.snapshot.sort(direction, fn);
}
}

Note, this will cause all the stores to sort case-insensitively since we are overriding the default behavior.

Saturday, December 17, 2011

EXTJS ComboBox validation fails even when validation is turned off

When validationEvent is set to false and validateOnBlur is set to false on a Field (i.e. TextField or Combobox) then there should be no validation.

I found two cases where the Field validates when validation is turned off ...
1) When you use setValue on a TextField
2) When you select value in a combobox

The same can be fixed by overriding the setValue method:

Ext.override( Ext.form.Field, {
setValue : function(v){
this.value = v;
if(this.rendered){
this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
if(this.validationEvent !== false || ((this.validateOnBlur || this.validationEvent === "blur") & this.hasFocus !== true ) ){
this.validate()
}
};
return this;
}
})

Rendering EXTJs components in a Grid Panel

EXTJs provides the EditorGridPanel where, you can have the editors specified and those components will be rendered while editing the record.
But you may want to render some components all the time in he grid columns. I had a similar requirement. This is pretty easy to achieve...
Define a renderer function or the column:
function columnRenderer(value,.......){
var id = Ext.id();

(function() {
new Ext.Button({
renderTo:id,
value:"Hello"
});
).defer(25);

return (String.format('<div id="{0}"></div>',id));

}

Thats it the renderer will create a div with a specific id, and the component will b rendered to that div after the specified time interval.
You can also create the component and render it to a known id in the afterRender method...

Sunday, December 11, 2011

Group Summary for Multi-level Grouping

while trying to get the GroupSummary extension working with the MultiLevel grouping extension, Without any coding changes to Group Summary, the only problem I faced is that, it generated an extra summary row at the end of each outer group. The totals on the extra summary are identical to those of the last inner group summary.
This is the solution for avoiding the extra summary row:
In the MultiGroupingView.js
for doRender function replace the for loop:
for (var k = 0; k < toEnd; k++) {
this.doGroupEnd(buf, g, cs, ds, colCount);
}

with,
for (var k = 0; k < toEnd-1; k++) {
this.doGroupEnd(buf, g, cs, ds, colCount);
}

This will remove the extra summary row.

Ideally this row must calculate the totals of all the sub-groups and display their summary. Will fix the same and post it soon..:)


Thursday, December 1, 2011

Multi-level Grouping

Extjs 3 has support for a first level/single level of grouping.
However, as multi-sort there may be a need to have multi-level grouping.
The following extension at http://jaffa.sourceforge.net/JaffaRIATests/tests/extjs/multigroup/MultiGroup.html has a good implementation of the same.

When I tried using the same in one of my projects, I noticed that the extension does not actually support multi-sort. It has overridden the sort function of the GroupingStore/store which supported multi-sort.
I modified the code to remove the overridaen sort logic from MultiGroupingStore   and it did work. The only function that needs to be overridden was groupBy. Will soon post the code and additional details for the same. Else you can try it yourself and it will be a good exercise to learn... :P..

Another problem with the extension is, the groups do not expand/collapse properly.
The reason for this is it may be the data that is causing it, since if 2 different groups have the same sub-group they might get the same id's which may cause the collapsed group style to work incorrectly.

The fix for this is (Though it may not be that optimized and the only fix..):

1. We will use an additional counter which will help us generate unique id's:
// init counter
 var cn = 0;  // ADD NEW VARIABLE
        for (var i = 0, len = rs.length; i < len; i++) {
            added = 0;
            var rowIndex = startRow + i;
            var r = rs[i];
            var differ = 0;
            var gvalue = [];
            var fieldName;
            var fieldLabel;
            var grpFieldNames = [];
            var grpFieldLabels = [];
            var v;
            var changed = 0;
            var addGroup = [];
     cn = cn + 1; //inc counter
2. Then while generating the group id, we can use it like this: 

gid = gidPrefix + '-gp'+cn+'-' + gp.dataIndex + '-' +
                    Ext.util.Format.htmlEncode(gp.value); 
3. Now, while getting the group/rows the regular 
expression needs to be modified:
   getRowsFromGroup: function(r, gs, lsField){
        var rx = new RegExp(".*-gp.*-"+lsField+"-.*
");
That's it.. Well EXTJS 4 now has a support for Multi-Grouping.