Results 1 to 7 of 7

Thread: [Ext 4] Simple Textfield character counter

  1. #1
    Sencha User
    Join Date
    Apr 2013
    Posts
    629
    Vote Rating
    117
      1  

    Default [Ext 4] Simple Textfield character counter

    This simple plugin displays remaining character count (maxLength has to be set) next to a textfield.
    It's pretty rough in current state and one of the reasons I am posting it is to get some feedback.

    Current version has few drawbacks:
    • Character count is not updated when textfield value is set by loading a record to a form (updateCounter has to be manually called)
    • It doesn't automatically reduce input width to accommodate the counter width. The right textfield width has to be manually set. Fixed by geopalam.
    • Only compatible with ExtJS 4. Doesn't work correctly with 5.
    I know that I could use (X)Templates to add the counter to the field (afterSubTpl?) but I am not sure how to efficiently update it when textfield value changes. Suggestions how the plugin could be improved are highly appreciated.

    PHP Code:
    Ext.define('Ext.ux.plugins.CounterTextField', {
        
    extend'Ext.util.Observable',
        
    alias'plugin.counter',

        
    constructor: function (config)
        {
            
    Ext.apply(thisconfig || {});
            
    this.callParent(arguments);
        },

        
    init: function (field)
        {
            
    field.on({
                
    scopefield,
                
    keyupthis.updateCounter,
                
    focusthis.updateCounter
            
    });
            if (!
    field.rendered)
                
    field.on('afterrender'this.handleAfterRenderfield);
            else
                
    this.handleAfterRender(field);
        },

        
    handleAfterRender: function(field)
        {
            
    field.counterEl field.bodyEl.createChild({
                
    tag'span',
                
    style'padding-left:5px;top:4px;position:absolute;',
                
    htmlfield.maxLength
            
    });
            
    setTimeout(function() {field.inputEl.setStyle({display:'inline',width:'90%'});}, 200);
            
    field.enableKeyEvents true;
        },

        
    updateCounter: function(textField)
        {
            
    textField.counterEl.update('' +
                 (
    textField.maxLength textField.getValue().length));
        }
    }); 
    Here is a usage example: https://fiddle.sencha.com/#fiddle/82v

    Edit: applied fix (or a simple hack) by geopalam for one of the issues listed above.

  2. #2
    Sencha - Support Team
    Join Date
    Feb 2013
    Location
    California
    Posts
    10,396
    Vote Rating
    264
      0  

    Default

    Looks handy! Thanks for sharing with the community.

  3. #3
    Sencha Premium Member
    Join Date
    Aug 2012
    Posts
    4
    Vote Rating
    1
      1  

    Question

    Hi

    I have been, for my own amusement, trying to rewrite part of this so it will work in both extjs 4.2 and 5.0 at the same time.

    Code is:

    Code:
    Ext.define('Ext.ux.plugins.CounterTextField', {
                extend: 'Ext.util.Observable',
                alias: 'plugin.counter',
    
                constructor: function (config)
                {
                    Ext.apply(this, config || {});
    
                    this.callParent(arguments);
                },
    
                init: function (field)
                {
                    field.on({
                        scope: field,
                        keyup: this.updateCounter,
                        focus: this.updateCounter
                    });
                    if (!field.rendered) {
                        field.on('afterrender', this.handleAfterRender, field, {single:true});
                    } else {
                        this.handleAfterRender(field);
                    }
                },
    
                handleAfterRender: function(field)
                {
                    field.counterEl = Ext.DomHelper.insertAfter(
                            field.inputEl,
                            {
                                tag: 'span',
                                style: 'width:10%;padding-left:4px',
                                html: field.maxLength
                            },
                            true);
    
                    field.enableKeyEvents = true;
    
                    setInterval(function(){
                        field.inputEl.setStyle({'display':'inline','width':'90%'},1);
                    });
                },
    
                updateCounter: function(textField)
                {
                    textField.counterEl.update('' +
                            (textField.maxLength - textField.getValue().length));
                }
            });
    
            Ext.application({
                name : 'Character Counter',
    
                launch : function() {
                    Ext.create('Ext.form.Panel', {
                        title: 'Character Counter',
                        bodyPadding: 5,
                        width: 400,
    
                        layout: 'vbox',
    
                        defaults: {
                            xtype: 'textfield',
                            width: 350,
                            labelWidth: 70
                        },
    
                        items: [{
                            fieldLabel: 'First Name',
                            maxLength: 45,
                            grow: false,
                            plugins: ['counter']
                        },{
                            fieldLabel: 'Last Name',
                            maxLength: 50,
                            plugins: ['counter']
                        }, {
                            fieldLabel: 'Address',
                            width: 380
                        }],
    
                        renderTo: Ext.getBody()
                    });
                }
            });
    Would it be better to not use an Observable here and instead use a custom field container with a hbox layout?

    And the layout only seems to work when I add this in:

    Code:
     setInterval(function(){
                        field.inputEl.setStyle({'display':'inline','width':'90%'},1);
                    });
    Why is that?

  4. #4
    Sencha User
    Join Date
    Apr 2013
    Posts
    629
    Vote Rating
    117
      1  

    Default

    I think instead of setInterval() you meant to use "setTimeout()" or "Ext.util.DelayedTask()".
    You can use a combination of textfield and displayfield in hbox layout as an altrernative, but even it's easy to implement it can be a bit "heavy" solution.
    I guess the best solution might be to create custom textfield by extending "Ext.form.textfield" and set some custom template(s) like it was done with IconCombo.

  5. #5
    Sencha Premium Member
    Join Date
    Aug 2012
    Posts
    4
    Vote Rating
    1
      0  

    Default

    Quote Originally Posted by hakimio View Post
    I think instead of setInterval() you meant to use "setTimeout()" or "Ext.util.DelayedTask()".
    You can use a combination of textfield and displayfield in hbox layout as an altrernative, but even it's easy to implement it can be a bit "heavy" solution.
    I guess the best solution might be to create custom textfield by extending "Ext.form.textfield" and set some custom template(s) like it was done with IconCombo.
    Yes you are absolutely correct, should be setTimeout or Delayed Task. Thanks for pointing out that IconCombo will check that out.

  6. #6
    Sencha User
    Join Date
    Aug 2014
    Posts
    27
    Vote Rating
    0
      0  

    Default

    First of all thanks for sharing hakimio and I am having only one doubt you have told that it is compatible only to ExtJs4 versions but you haven't mentioned the browser name and its version in which you have tested which will be very useful for all can you please mention it also.

  7. #7
    Sencha User
    Join Date
    Apr 2013
    Posts
    629
    Vote Rating
    117
      0  

    Default

    Quote Originally Posted by Richardmansfield View Post
    First of all thanks for sharing hakimio and I am having only one doubt you have told that it is compatible only to ExtJs4 versions but you haven't mentioned the browser name and its version in which you have tested which will be very useful for all can you please mention it also.
    I think it's compatible with all browsers, but you can test the fiddle I made yourself.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •