Showing posts with label extjs. Show all posts
Showing posts with label extjs. Show all posts

Monday, February 18, 2013

Removing Sencha Eclipse plugin license file from my linux platform


I am using spket eclipse plugin for editing ExtJS code. But, I tried Sencha Eclipse plugin before. I need to delete some directories and files if I want to completely remove Sencha Eclipse plugin.

For example, I need to remove its license file as below,

rm $HOME/.local/share/Sencha/.ftp


Btw, I am listing two books about ExtJS 4.x here. I am happy to serve as technical reviewer for these two books. They will save your time that costs more money than these books.

Friday, February 10, 2012

Spring singleton and singleton design pattern vs Ext JS 4 singleton and JavaScript Singleton

I discussed "Implementing Singleton object in JavaScript" and "Implementing Singleton pattern in Java and PHP shows different "static" modifers between Java and PHP". Today, I am going to compare the similarity between difference between Java Singleton pattern and Spring singleton and difference between Javascript singleton pattern and Ext JS 4 singleton object.

As described in Spring document, Spring's concept of a singleton bean is different from the Singleton patter, which could be called GoF (Gang of Four) Singleton. As discussed in my post "Java Class loader and static variable and JVM memory management", the GoF Singleton implements one and only one instance of a particular class will ever be created per ClassLoader. Meanwhile, the singleton object defined in Spring framework is single/unique object managed in Spring container. So, Spring singleton needs to be carefully used in multithread environment. Normally, we should use Spring prototype instead of singleton as service that will be requested by multi threads.

Now let's look at Ext JS 4 singleton. I will say it has similar implementation as Spring singleton. That is, Ext JS 4 develops a container to hold all Ext JS 4 class/object. JavaScript's multi-task programming is not popular yet. However, how about testing this through two tab in same browser?

This discussion reveals how Ext JS 4 implements singleton. It is pretty similar as the way Spring does. In Ext JS 4, a singleton is an object instead a class. It's not the same with GoF Singleton just like Spring singleton is not same with GoF Singleton. I think this is an interesting investigation.

http://stackoverflow.com/questions/3920689/plain-old-singleton-or-spring-singleton-bean http://www.bleext.com/blog/configurations-statics-and-singleton-in-ext-js-4/ http://www.sencha.com/forum/showthread.php?128646-Singleton-vs-class-with-all-static-members

Thursday, October 6, 2011

Ext JS 4 reCAPTCHA widget

After password strength meter widget, I am asked to give a Captcha verify widget too. Well, it is not so difficult, below is a ReCaptcha widget for Ext JS 4.x. On ExtJS 2.x forum, there are detailed description about how to apply for ReCaptcha account.


Source code:

//define a reCaptcha widget.
Ext.define('yiyu.util.ReCaptcha', 
 { 
 extend : 'Ext.Component',
  alias : 'widget.recaptcha',
    

    onRender : function(ct, position){
     var me = this;
     me.callParent(arguments);
     
     me.recaptcha = me.el.createChild({
   tag : "div",
   'id' : me.recaptchaId
  });
     
     Recaptcha.create(me.publickey, me.recaptcha.id, {
            theme: me.theme,
            lang: me.lang,
            callback: Recaptcha.focus_response_field
     });
     
     //me.recaptcha.setWidth(me.el.getWidth(true));
        
    },
    
    getChallenge: function(){
     return Recaptcha.get_challenge();
    }, 
    
    getResponse: function(){
     return Recaptcha.get_response();
    }

});

//create a ReCaptcha instance and we can use it as item in Form.
var recaptcha = Ext.create('yiyu.util.ReCaptcha',{
  name: 'recaptcha',
        recaptchaId: 'recaptcha',
        publickey: 'Your public Key from ReCaptcha',
        theme: 'white',
        lang: 'en'
 });

Sunday, September 18, 2011

Ext JS 4 password strength meter

