`
crabdave
  • 浏览: 1294730 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Ext.ux.form.BrowseButton组件的使用(上传浏览按钮) 示例

阅读更多

Ext.ux.form.BrowseButton组件的使用(上传浏览按钮) 示例

 效果:

 

 创建调用HTML:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css" />
 <script type="text/javascript" src="extjs/adapter/ext/ext-base.js"></script>
 <script type="text/javascript" src="extjs/ext-all.js"></script>
<script type="text/javascript" src="./Ext.ux.form.BrowseButton.js"></script>
<script type="text/javascript" src="./ScreenshotPanel.js"></script>

<style type="text/css">

</style>
<script>
Ext.onReady(function(){
             Ext.QuickTips.init();
             
              new Ext.ux.ScreenshotsPanel({
               renderTo : document.body,
                title: 'Screenshot Adder - Debug = false, meaning Browse butons are hidden.',
                frame: true,
                debug: false
             });
            });
</script>
</head>
<body>

</body>
</html>

 

 ScreenshotsPanel.js文件源码:

/**
 * @class Ext.ux.ScreenshotPanel
 * @extends Ext.Panel
 * Renders a browse button for demonstration purposes.
 * @constructor
 * @param {Object} config The config object
 */
Ext.ux.ScreenshotsPanel = Ext.extend(Ext.Panel, {
 /*
  * Config options
  */
 /**
  * For whether to draw the panel (and it's BrowseButtons) in debug mode.
  * @type Boolean
  */
 debug: false,
 
 
 /*
  * Private properties
  */
 /**
  * Panel for displaying the files that have selected for upload.
  * @type Ext.Panel
  */
 filePanel: null,
 /**
  * Form for uploading screenshot images.
  * Is only instantiated if a screenshot is selected to upload.
  * @type Ext.form.BasicForm
  */
 addScreenshotForm: null,
 
 
 /*
  * Protected methods
  */
 /**
  * @see Ext.Panel.initConfiguration
  */
 initComponent: function(){
  var browseButtonBaseConfig = {
   xtype: 'browsebutton',
   handler: this.onAddScreenshot,
   scope: this,
   tooltip: 'Click to upload a new screenshot.',
   inputFileName: 'screenshot',
   debug: this.debug // set to true to see the "Browse" overlay
  };
  this.filePanel = new Ext.Panel({
   frame: true,
   title: 'selected files',
   buttonAlign: 'center',
   buttons: [{
    text: 'Upload (does not work and will fail)',
    handler: this.uploadScreenshots,
    scope: this
   }]
  });
  Ext.apply(this, {
   tbar: [
    new Ext.ux.form.BrowseButton(Ext.apply({
     text: 'tbar - explicit'
    }, browseButtonBaseConfig)),
    Ext.apply({
     text: 'tbar - xtype'
    }, browseButtonBaseConfig)
   ],
   items: [
    new Ext.ux.form.BrowseButton(Ext.apply({
     text: 'items - explicit'
    }, browseButtonBaseConfig)),
    Ext.apply({
     text: 'items - xtype'
    }, browseButtonBaseConfig),
    this.filePanel
   ],
   buttons: [
    new Ext.ux.form.BrowseButton(Ext.apply({
     text: 'buttons - explicit'
    }, browseButtonBaseConfig)),
    Ext.apply({
     text: 'buttons - xtype'
    }, browseButtonBaseConfig) // doesn't work correctly as Ext uses the config object to instaniate an Ext.Button
   ]
  });
  Ext.ux.ScreenshotsPanel.superclass.initComponent.call(this);
 },
 
 
 /*
  * Private methods
  */
 /**
  * Handler for the add screenshot button.
  * @param {Ext.ux.form.BrowseButton} browseButton The browse button where "Add Screenshot" was clicked.
  * @private
  */
 onAddScreenshot: function(browseButton){
  if (!this.addScreenshotForm) { // if the form hasn't been created
   var addScreenshotFormEl = this.filePanel.body.createChild({
    tag: 'form',
    style: 'display:none'
   });
   this.addScreenshotForm = new Ext.form.BasicForm(addScreenshotFormEl, {
    url: '/AddScreenshot',
    fileUpload: true
   });
  }
  var inputFileEl = browseButton.detachInputFile();
  inputFileEl.appendTo(this.addScreenshotForm.getEl());
  this.filePanel.body.createChild({
   tag: 'div',
   html: inputFileEl.dom.value
  });
 },
 
 /**
  * Handler for the upload screenshots button
  */
 uploadScreenshots: function(){
  this.addScreenshotForm.submit({
   params: {
    extraParam1: 'value1'
   },
   success: this.onAddScreenshotSuccess,
   failure: this.onAddScreenshotFailure,
   scope: this,
   waitTitle: 'Uploading Screenshot',
   waitMsg: 'Your screenshot is being uploaded...'
  });
 },
 
 /**
  * Callback for when a screenshot has been successfully added.
  * @param {Ext.form.BasicForm} form the form for which the uploading occurred.
  * @param {Ext.form.Action} action the action of the form submit
  * @private
  */
 onAddScreenshotSuccess: function(form, action){
  // remove the file input element so that it doesn't get uploaded again with the next screenshot
  var inputFileEl = this.addScreenshotForm.getEl().child('input');
  inputFileEl.remove();
  Ext.Msg.show({
   title: 'Screenshot Upload Success',
   msg: 'Your screenshot was successfully uploaded.',
   buttons: Ext.Msg.OK,
   minWidth: 300
  });
 },
 
 /**
  * Callback for when a screenshot has not been successfully added.
  * @param {Ext.form.BasicForm} form the form for which the uploading occurred.
  * @param {Ext.form.Action} action the action of the form submit
  * @private
  */
 onAddScreenshotFailure: function(form, action){
  // remove the file input element so that it doesn't get uploaded again with the next screenshot
  var inputFileEl = this.addScreenshotForm.getEl().child('input');
  inputFileEl.remove();
  var errorMessageTemplate = new Ext.XTemplate('<p>Your screenshot was not uploaded.  The server reported the following errors:</p>', '<tpl for="errors">', '<p>- {.}</p>', '</tpl>');
  Ext.Msg.show({
   title: 'Screenshot Upload Failed',
   msg: errorMessageTemplate.applyTemplate(action.result),
   buttons: Ext.Msg.OK,
   minWidth: 300
  });
 }
});

 

 Ext.ux.form.BrowseButton.js文件源码:

Ext.namespace('Ext.ux.form');

/**
 * @class Ext.ux.form.BrowseButton
 * @extends Ext.Button
 * Ext.Button that provides a customizable file browse button.
 * Clicking this button, pops up a file dialog box for a user to select the file to upload.
 * This is accomplished by having a transparent <input type="file"> box above the Ext.Button.
 * When a user thinks he or she is clicking the Ext.Button, they're actually clicking the hidden input "Browse..." box.
 * Note: this class can be instantiated explicitly or with xtypes anywhere a regular Ext.Button can be except in 2 scenarios:
 * - Panel.addButton method both as an instantiated object or as an xtype config object.
 * - Panel.buttons config object as an xtype config object.
 * These scenarios fail because Ext explicitly creates an Ext.Button in these cases.
 * Browser compatibility:
 * Internet Explorer 6:
 * - no issues
 * Internet Explorer 7:
 * - no issues
 * Firefox 2 - Windows:
 * - pointer cursor doesn't display when hovering over the button.
 * Safari 3 - Windows:
 * - no issues.
 * @author loeppky - based on the work done by MaximGB in Ext.ux.UploadDialog (http://extjs.com/forum/showthread.php?t=21558)
 * The follow the curosr float div idea also came from MaximGB.
 * @see http://extjs.com/forum/showthread.php?t=29032
 * @constructor
 * Create a new BrowseButton.
 * @param {Object} config Configuration options
 */
Ext.ux.form.BrowseButton = Ext.extend(Ext.Button, {
 /*
  * Config options:
  */
 /**
  * @cfg {String} inputFileName
  * Name to use for the hidden input file DOM element.  Deaults to "file".
  */
 inputFileName: 'file',
 /**
  * @cfg {Boolean} debug
  * Toggle for turning on debug mode.
  * Debug mode doesn't make clipEl transparent so that one can see how effectively it covers the Ext.Button.
  * In addition, clipEl is given a green background and floatEl a red background to see how well they are positioned.
  */
 debug: false,
 
 
 /*
  * Private constants:
  */
 /**
  * @property FLOAT_EL_WIDTH
  * @type Number
  * The width (in pixels) of floatEl.
  * It should be less than the width of the IE "Browse" button's width (65 pixels), since IE doesn't let you resize it.
  * We define this width so we can quickly center floatEl at the mouse cursor without having to make any function calls.
  * @private
  */
 FLOAT_EL_WIDTH: 60,
 
 /**
  * @property FLOAT_EL_HEIGHT
  * @type Number
  * The heigh (in pixels) of floatEl.
  * It should be less than the height of the "Browse" button's height.
  * We define this height so we can quickly center floatEl at the mouse cursor without having to make any function calls.
  * @private
  */
 FLOAT_EL_HEIGHT: 18,
 
 
 /*
  * Private properties:
  */
 /**
  * @property buttonCt
  * @type Ext.Element
  * Element that contains the actual Button DOM element.
  * We store a reference to it, so we can easily grab its size for sizing the clipEl.
  * @private
  */
 buttonCt: null,
 /**
  * @property clipEl
  * @type Ext.Element
  * Element that contains the floatEl.
  * This element is positioned to fill the area of Ext.Button and has overflow turned off.
  * This keeps floadEl tight to the Ext.Button, and prevents it from masking surrounding elements.
  * @private
  */
 clipEl: null,
 /**
  * @property floatEl
  * @type Ext.Element
  * Element that contains the inputFileEl.
  * This element is size to be less than or equal to the size of the input file "Browse" button.
  * It is then positioned wherever the user moves the cursor, so that their click always clicks the input file "Browse" button.
  * Overflow is turned off to preven inputFileEl from masking surrounding elements.
  * @private
  */
 floatEl: null,
 /**
  * @property inputFileEl
  * @type Ext.Element
  * Element for the hiden file input.
  * @private
  */
 inputFileEl: null,
 /**
  * @property originalHandler
  * @type Function
  * The handler originally defined for the Ext.Button during construction using the "handler" config option.
  * We need to null out the "handler" property so that it is only called when a file is selected.
  * @private
  */
 originalHandler: null,
 /**
  * @property originalScope
  * @type Object
  * The scope originally defined for the Ext.Button during construction using the "scope" config option.
  * While the "scope" property doesn't need to be nulled, to be consistent with originalHandler, we do.
  * @private
  */
 originalScope: null,
 
 
 /*
  * Protected Ext.Button overrides
  */
 /**
  * @see Ext.Button.initComponent
  */
 initComponent: function(){
  Ext.ux.form.BrowseButton.superclass.initComponent.call(this);
  // Store references to the original handler and scope before nulling them.
  // This is done so that this class can control when the handler is called.
  // There are some cases where the hidden file input browse button doesn't completely cover the Ext.Button.
  // The handler shouldn't be called in these cases.  It should only be called if a new file is selected on the file system. 
  this.originalHandler = this.handler || null;
  this.originalScope = this.scope || window;
  this.handler = null;
  this.scope = null;
 },
 
 /**
  * @see Ext.Button.onRender
  */
 onRender: function(ct, position){
  Ext.ux.form.BrowseButton.superclass.onRender.call(this, ct, position); // render the Ext.Button
  this.buttonCt = this.el.child('.x-btn-center em');
  this.buttonCt.position('relative'); // this is important!
  var styleCfg = {
   position: 'absolute',
   overflow: 'hidden',
   top: '0px', // default
   left: '0px' // default
  };
  // browser specifics for better overlay tightness
  if (Ext.isIE) {
   Ext.apply(styleCfg, {
    left: '-3px',
    top: '-3px'
   });
  } else if (Ext.isGecko) {
   Ext.apply(styleCfg, {
    left: '-3px',
    top: '-3px'
   });
  } else if (Ext.isSafari) {
   Ext.apply(styleCfg, {
    left: '-4px',
    top: '-2px'
   });
  }
  this.clipEl = this.buttonCt.createChild({
   tag: 'div',
   style: styleCfg
  });
  this.setClipSize();
  this.clipEl.on({
   'mousemove': this.onButtonMouseMove,
   'mouseover': this.onButtonMouseMove,
   scope: this
  });
  
  this.floatEl = this.clipEl.createChild({
   tag: 'div',
   style: {
    position: 'absolute',
    width: this.FLOAT_EL_WIDTH + 'px',
    height: this.FLOAT_EL_HEIGHT + 'px',
    overflow: 'hidden'
   }
  });
  
  
  if (this.debug) {
   this.clipEl.applyStyles({
    'background-color': 'green'
   });
   this.floatEl.applyStyles({
    'background-color': 'red'
   });
  } else {
   this.clipEl.setOpacity(0.0);
  }
  
  this.createInputFile();
 },
 
 
 /*
  * Private helper methods:
  */
 /**
  * Sets the size of clipEl so that is covering as much of the button as possible.
  * @private
  */
 setClipSize: function(){
  if (this.clipEl) {
   var width = this.buttonCt.getWidth();
   var height = this.buttonCt.getHeight();
   if (Ext.isIE) {
    width = width + 5;
    height = height + 5;
   } else if (Ext.isGecko) {
    width = width + 6;
    height = height + 6;
   } else if (Ext.isSafari) {
    width = width + 6;
    height = height + 6;
   }
   this.clipEl.setSize(width, height);
  }
 },
 
 /**
  * Creates the input file element and adds it to inputFileCt.
  * The created input file elementis sized, positioned, and styled appropriately.
  * Event handlers for the element are set up, and a tooltip is applied if defined in the original config.
  * @private
  */
 createInputFile: function(){
 
  this.inputFileEl = this.floatEl.createChild({
   tag: 'input',
   type: 'file',
   size: 1, // must be > 0. It's value doesn't really matter due to our masking div (inputFileCt). 
   name: this.inputFileName || Ext.id(this.el),
   // Use the same pointer as an Ext.Button would use.  This doesn't work in Firefox.
   // This positioning right-aligns the input file to ensure that the "Browse" button is visible.
   style: {
    position: 'absolute',
    cursor: 'pointer',
    right: '0px',
    top: '0px'
   }
  });
  this.inputFileEl = this.inputFileEl.child('input') || this.inputFileEl;
  
  // setup events
  this.inputFileEl.on({
   'click': this.onInputFileClick,
   'change': this.onInputFileChange,
   scope: this
  });
  
  // add a tooltip
  if (this.tooltip) {
   if (typeof this.tooltip == 'object') {
    Ext.QuickTips.register(Ext.apply({
     target: this.inputFileEl
    }, this.tooltip));
   } else {
    this.inputFileEl.dom[this.tooltipType] = this.tooltip;
   }
  }
 },
 
 /**
  * Handler when the cursor moves over the clipEl.
  * The floatEl gets centered to the cursor location.
  * @param {Event} e mouse event.
  * @private
  */
 onButtonMouseMove: function(e){
  var xy = e.getXY();
  xy[0] -= this.FLOAT_EL_WIDTH / 2;
  xy[1] -= this.FLOAT_EL_HEIGHT / 2;
  this.floatEl.setXY(xy);
 },
 
 /**
  * Handler when inputFileEl's "Browse..." button is clicked.
  * @param {Event} e click event.
  * @private
  */
 onInputFileClick: function(e){
  e.stopPropagation();
 },
 
 /**
  * Handler when inputFileEl changes value (i.e. a new file is selected).
  * @private
  */
 onInputFileChange: function(){
  if (this.originalHandler) {
   this.originalHandler.call(this.originalScope, this);
  }
 },
 
 
 /*
  * Public methods:
  */
 /**
  * Detaches the input file associated with this BrowseButton so that it can be used for other purposed (e.g. uplaoding).
  * The returned input file has all listeners and tooltips applied to it by this class removed.
  * @param {Boolean} whether to create a new input file element for this BrowseButton after detaching.
  * True will prevent creation.  Defaults to false.
  * @return {Ext.Element} the detached input file element.
  */
 detachInputFile: function(noCreate){
  var result = this.inputFileEl;
  
  if (typeof this.tooltip == 'object') {
   Ext.QuickTips.unregister(this.inputFileEl);
  } else {
   this.inputFileEl.dom[this.tooltipType] = null;
  }
  this.inputFileEl.removeAllListeners();
  this.inputFileEl = null;
  
  if (!noCreate) {
   this.createInputFile();
  }
  return result;
 },
 
 /**
  * @return {Ext.Element} the input file element attached to this BrowseButton.
  */
 getInputFile: function(){
  return this.inputFileEl;
 },
 
 /**
  * @see Ext.Button.disable
  */
 disable: function(){
  Ext.ux.form.BrowseButton.superclass.disable.call(this);
  this.inputFileEl.dom.disabled = true;
 },
 
 /**
  * @see Ext.Button.enable
  */
 enable: function(){
  Ext.ux.form.BrowseButton.superclass.enable.call(this);
  this.inputFileEl.dom.disabled = false;
 }
});

Ext.reg('browsebutton', Ext.ux.form.BrowseButton);

分享到:
评论

相关推荐

    extjs-Ext.ux.form.LovCombo下拉框

    在EXTJS框架中,`Ext.ux.form.LovCombo`是一种自定义组件,它扩展了基本的`Ext.form.field.ComboBox`,提供了更丰富的功能,尤其是针对多选和联动选择的需求。这个组件通常用于创建具有“lov”(即“Look Up Value”...

    Ext.ux.form.ColorPickerFieldPlus 老外重写调色版

    `Ext.ux.form.ColorPickerFieldPlus` 是一个由老外开发者重写的色彩选择器组件,它扩展了原生的Ext JS库中的`ColorPickerField`控件,为用户提供更加丰富的色彩选取体验。这个组件的目的是为了实现更自由、更接近...

    如何在服务器端 读取Ext.ux.UploadDialog上传的文件?

    在使用 Ext.ux.UploadDialog 进行文件上传时,客户端与服务器端的交互是一个关键环节。Ext.ux.UploadDialog 是一个 ExtJS 框架的扩展组件,它提供了一个友好的用户界面来处理文件上传。在服务器端,我们需要正确解析...

    Ext.ux.form.TinyMCETextArea

    Ext.ux.form.TinyMCETextArea 是一个在Extjs4框架下实现的组件,它将TinyMCE编辑器集成到了ExtJS的表单控件中,提供了富文本编辑的功能。这个组件是基于HTML5构建的,因此在兼容性和功能上能够满足现代网页应用的...

    Extjs4.X下comboboxTree下拉树型菜单,完美支持多选、单选,绝对好用

    Ext.create('Ext.form.field.ComboBox', { fieldLabel: '选择部门', store: Ext.create('Ext.data.TreeStore', { model: 'Department', root: { text: '所有部门', expanded: true, children: [ /* ... *...

    可编辑表格Ext.grid.EditorGridPanel

    Ext.grid.EditorGridPanel是Ext JS库中的一个组件,主要用于创建具有可编辑单元格的表格。这个组件在数据展示和编辑方面提供了丰富的功能,是构建数据密集型应用的理想选择。下面将详细阐述其特点、工作原理及如何...

    ext 下拉树

    在Ext 4.0版本中,下拉树的实现主要依赖于几个关键组件:`Ext.tree.Panel`(树面板)、`Ext.form.field.Tree`(树形字段)以及可能用到的`Ext.data.TreeStore`(树存储)。下面我们将详细探讨这些知识点: 1. **Ext...

    Ext下拉树、下拉表格

    在本项目中,"Ext下拉树、下拉表格"指的是使用Ext库实现的两种交互式组件:下拉树(ComboBox with Tree)和下拉表格(ComboBox with Grid)。这两种组件都是在输入框中展示可选择的列表,但呈现形式不同,下拉树以...

    EXT控件lovcombo

    EXT控件是Sencha EXT JS框架中的一种组件,它提供了丰富的用户界面元素,用于构建复杂的Web应用程序。在EXT控件中,"lovcombo"(即Love Combo)是一种特殊的ComboBox,通常用于显示一个列表,其中每个项可以被选择,...

    Ext Js权威指南(.zip.001

    Ex4.0共2个压缩包特性,《ext js权威指南》 前 言 第1章 ext js 4开发入门 / 1 1.1 学习ext js必需的基础知识 / 1 1.2 json概述 / 3 1.2.1 认识json / 3 1.2.2 json的结构 / 3 1.2.3 json的例子 / 4 1.2.4 ...

    ext表格布局小例子

    &lt;script src="ext-3.2.1/examples/ux/PagingMemoryProxy.js"&gt; ``` 接下来通过 `Ext.onReady` 函数确保 DOM 完全加载后执行代码。 ```javascript Ext.onReady(function() { //... }); ``` #### 三、数据模型与列...

    Ext.data专题

    ### Ext.data专题详解 #### 一、Ext.data概述 **Ext.data** 是一个重要的JavaScript库组件,用于处理数据传输和管理。它定义了一系列的核心概念,包括 **Store**、**Reader** 和 **Proxy**,这些都是Ext.data的...

    Ext 文件上传demo

    在文件上传场景中,EXT可能使用了`Ext.form.FileField`或`Ext.ux.FileUploadField`组件,这些组件提供了文件选择和上传功能。 2. **文件选择控件**:在EXT中,文件选择通常通过一个隐藏的...

    精通JS脚本之ExtJS框架.part1.rar

    10.12 表格与树形的结合——Ext.ux.tree.ColumnTree 第11章 其他布局类简介 11.1 标准布局类 11.1.1 折叠布局——AccordionLayout 11.1.2 边框布局——BorderLayout 11.1.3 卡片式布局——CardLayout 11.1.4 ...

    精通JS脚本之ExtJS框架.part2.rar

    10.12 表格与树形的结合——Ext.ux.tree.ColumnTree 第11章 其他布局类简介 11.1 标准布局类 11.1.1 折叠布局——AccordionLayout 11.1.2 边框布局——BorderLayout 11.1.3 卡片式布局——CardLayout 11.1.4 ...

    ExtJS-4.2.6扩展ux插件89个

    这个特定的压缩包"ExtJS-4.2.6扩展ux插件89个"包含了Ext JS 4.2.6版本的一个重要组件:ux(用户界面扩展)插件。这些插件提供了额外的功能和组件,增强了框架的原生能力,帮助开发者构建更复杂、功能更丰富的应用...

    extjs时间控件

    ExtJS时间控件是Sencha ExtJS框架中的一个组件,用于在Web应用中提供用户友好的时间选择功能。它允许用户以小时、分钟和秒为单位精确选择时间,极大地增强了用户体验,尤其适用于需要用户输入时间信息的场景。在...

    lovcombo-1.0.zip lovcombo-1.0.zip

    2. **Ext.ux.form.LovCombo Extension by Saki.htm**:此文件可能详细介绍了Saki开发的名为LovCombo的扩展,它可能是基于Ext JS框架的一个用户界面组件。"ux"通常表示"用户体验",是Ext JS中用于非核心功能的扩展...

    Ext3_FileUpload:Ext上传文件

    在ExtJS中,文件上传通常通过Ext.form.FileField或Ext.ux.FileUploader组件来实现。这些组件利用HTML5的File API或者传统的form提交方式来处理文件上传。Ext3_FileUpload可能是对原生组件的一种扩展或定制,增加了...

    extjs3.4+swfupload上传

    EXT JS 3.4中的上传功能主要通过其组件系统来实现,特别是`Ext.form.FileField`(也称为上传字段)或`Ext.ux.upload.Uploader`组件。`FileField`允许用户选择文件,并且可以与后端服务器进行交互,完成文件上传。...

Global site tag (gtag.js) - Google Analytics