Page 1 of 3 123 LastLast
Results 1 to 10 of 23

Thread: Plugin to allow auto sizing of the combo's list

  1. #1
    Ext JS Premium Member Juanito's Avatar
    Join Date
    Apr 2007
    Location
    San Diego->Boston->Brazil
    Posts
    164
    Vote Rating
    5
      0  

    Smile Plugin to allow auto sizing of the combo's list

    Hello all,

    I needed something to auto size the combo's list to its content. I found the simplest solution here in the forum, overriding initList. However, we hate overriding component's methods, so I wrote a plugin that does the same thing.

    Let me know if anybody uses it.

    PHP Code:
    Ext.ns('wfs.extplugins');

    /**
     * Plugin for Ext.form.ComboBox that auto sizes the combo's list based on the text in the store when the view opens
     * This plugin relies on each item in the having the .x-combo-list-item class. Therefore, if you override the
     * template, make sure each item still has the .x-combo-list-item class.
     * Warning, this plugin relies on the internals of combo box, lookout when upgrading.
     */
    wfs.extplugins.ComboListAutoSizer = (function(){
      
      
    // How much padding to add when measuring the list items, used to prevent text from being jammed against the edge
      
    var LIST_PADDING 10;

      
    /**
       * Auto sizes the list in a combo by measuring the text in the combo's records.
       * @param {Ext.form.ComboBox}combo
       */
      
    function autoSizeList(combo) {
        var 
    viewEl combo.view && combo.view.getEl();
        
    // This may get called before the view is rendered, ignore it in that case
        
    if (!viewEl) {
          return;
        }
        var 
    metrics =  Ext.util.TextMetrics.createInstance(viewEl.child('.x-combo-list-item'));
        
        var 
    maxWidth combo.minListWidth;
        
    combo.getStore().each(function(rec){
          
    // Add some padding so the text is not jammed against the edge of the drop down
          
    maxWidth Math.max(maxWidthmetrics.getWidth(rec.get(combo.displayField)) + LIST_PADDING);
        });
        
    // There are two elements in the dropdown list that have their width set. See Ext.form.ComboBox.initList
        
    combo.list.setWidth(maxWidth);
        
    combo.innerList.setWidth(maxWidth combo.list.getFrameWidth('lr'));
        
    combo.list.alignTo(combo.wrapcombo.listAlign);
      }
      
      
    // Return the actual plugin object
      
    return {
        
    init: function(combo) {
          
    combo.on('expand'autoSizeListnull, {singletrue});
          var 
    store combo.getStore();
          
    store.on('load'autoSizeList);
          
    store.on('update'autoSizeList);
        }
      };
    })(); 
    This plugin is a singleton, so don't use new when adding it to the plugins array:

    PHP Code:
    {
      
    xtype'combo',
      
    plugins: [wfs.extplugins.ComboListAutoSizer]

    Last edited by Juanito; 3 Feb 2011 at 11:33 AM. Reason: Explain that it's a singleton

  2. #2
    Sencha User
    Join Date
    Aug 2009
    Posts
    5
    Vote Rating
    0
      0  

    Default

    Great plugin, is exactly what I was looking!!!!
    I already implemented it in the app I'm doing and works great!
    It would be nice to have the same plugin for grid columns.

    One more comment to your plugin, it would be excellent if it gets the minimum size of the combo if the min width of the list is not set or maybe always. It looks nicer!

  3. #3
    Sencha Premium User
    Join Date
    Jan 2008
    Location
    Germany
    Posts
    533
    Vote Rating
    1
      0  

    Default

    Great plugin, had to make two changes though:
    1. The list has no items on first expand if the store is remote, so you need to check for the existence of an item row before instantiating TextMetrics on it
    2. The autoSizeList function can't be directly assigned as a handler to the store's "load" and "update" events because their signatures don't match
    3. Use combo's itemSelector config property if there is one


    Updated code (relocated to the Ext.ux namespace):

    PHP Code:
    Ext.namespace("Ext.ux");

    Ext.ux.ComboListAutoSizer = (function() {
        
        function 
    autoSizeList(combo) {
            
            var 
    itemEl combo.view && combo.view.getEl() && combo.view.getEl().child(combo.itemSelector || ".x-combo-list-item");
            if (!
    itemEl) return;
            
            var 
    textMetrics Ext.util.TextMetrics.createInstance(itemEl);
            var 
    autoWidth Math.max(combo.minListWidthcombo.getWidth());
            
            
    combo.getStore().each(function(record) {
                
    autoWidth Math.max(autoWidthtextMetrics.getWidth(record.get(combo.displayField)) + 10);
            });
            
            
    combo.list.setWidth(autoWidth);
            
    combo.innerList.setWidth(autoWidth combo.list.getFrameWidth("lr"));
            
    combo.list.alignTo(combo.wrapcombo.listAlign);
            
        }
        
        
    // Public API
        
    return {
            
            
    init: function(combo) {
            
                
    combo.on("expand"autoSizeListnull, {
                    
    singletrue
                
    });
                
                var 
    store combo.getStore();
                
    store.on("load", function() {
                    
    autoSizeList(combo);
                });
                
    store.on("update", function() {
                    
    autoSizeList(combo);
                });
                
            }
        
        };
      
    })(); 
    Last edited by Stefan B; 20 Apr 2010 at 6:45 AM. Reason: Added the previous poster's request to the minimum width calculation

  4. #4
    Ext User
    Join Date
    Mar 2010
    Posts
    17
    Vote Rating
    0
      0  

    Default

    Sorry if my question is dumb, but Ive spend over 2 hours trying to implement this plugin already.
    I put code from Stefan B into file called Ext.ux.plugins.js and include in on my page.

    When add plugins to my combobox as follows
    PHP Code:
    plugins: [new Ext.ux.ComboListAutoSizer()], 
    I get
    Code:
    Ext.ux.ComboListAutoSizer is not a constructor
    What is wrong?

  5. #5
    Ext User
    Join Date
    Apr 2010
    Posts
    1
    Vote Rating
    0
      0  

    Default

    Quote Originally Posted by Juanito View Post
    Hello all,

    I needed something to auto size the combo's list to its content. I found the simplest solution here in the forum, overriding initList. However, we hate overriding component's methods, so I wrote a plugin that does the same thing.

    Let me know if anybody uses it.

    PHP Code:
    Ext.ns('wfs.extplugins');

    /**
     * Plugin for Ext.form.ComboBox that auto sizes the combo's list based on the text in the store when the view opens
     * This plugin relies on each item in the having the .x-combo-list-item class. Therefore, if you override the
     * template, make sure each item still has the .x-combo-list-item class.
     * Warning, this plugin relies on the internals of combo box, lookout when upgrading.
     */
    wfs.extplugins.ComboListAutoSizer = (function(){
      
      
    // How much padding to add when measuring the list items, used to prevent text from being jammed against the edge
      
    var LIST_PADDING 10;

      
    /**
       * Auto sizes the list in a combo by measuring the text in the combo's records.
       * @param {Ext.form.ComboBox}combo
       */
      
    function autoSizeList(combo) {
        var 
    viewEl combo.view && combo.view.getEl();
        
    // This may get called before the view is rendered, ignore it in that case
        
    if (!viewEl) {
          return;
        }
        var 
    metrics =  Ext.util.TextMetrics.createInstance(viewEl.child('.x-combo-list-item'));
        
        var 
    maxWidth combo.minListWidth;
        
    combo.getStore().each(function(rec){
          
    // Add some padding so the text is not jammed against the edge of the drop down
          
    maxWidth Math.max(maxWidthmetrics.getWidth(rec.get(combo.displayField)) + LIST_PADDING);
        });
        
    // There are two elements in the dropdown list that have their width set. See Ext.form.ComboBox.initList
        
    combo.list.setWidth(maxWidth);
        
    combo.innerList.setWidth(maxWidth combo.list.getFrameWidth('lr'));
        
    combo.list.alignTo(combo.wrapcombo.listAlign);
      }
      
      
    // Return the actual plugin object
      
    return {
        
    init: function(combo) {
          
    combo.on('expand'autoSizeListnull, {singletrue});
          var 
    store combo.getStore();
          
    store.on('load'autoSizeList);
          
    store.on('update'autoSizeList);
        }
      };
    })(); 
    This is a godsend and very timely. Thanks very much for the cool plugin. I would it give it a try later today

    Elizabeth Smith
    ronald Cruzag
    u

  6. #6
    Sencha User
    Join Date
    Aug 2009
    Posts
    5
    Vote Rating
    0
      0  

    Default

    Quote Originally Posted by itrushn View Post
    Sorry if my question is dumb, but Ive spend over 2 hours trying to implement this plugin already.
    I put code from Stefan B into file called Ext.ux.plugins.js and include in on my page.

    When add plugins to my combobox as follows
    PHP Code:
    plugins: [new Ext.ux.ComboListAutoSizer()], 
    I get
    Code:
    Ext.ux.ComboListAutoSizer is not a constructor
    What is wrong?
    Try something, in your HTML code, put above your script the declaration of the plugin, if it still doesn't work, put it below.
    <script type="text/javascript" src="Ext.ux.ComboListAutoSizer.js"/>
    <script type="text/javascript" src="yourscript.js"/>

  7. #7
    Sencha Premium User
    Join Date
    Jan 2008
    Location
    Germany
    Posts
    533
    Vote Rating
    1
      0  

    Default

    @ itrushn:

    Quote Originally Posted by itrushn View Post
    When add plugins to my combobox as follows
    PHP Code:
    plugins: [new Ext.ux.ComboListAutoSizer()], 
    I get
    Code:
    Ext.ux.ComboListAutoSizer is not a constructor
    Ext.ux.ComboListAutoSizer is implemented as a singleton.
    Just use
    PHP Code:
    plugins: [new Ext.ux.ComboListAutoSizer

  8. #8
    Ext User
    Join Date
    Mar 2010
    Posts
    17
    Vote Rating
    0
      0  

    Default

    Quote Originally Posted by torres10 View Post
    Try something, in your HTML code, put above your script the declaration of the plugin, if it still doesn't work, put it below.
    <script type="text/javascript" src="Ext.ux.ComboListAutoSizer.js"/>
    <script type="text/javascript" src="yourscript.js"/>
    I've tried shifting script tag around, however that doesnt resolve issue.

  9. #9
    Ext User
    Join Date
    Mar 2010
    Posts
    17
    Vote Rating
    0
      0  

    Default

    Quote Originally Posted by Stefan B View Post
    @ itrushn:



    Ext.ux.ComboListAutoSizer is implemented as a singleton.
    Just use
    PHP Code:
    plugins: [new Ext.ux.ComboListAutoSizer
    Making this change has not fixed the issue. Ive tried moving code around and even placed it inside of the same js file, however I am still receiving Ext.us.ComboListAutoSizer is not a constructor in the firebug.



    Ext.ux looks like that in the DOM browser:

  10. #10
    Ext User
    Join Date
    Mar 2010
    Posts
    17
    Vote Rating
    0
      0  

    Default

    I've just went to original combos.html example file which comes with ExtJS and customized to:

    combos.js
    PHP Code:
    /*!
     * Ext JS Library 3.2.0
     * Copyright(c) 2006-2010 Ext JS, Inc.
     * licensing@extjs.com
     * http://www.extjs.com/license
     */
     
    Ext.namespace("Ext.ux");
    Ext.ux.ComboListAutoSizer = (function ()
    {
        function 
    autoSizeList(combo)
        {
            var 
    itemEl combo.view && combo.view.getEl() && combo.view.getEl().child(combo.itemSelector || ".x-combo-list-item");
            if (!
    itemEl) return;
            var 
    textMetrics Ext.util.TextMetrics.createInstance(itemEl);
            var 
    autoWidth Math.max(combo.minListWidthcombo.getWidth());

            
    combo.getStore().each(function (record)
            {
                
    autoWidth Math.max(autoWidthtextMetrics.getWidth(record.get(combo.displayField)) + 10);
            });
            
    combo.list.setWidth(autoWidth);
            
    combo.innerList.setWidth(autoWidth combo.list.getFrameWidth("lr"));
            
    combo.list.alignTo(combo.wrapcombo.listAlign);
        }

        
    // Public API
        
    return {
            
    init: function (combo)
            {
                
    combo.on("expand"autoSizeListnull, {
                    
    singletrue
                
    });
                var 
    store combo.getStore();
                
    store.on("load", function ()
                {
                    
    autoSizeList(combo);
                });
                
    store.on("update", function ()
                {
                    
    autoSizeList(combo);
                });
            }
        };
    })();  
     
    Ext.onReady(function(){
        
    Ext.QuickTips.init();

        
    // simple array store
        
    var store = new Ext.data.ArrayStore({
            
    fields: ['abbr''state''nick'],
            
    data Ext.exampledata.states // from states.js
        
    });
        var 
    combo = new Ext.form.ComboBox({
            
    storestore,
            
    displayField:'state',
            
    typeAheadtrue,
            
    mode'local',
            
    forceSelectiontrue,
            
    triggerAction'all',
            
    emptyText:'Select a state...',
            
    selectOnFocus:true,
            
    plugins: [new Ext.ux.ComboListAutoSizer],  
            
    applyTo'local-states'
        
    });  
    }); 
    combos.html
    PHP Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <
    html>
    <
    head>
        <
    meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
        <
    title>Combo Boxes</title>
        <
    link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
        <
    link rel="stylesheet" type="text/css" href="../../resources/css/xtheme-gray.css" />

        <!-- 
    GC -->
         <!-- 
    LIBS -->
         <
    script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
         <!-- ENDLIBS -->

        <script type="text/javascript" src="../../ext-all.js"></script>

        <script type="text/javascript" src="states.js"></script>
        <script type="text/javascript" src="combos.js"></script>
        <link rel="stylesheet" type="text/css" href="combos.css" />

        <!-- Common Styles for the examples -->
        <link rel="stylesheet" type="text/css" href="../shared/examples.css" />
        <style type="text/css">
            p { width:650px; }
        </style>
    </head>
    <body>
    <script type="text/javascript" src="../shared/examples.js"></script><!-- EXAMPLES -->
    <h1>Combo Boxes</h1>
    <div>
        <input type="text" id="local-states" size="20"/>
    </div>


    </body>
    </html> 
    When I've opened the file I've received exactly same error which I am describing above. Any idea whats wrong? Does anyone has working example of this plugin?

Page 1 of 3 123 LastLast

Posting Permissions

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