One of my friends wants me to help him on putting a password strength meter on his registration page. Inspired by a post on Ext JS 1.x forum, I created a Ext JS 4 compatible one as shown below,


To do this, what you need is 1) the following Ext JS widget extends from Ext.form.field.Text. 2) do not forget the CSS file and images used in CSS. To change the appearance of password meter, you can simply change images used in CSS.

JavaScript code:
Ext.define('yiyu.util.PasswordMeter',
    {
     extend : 'Ext.form.field.Text',
     alias : 'widget.passwordMeter',
     inputType : 'password',

     reset : function() {
      this.callParent();
      this.updateMeter(this);
     },
     
     //private
     onRender : function(container, position) {
      var me = this;
      me.callParent(arguments);
      this.objMeter = me.el.createChild({
       tag : "div",
       'class' : "strengthMeter"
      });
      me.objMeter.setWidth(me.el.getWidth(true) - 17);
      me.scoreBar = me.objMeter.createChild({
       tag : "div",
       'class' : "scoreBar"
      });
      me.scoreBar.setWidth(me.objMeter.getWidth(true));

      if (Ext.isIE6) { // Fix style for IE6
       this.objMeter.setStyle('margin-left', '3px');
      }
     },

     // private
     initEvents : function() {
      var me = this, el = me.inputEl;
      me.callParent();
      me.mon(el, {
       scope : me,
       keyup : me.updateMeter
      });
     },
     /**
      * Sets the width of the meter, based on the score
      * 
      * @param {Object} e
      * Private function 
      */
     updateMeter : function() {
      var score, p, maxWidth, nScore, scoreWidth;
      score = 0;
      p = this.getValue();
      
      maxWidth = this.objMeter.getWidth() - 2;

      nScore = this.calcStrength(p);

      scoreWidth = maxWidth - (maxWidth / 100) * nScore;
      
      this.scoreBar.setWidth(scoreWidth, true);
     },

     /**
      * Calculates the strength of a password
      * 
      * @param {Object} p
      *   The password that needs to be calculated
      * @return {int} intScore The strength score of the password
      */
     calcStrength : function(p) {
      var intScore = 0;

      // PASSWORD LENGTH
      intScore += p.length;

      if (p.length > 0 && p.length <= 4) { // length 4 or
                // less
       intScore += p.length;
      } else if (p.length >= 5 && p.length <= 7) { 
       // length between 5 and 7
       intScore += 6;
      } else if (p.length >= 8 && p.length <= 15) { 
       // length between 8 and 15
       intScore += 12;       
      } else if (p.length >= 16) { // length 16 or more
       intScore += 18;       
      }

      // LETTERS (Not exactly implemented as dictacted above
      // because of my limited understanding of Regex)
      if (p.match(/[a-z]/)) { 
       // [verified] at least one lower case letter
       intScore += 1;
      }
      if (p.match(/[A-Z]/)) { // [verified] at least one upper
            // case letter
       intScore += 5;
      }
      // NUMBERS
      if (p.match(/\d/)) { // [verified] at least one
            // number
       intScore += 5;
      }
      if (p.match(new RegExp(".*\\d.*\\d.*\\d"))) {
       // [verified] at least three numbers
       intScore += 5;
      }

      // SPECIAL CHAR
      if (p.match(new RegExp("[!,@,#,$,%,^,&,*,?,_,~]"))) {
       // [verified] at least one special character
       intScore += 5;
      }
      // [verified] at least two special characters
      if (p.match(new RegExp(
          ".*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~]"
        ))) {
       intScore += 5;
      }

      // COMBOS
      if (p.match(new RegExp("(?=.*[a-z])(?=.*[A-Z])"))) {
       // [verified] both upper and lower case
       intScore += 2;
      }
      if (p.match(new RegExp(
        "(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])"))) {
       // [verified] both letters and numbers
       intScore += 2;
      }
      // [verified] letters, numbers, and special characters
      if (p
        .match(new RegExp(
          "(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!,@,#,$,%,^,&,*,?,_,~])"
          ))) {
       intScore += 2;
      }

      var nRound = Math.round(intScore * 2);

      if (nRound > 100) {
       nRound = 100;
      }

      return nRound;
     }
    })


