8/21/2013

[ExtJS] Remove "No file chosen" Tooltip for File Input Field

When I was implementing file uploading feature in js, I found the file field button always shows "No file chosen" in Chrome when the field is empty. I had tried many solutions described in stackoverflow. Unfortunately, none of them could override or remove the "No file chosen" Tooltip. There’s no chance for javasript developer to remove it directly.
No file chosen
"No file chosen" tooltip
<html>
    <head>
    </head>
    <body>
        <input type="file" multiple/>
    </body>
</html>

But when user upload files in gmail, it can show custom tooltip such as “Attach files”.
Gmail file uploading with custom tooltip.
So I checked the source of gmail in firebug, I found the “Attach files” button is defined as a div tag. However, a div tag is not able to open file picker for security issue. How can google make it? Actually, the div tag is just a wrapper. And the file field is hidden in the body. Whenever div tag is clicked, just click the file field programmably. Then you can listen onchange event for file field to get the file metadata. For ExtJS developer, you can refer to the following code in you project.
Custom Tooltip for File Uploading in ExtJS
Ext.define('TonyTuan.BrowseButton', {
    extend : 'Ext.button.Button',
    icon : 'css/images/arrow_up_16x16.png',
    text : 'Browse...',
    constructor : function(config) {
        var me = this;
        // Show custom tooltip instead of "No file chosen".
        config.tooltip = 'Attach Files';
        me.callParent([ config ]);
    },
    handler : function() {
        // To trigger the file field click event
        document.getElementById('upload-field').click();
    }
});

Ext.define('TonyTuan.FileGrid', {
    extend : 'Ext.grid.Panel',
    alias : 'widget.fileGrid',
    title : 'Files',
    store : 'File',
    initComponent : function() {
        var me = this;
        me.columns = [ {
            dataIndex : 'filename',
            header : 'Filename',
        } ];
        me.tbar = [ Ext.create('TonyTuan.BrowseButton', {
            itemId : 'browseButton'
        }) ];
        me.callParent(arguments);
    }
}); 

Ext.define('TonyTuan.FilePanel', {
    extend : 'Ext.panel.Panel',
    title : 'Files',
    layout : 'border',
    initComponent : function() {
        var me = this;
        me.items = [ {
            region : 'center',
            xtype : 'fileGrid',
            layout : 'fit',
            flex : 3,
            margins : '5 5 0 0'
        }, {
            hidden : true,
            region : 'north',
            xtype : 'component',
            html : '<input type="file" multiple id="upload-field"/>'
        } ];
        me.callParent(arguments);
        me.on({
            afterrender : function() {
                document.getElementById('upload-field').onchange = function() {
                    var files = document.getElementById('upload-field').files;
                    console.log('files', files); 
                    // Add files to your fileGrid store
                };
            }
        });
    }
});