Thank you for reporting this bug. We will make it our priority to review this report.
  1. #1
    Ext JS Premium Member mynameisyoda's Avatar
    Join Date
    Mar 2008
    Location
    Turin, Italy
    Posts
    14
    Vote Rating
    0
    mynameisyoda is on a distinguished road

      0  

    Default [FIXED-282][3.0.2] GridFilter plugins: date filter choke on null date

    [FIXED-282][3.0.2] GridFilter plugins: date filter choke on null date


    Ext version tested:
    • Ext 3.0.2


    Adapter used:
    • ext

    css used:
    • only default ext-all.css

    Browser versions tested against:
    • FF3 (firebug 1.3.0.10 installed)

    Operating System:
    • Mac OS X
    • WinXP Pro
    Description:
    • Using GridFilter plugin on date time column with null value throw exception on non object.


    Test Case:

    Code:
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Custom Grid Filters</title>
    
        <!-- ** CSS ** -->
        <!-- base library -->
        <link rel="stylesheet" type="text/css" href="../resources/css/ext-all.css" />
    
        <!-- overrides to base library -->
        <link rel="stylesheet" type="text/css" href="ux/gridfilters/css/GridFilters.css" />
        <link rel="stylesheet" type="text/css" href="ux/gridfilters/css/RangeMenu.css" />
    
    
        <!-- ** Javascript ** -->
        <!-- ExtJS library: base/adapter -->
        <script type="text/javascript" src="../adapter/ext/ext-base.js"></script>
    
        <!-- ExtJS library: all widgets -->
        <script type="text/javascript" src="../ext-all.js"></script>
    
        <!-- overrides to base library -->
    
        <!-- extensions -->
        <script type="text/javascript" src="ux/gridfilters/menu/RangeMenu.js"></script>
        <script type="text/javascript" src="ux/gridfilters/menu/ListMenu.js"></script>
    
        <script type="text/javascript" src="ux/gridfilters/GridFilters.js"></script>
        <script type="text/javascript" src="ux/gridfilters/filter/Filter.js"></script>
        <script type="text/javascript" src="ux/gridfilters/filter/StringFilter.js"></script>
        <script type="text/javascript" src="ux/gridfilters/filter/DateFilter.js"></script>
        <script type="text/javascript" src="ux/gridfilters/filter/ListFilter.js"></script>
        <script type="text/javascript" src="ux/gridfilters/filter/NumericFilter.js"></script>
        <script type="text/javascript" src="ux/gridfilters/filter/BooleanFilter.js"></script>
    
        <!-- page specific -->
        <script type="text/javascript">
        /*!
        * Ext JS Library 3.0.2
        * Copyright(c) 2006-2009 Ext JS, LLC
        * licensing@extjs.com
        * http://www.extjs.com/license
        */
        Ext.onReady(function(){
    
    
            Ext.QuickTips.init();
    
            
            // for this demo configure local and remote urls for demo purposes
            var url = {
                local:  'grid-filter.json'  // static data file
            };
    
            // configure whether filter query is encoded or not (initially)
            var encode = false;
    
            // configure whether filtering is performed locally or remotely (initially)
            var local = true;
    
            store = new Ext.data.JsonStore({
                // store configs
                autoDestroy: true,
                url: (local ? url.local : url.remote),
                remoteSort: false,
                sortInfo: {
                    field: 'company',
                    direction: 'ASC'
                },
                storeId: 'myStore',
    
                // reader configs
                idProperty: 'id',
                root: 'data',
                totalProperty: 'total',
                fields: [{
                    name: 'id'
                }, {
                    name: 'company'
                }, {
                    name: 'price',
                    type: 'float'
                }, {
                    name: 'date',
                    type: 'date',
                    dateFormat: 'Y-m-d H:i:s'
                }, {
                    name: 'visible',
                    type: 'boolean'
                }, {
                    name: 'size'
                }]
            });
    
            var filters = new Ext.ux.grid.GridFilters({
                // encode and local configuration options defined previously for easier reuse
                encode: encode, // json encode the filter query
                local: local,   // defaults to false (remote filtering)
                filters: [{
                    type: 'numeric',
                    dataIndex: 'id'
                }, {
                    type: 'string',
                    dataIndex: 'company',
                    disabled: true
                }, {
                    type: 'numeric',
                    dataIndex: 'price'
                }, {
                    type: 'date',
                    dataIndex: 'date'
                }, {
                    type: 'list',
                    dataIndex: 'size',
                    options: ['small', 'medium', 'large', 'extra large'],
                    phpMode: true
                }, {
                    type: 'boolean',
                    dataIndex: 'visible'
                }]
            });
    
            // use a factory method to reduce code while demonstrating
            // that the GridFilter plugin may be configured with or without
            // the filter types (the filters may be specified on the column model
            var createColModel = function (finish, start) {
    
                var columns = [{
                    dataIndex: 'id',
                    header: 'Id',
                    // instead of specifying filter config just specify filterable=true
                    // to use store's field's type property (if type property not
                    // explicitly specified in store config it will be 'auto' which
                    // GridFilters will assume to be 'StringFilter'
                    filterable: true
                    //,filter: {type: 'numeric'}
                }, {
                    dataIndex: 'company',
                    header: 'Company',
                    id: 'company',
                    filter: {
                        type: 'string'
                        // specify disabled to disable the filter menu
                        //, disabled: true
                    }
                }, {
                    dataIndex: 'price',
                    header: 'Price',
                    filter: {
                        //type: 'numeric'  // specify type here or in store fields config
                    }
                }, {
                    dataIndex: 'size',
                    header: 'Size',
                    filter: {
                        type: 'list',
                        options: ['small', 'medium', 'large', 'extra large']
                        //,phpMode: true
                    }
                }, {
                    dataIndex: 'date',
                    header: 'Date',
                    renderer: Ext.util.Format.dateRenderer('m/d/Y'),
                    filter: {
                        //type: 'date'     // specify type here or in store fields config
                    }
                }, {
                    dataIndex: 'visible',
                    header: 'Visible',
                    filter: {
                        //type: 'boolean'  // specify type here or in store fields config
                    }
                }];
    
                return new Ext.grid.ColumnModel({
                    columns: columns.slice(start || 0, finish),
                    defaults: {
                        sortable: true
                    }
                });
            };
    
            var grid = new Ext.grid.GridPanel({
                border: false,
                store: store,
                colModel: new Ext.grid.ColumnModel({
                    columns: [{
                        dataIndex: 'id',
                        header: 'Id',
                        // instead of specifying filter config just specify filterable=true
                        // to use store's field's type property (if type property not
                        // explicitly specified in store config it will be 'auto' which
                        // GridFilters will assume to be 'StringFilter'
                        filterable: true
                        //,filter: {type: 'numeric'}
                    }, {
                        dataIndex: 'company',
                        header: 'Company',
                        id: 'company',
                        filter: {
                            type: 'string'
                            // specify disabled to disable the filter menu
                            //, disabled: true
                        }
                    }, {
                        dataIndex: 'price',
                        header: 'Price',
                        filter: {
                            //type: 'numeric'  // specify type here or in store fields config
                        }
                    }, {
                        dataIndex: 'size',
                        header: 'Size',
                        filter: {
                            type: 'list',
                            options: ['small', 'medium', 'large', 'extra large']
                            //,phpMode: true
                        }
                    }, {
                        dataIndex: 'date',
                        header: 'Date',
                        renderer: Ext.util.Format.dateRenderer('m/d/Y'),
                        filter: {
                            //type: 'date'     // specify type here or in store fields config
                        }
                    }, {
                        dataIndex: 'visible',
                        header: 'Visible',
                        filter: {
                            //type: 'boolean'  // specify type here or in store fields config
                        }
                    }]
                }),
                loadMask: true,
                plugins: [filters],
                autoExpandColumn: 'company',
                listeners: {
                    render: {
                        fn: function(){
                            store.load({
                                params: {
                                    start: 0,
                                    limit: 50
                                }
                            });
                        }
                    }
                },
                bbar: new Ext.Toolbar({
                    plugins: [filters]
                })
            });
    
            // add some buttons to bottom toolbar just for demonstration purposes
            grid.getBottomToolbar().add([
            '->',
            {
                text: 'Clear Filter Data',
                handler: function () {
                    grid.filters.clearFilters();
                }
            }
            ]);
    
            var win = new Ext.Window({
                title: 'Grid Filters Example',
                height: 400,
                width: 700,
                layout: 'fit',
                items: grid
            }).show();
    
        });
    </script>
    
    </head>
    <body>
        <div id="grid-example" style="margin: 10px;"></div>
    
    </body>
    </html>
    Steps to reproduce the problem:
    • save the code into examples directory
    • save in the same directory the json data attached (unzipped)
    • filter on the Date column with a date from the collection displayed

    The result that was expected:
    • only the filtered date show on the result
    • date with null value doesnt show on the result

    The result that occurs instead:


    Possible fix:

    Code:
    Ext.override(Ext.ux.grid.filter.DateFilter, {
        validateRecord : function (record) {
            var key,
            pickerValue;
            var val = record.get(this.dataIndex);
    
            if(!val) return false;
    
            val = val.clearTime(true).getTime();
    
            for (key in this.fields) {
                if (this.fields[key].checked) {
                    pickerValue = this.getFieldValue(key).clearTime(true).getTime();
                    if (key == 'before' && pickerValue <= val) {
                        return false;
                    }
                    if (key == 'after' && pickerValue >= val) {
                        return false;
                    }
                    if (key == 'on' && pickerValue != val) {
                        return false;
                    }
                }
            }
            return true;
        }
    });
    Attached Files
    Sergio - Ext addict
    -----------------------------
    may the force be with you

  2. #2
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    83
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    I would prefer:
    Code:
    if(!Ext.isDate(val)) return false;

  3. #3
    Ext JS Premium Member mynameisyoda's Avatar
    Join Date
    Mar 2008
    Location
    Turin, Italy
    Posts
    14
    Vote Rating
    0
    mynameisyoda is on a distinguished road

      0  

    Default


    Quote Originally Posted by Condor View Post
    I would prefer:
    Code:
    if(!Ext.isDate(val)) return false;
    Off course I agree...

    Ubi maior minor cessat...
    Sergio - Ext addict
    -----------------------------
    may the force be with you

  4. #4
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,662
    Vote Rating
    584
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    Fix applied to svn in rev #5456 for patch release 3.0.3.
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

Thread Participants: 2