CSS code:
.strengthMeter {
 border: 1px solid #B5B8C8;
 margin: 3px 0 3px 0;
 background-image: url(images/meter.gif);
 height: 10px;
 background-size: 100%; 
}

.scoreBar {
 background-image: url(images/meter_background.gif);
 height: 10px;
 background-size: 100%; 
 line-height: 1px;
 font-size: 1px;
 float: right;
}


Edit: Here is a better implementation crated by osnoek.

Thursday, July 28, 2011

how Ext JS 4 deals with postprocessors and preprocessors?

I looked into source code of Ext.ClassManager recently. But, I found that I can not understand it. Actually, I think it is a bug?

According to the signature of Ext.ClassManager.create function, It seems that developer can pass in postprocessors in configuration data. However, I think the postprocessors in configuration data will overwrite ClassManager's default postProcessors.

I put sample code to show what happen once we apply "||" operator to two JavaScript arrays. I cited the source code as below and add several lines comments there. Similar things happen to preprocessors in Class.js .

code snippet to show || operator on JavaScript arrays

The output of above code is:
Array is:
0
1
Another array is:
2
3
4
Now, let's see what happens in ClassManager.js: Code snippet cited from ClassManager.js
return new Class(data, function() {
                //If I pass in data having postprocessors,
                //all default postprocessors is going to ignored? 
                var postprocessorStack = data.postprocessors || manager.defaultPostprocessors,
                    registeredPostprocessors = manager.postprocessors,
                    index = 0,
                    postprocessors = [],
                    postprocessor, postprocessors, process, i, ln;

                delete data.postprocessors;

                //if my data has just one postprocessor, 
                //doesn't postprocessorStack.length only equal to 1?  
                for (i = 0, ln = postprocessorStack.length; i < ln; i++) {
                    postprocessor = postprocessorStack[i];

                    if (typeof postprocessor === 'string') {
                        postprocessor = registeredPostprocessors[postprocessor];

                        if (!postprocessor.always) {
                            if (data[postprocessor.name] !== undefined) {
                                postprocessors.push(postprocessor.fn);
                            }
                        }
                        else {
                            postprocessors.push(postprocessor.fn);
                        }
                    }
                    else {
                        postprocessors.push(postprocessor);
                    }
                }

                process = function(clsName, cls, clsData) {
                    postprocessor = postprocessors[index++];

                    if (!postprocessor) {
                        manager.set(className, cls);

                        Ext.Loader.historyPush(className);

                        if (createdFn) {
                            createdFn.call(cls, cls);
                        }

                        return;
                    }

                    if (postprocessor.call(this, clsName, cls, clsData, process) !== false) {
                        process.apply(this, arguments);
                    }
                };

                process.call(manager, className, this, data);
            }

I reported a bug here to see if I am right or it is just because I do not understand the code. Please feel free to make comments below if I am wrong.

Friday, July 1, 2011

ExtJS 4 REST proxy and Zend framework Zend_Rest_Route are incompatible.

I noticed a very strange thing when I worked on Ext JS 4 v4.0.2 and Zend Framework. I find that every time when Ext JS grid sends new created Record to the server through its REST proxy, the POST method was teated as PUT method in Zend_Rest_Route. This cause troublesome because my code have to know if the incoming record a new one for insert or exsiting one for update. Otherwise, I have to use some UPSERT SQL statement to UPDATE or INSERT record into Database table. Unfortunately, I use DB2 for i5/OS V5R4, which does not have built-in UPSERT command and it even does nor support MERGE statement.

I do not want to walkaround this by doing SELECT first and judging if the code need to run INSERT or UPDATE statement. So, I traced the Ext JS 4 code and Zend Framework 1.11 code. I found that these two are not compatiable. I am not sure if we can say it is BUG as this wont happen if either side change their code. Or, both side can change the code to avoid the confilicaton if we say bugs are from both sides.

The key for this issue is that Ext JS 4 append record's id at the end of base URL, which points to RESTful service. Below is a psuedo POST URL create by Ext JS 4 REST proxy. I highlight the unexpected friend in red color.

http://hostname/yourRestServiceURI/yourRecordId/?dc=randomNum


We understand that adding record id as part of URI can allow server side script easily find it. But, why this design is implemented in a general SDK like Ext JS? Especially, I do not see good reason for a POST request to have it as record in POST are suppoe not to have been existing on server side. Therefore, the ID of the new record might not have been generated if it will be generated on the server side only.

In Ext JS 4 source code \src\data\proxyRest.js, we can see what happens,
/**
     * Specialized version of buildUrl that incorporates the {@link #appendId} and {@link #format} options into the
     * generated url. Override this to provide further customizations, but remember to call the superclass buildUrl
     * so that additional parameters like the cache buster string are appended
     */
    buildUrl: function(request) {
        var me        = this,
            operation = request.operation,
            records   = operation.records || [],
            record    = records[0],
            format    = me.format,
            url       = me.getUrl(request),
            id        = record ? record.getId() : operation.id;
        
        if (me.appendId && id) {
            if (!url.match(/\/$/)) {
                url += '/';
            }
            
            url += id; //Why add ID here even for POST? Yiyu Jia
        }
        
        if (format) {
            if (!url.match(/\.$/)) {
                url += '.';
            }
            
            url += format;
        }
        
        request.url = url;
        
        return me.callParent(arguments);
    }
}

Now, people will ask why adding id in URL cause the problem in Zend Framework? Well, let's trace Zend Framework code now.

On Zend Framework API document about Zend_Rest_Route, we can see Zend clearly described their design how RESTful URI should looks like,
Zend_Rest_Route Behavior
MethodURIModule_Controller::action
GET/product/ratings/Product_RatingsController::indexAction()
GET/product/ratings/:idProduct_RatingsController::getAction()
POST/product/ratingsProduct_RatingsController::postAction()
PUT/product/ratings/:idProduct_RatingsController::putAction()
DELETE/product/ratings/:idProduct_RatingsController::deleteAction()
POST/product/ratings/:id?_method=PUTProduct_RatingsController::putAction()
POST/product/ratings/:id?_method=DELETEProduct_RatingsController::deleteAction()

As we can see, Zend Framework does not expect any thing attached to method URI when PHP programmer intend to use POST method. In Zend_Rest_Route source code, we can see a case switch statement as below. You will see when the POST method will be "magically" routed to PUT method if pathElementCount is larger than zero.

switch( $values[$this->_actionKey] ){
                    case 'post':
                        if ($pathElementCount > 0) {
                            $values[$this->_actionKey] = 'put';
                        } else {
                            $values[$this->_actionKey] = 'post';
                        }
                        break;
                    case 'put':
                        $values[$this->_actionKey] = 'put';
                        break;
                }


But, where is the $pathElementCount set? In the same source code file, we can see below statement,

//Store path count for method mapping
$pathElementCount = count($path);

So, where is value of $path populated? Still, in the same source code, there is a function call match. Part of it is cited as below.

/**
     * Matches a user submitted request. Assigns and returns an array of variables
     * on a successful match.
     *
     * If a request object is registered, it uses its setModuleName(),
     * setControllerName(), and setActionName() accessors to set those values.
     * Always returns the values as an array.
     *
     * @param Zend_Controller_Request_Http $request Request used to match against this routing ruleset
     * @return array An array of assigned values or a false on a mismatch
     */
    public function match($request, $partial = false)
    {
        if (!$request instanceof Zend_Controller_Request_Http) {
            $request = $this->_front->getRequest();
        }
        $this->_request = $request;
        $this->_setRequestKeys();

        $path   = $request->getPathInfo();
        $params = $request->getParams();
        $values = array();
        $path   = trim($path, self::URI_DELIMITER);

Ok, now, it is not the end of code tracing yet. Where is the getPathInfo() function? It is in Zend_Controller_Request_Http. The following code citation will show us that getPathInfo() eeturns everything between the BaseUrl and QueryString and deos something special.

/**
     * Returns everything between the BaseUrl and QueryString.
     * This value is calculated instead of reading PATH_INFO
     * directly from $_SERVER due to cross-platform differences.
     *
     * @return string
     */
    public function getPathInfo()
    {
        if (empty($this->_pathInfo)) {
            $this->setPathInfo();
        }

        return $this->_pathInfo;
    }

/**
     * Set the PATH_INFO string
     *
     * @param string|null $pathInfo
     * @return Zend_Controller_Request_Http
     */
    public function setPathInfo($pathInfo = null)
    {
        if ($pathInfo === null) {
            $baseUrl = $this->getBaseUrl(); // this actually calls setBaseUrl() & setRequestUri()
            $baseUrlRaw = $this->getBaseUrl(false);
            $baseUrlEncoded = urlencode($baseUrlRaw);
        
            if (null === ($requestUri = $this->getRequestUri())) {
                return $this;
            }
        
            // Remove the query string from REQUEST_URI
            if ($pos = strpos($requestUri, '?')) {
                $requestUri = substr($requestUri, 0, $pos);
            }
            
            if (!empty($baseUrl) || !empty($baseUrlRaw)) {
                if (strpos($requestUri, $baseUrl) === 0) {
                    $pathInfo = substr($requestUri, strlen($baseUrl));
                } elseif (strpos($requestUri, $baseUrlRaw) === 0) {
                    $pathInfo = substr($requestUri, strlen($baseUrlRaw));
                } elseif (strpos($requestUri, $baseUrlEncoded) === 0) {
                    $pathInfo = substr($requestUri, strlen($baseUrlEncoded));
                } else {
                    $pathInfo = $requestUri;
                }
            } else {
                $pathInfo = $requestUri;
            }
        
        }

        $this->_pathInfo = (string) $pathInfo;
        return $this;
    }

So, what is the conclusion? The conclusion is that both Ext JS and Zend framework has their own design of RESTful URI pattern. Unfortunately, they are not compatible with each other. They are too nice to do more than developer expected. As libraries vendor, they maybe should do less sometimes in order to make their library as general as possible. Ext JS, as a pure client side JavaScript library, should not guide server side script designer how to implement RESTful Web service. Zend Framework, as a pure server side script library, should not make design for client side application either. In fact, RESTful Web service is a set of guide lines for developer to make scalable application over HTTP methods. But, it does not define how the URI pattern must be.

Thursday, June 23, 2011

Managing Grid CRUD In ExtJS 4

I read a discussion on Sencha forum (here). Obviously, ExtJS 4 make user to be frustrating because of the lack of well organized document and lack of well commented sample code. Probably, it is just because ExtJS 4 is too new that developers have not catch up. However, since ExtJS is partially commercial product instead of a pure open source project, its quality should be well controlled before it announce final release. Here is a little bit experiece on how to make a CRUD grid with ExtJS 4.

To successfully use Grid, auto sync store, and rowediting plugin in ExtJS 4, there are several points need to be highlighted. I listed them as below,


  1. In your Model class, you have to either define a hardcoded 'id' property or use 'idProperty' to specify one column as 'id'.
  2. You server side code need to return processed records back to browser. I tried only send back "id" in "data" part. But, it is not successful.
  3. Be aware that the format of record in the "data" has JSON format.
  4. Be sure to implemented at least one Validator in your Model class because, in ExtJS source code AbstractStore.js, you can find the following code, which may always return true for a new created record in RowEditing plugin when the store is set as autoSync = true

/**
     * @private
     * Filter function for new records.
     */
    filterNew: function(item) {
        // only want phantom records that are valid
        return item.phantom === true && item.isValid();
    },

Most likely, we wont use auto sync store in real product. But, this example could be a good start.

Saturday, May 28, 2011

Using dynamic class loading feature in ExtJS 4

ExtJS 4 introduces a new feature about dynamical class loading. It is not recommended in a product environment. However, it will be very useful when you want to debug your application. Especially, it is extremely helpful when you have to debug into source code of ExtJS 4 as it is still buggy now. Here is a template that I use in my project.

First of all, in HTML HEADER, I include ExtJS file ext-dev.js instead of ext-all-debug.js . And, ext-dev.js is the only JavaScript file I need to included there.

Then, in the first page of ExtJS app, I have code like below,



Sunday, April 24, 2011

Using Abstract class and Interface in ExtJS 4.x programming.

I was driven to think about how to implement Interface and Abstract class when I review a project using Ext JS as front GUI library. It is good to see they try to do OOP and design the GUI component as reusable.

However, I saw that there was no clear idea about Interface and Abstract class design in the code. I say this because I saw some empty function in parent classes. Obviously, the programmer of parent classes wish subclass programmer to implement those empty functions. But, I did not see any code there to force subclass programmer to implement the function. The way to solve this is very simple, we only need to add a throw statement in parent class.

Ext.define('jia.blog.ParentClass', {
    greeting : function(){
                  throw "Unimplemented method.";
               }
}

Ext.define('jia.blog.ChildClass', {
    extend: 'jia.blog.ParentClass',

    greeting : function(){
                  alert('I implemented a abstract method');
               }
}

About using Interface in Ext JS, I think the new feature mixins introduced in Ext JS 4.0 can be good candidate as it is invented to solve multiple inherent. In Java, we know that one class can only extends from one and only one parent class. But, it can implement multiple Interfaces. So, for my opinion, I will declare my interface as mixins as below,

//a mixins class to be used as Interface
Ext.define('jia.blog.TechnicalManager', {
    level : 'manager',
    meetingWithPM : function() {
        throw "unimplemented method";
    }
});

//a mixins class to be used as Interface
Ext.define('jia.blog.Mother', {
    sex : 'female',
    feedChild : function() {
        throw "unimplemented method";
    }
});

Ext.define('jia.blog.WorkingMom', {
    
    mixins: {
        inWork: 'jia.blog.TechnicalManager',
        atHome: 'jia.blog.Mother'
    }

    meetingWithPM : function() {
        alert('I am meeting with project manager');
    }

    feedChild : function() {
        alert('I am feeding my kids');
    }

});


Of course, you can put "abstract" method in mixins too. I did not do it here just because I want to show how I use mixins as Interface in OOP manner. Actually, Javascript has no class at all. Class here should be called as Ext JS class as Ext JS 4.0 create the infrastructure of Class and Object. extend and mixins are both preprocessors in ExtJS 4.0. I list default preprocessors and postprocessors as below.

  • default preprocessors (defined in Class.js):
    'extend', 'statics', 'inheritableStatics', 'mixins', 'config'
  • default postprocessors (defined in ClassManager.js):
    'alias', 'singleton', 'alternateClassName'

Although ExtJS tries to implement a Class infrastructure for OOP, it is not a sophisticated OOP environment after all. For example, the throw statement we used above does not really force subclass developer to implement methods. Subclass developer will not know until he run the code. This happens there is no something like ExtJS compiler or interpreter. But, we can apply certain OO design concept with it. Also, we need to be careful not to make same properties or function names in different preprocessors or postprocessors as, obviously, ExtJS class functions will deal with these processors in sequence.