1 /** 2 * Copyright (c) 2008, Steven Chim 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 * 7 * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 * * The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission. 10 * 11 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 */ 13 14 /** 15 * Ext.ux.form.Spinner Class 16 * 17 * @author Steven Chim 18 * @version Spinner.js 2008-08-27 v0.35 19 * 20 * @class Ext.ux.form.Spinner 21 * @extends Ext.form.TriggerField 22 */ 23 24 Ext.namespace("Ext.ux.form"); 25 26 Ext.ux.form.Spinner = function(config){ 27 Ext.ux.form.Spinner.superclass.constructor.call(this, config); 28 this.addEvents({ 29 'spin' : true, 30 'spinup' : true, 31 'spindown' : true 32 }); 33 } 34 35 Ext.extend(Ext.ux.form.Spinner, Ext.form.TriggerField, { 36 triggerClass : 'x-form-spinner-trigger', 37 splitterClass : 'x-form-spinner-splitter', 38 39 alternateKey : Ext.EventObject.shiftKey, 40 strategy : undefined, 41 42 //private 43 onRender : function(ct, position){ 44 Ext.ux.form.Spinner.superclass.onRender.call(this, ct, position); 45 46 this.splitter = this.wrap.createChild({tag:'div', cls:this.splitterClass, style:'width:13px; height:2px;'}); 47 this.splitter.show().setRight( (Ext.isIE) ? 1 : 2 ); 48 this.splitter.show().setTop(10); 49 50 this.proxy = this.trigger.createProxy('', this.splitter, true); 51 this.proxy.addClass("x-form-spinner-proxy"); 52 this.proxy.setStyle('left','0px'); 53 this.proxy.setSize(14, 1); 54 this.proxy.hide(); 55 this.dd = new Ext.dd.DDProxy(this.splitter.dom.id, "SpinnerDrag", {dragElId: this.proxy.id}); 56 57 this.initSpinner(); 58 }, 59 60 //private 61 initTrigger : function(){ 62 this.trigger.addClassOnOver('x-form-trigger-over'); 63 this.trigger.addClassOnClick('x-form-trigger-click'); 64 }, 65 66 //private 67 initSpinner : function(){ 68 this.keyNav = new Ext.KeyNav(this.el, { 69 "up" : function(e){ 70 e.preventDefault(); 71 this.onSpinUp(); 72 }, 73 74 "down" : function(e){ 75 e.preventDefault(); 76 this.onSpinDown(); 77 }, 78 79 "pageUp" : function(e){ 80 e.preventDefault(); 81 this.onSpinUpAlternate(); 82 }, 83 84 "pageDown" : function(e){ 85 e.preventDefault(); 86 this.onSpinDownAlternate(); 87 }, 88 89 scope : this 90 }); 91 92 this.repeater = new Ext.util.ClickRepeater(this.trigger); 93 this.repeater.on("click", this.onTriggerClick, this, {preventDefault:true}); 94 this.trigger.on("mouseover", this.onMouseOver, this, {preventDefault:true}); 95 this.trigger.on("mouseout", this.onMouseOut, this, {preventDefault:true}); 96 this.trigger.on("mousemove", this.onMouseMove, this, {preventDefault:true}); 97 this.trigger.on("mousedown", this.onMouseDown, this, {preventDefault:true}); 98 this.trigger.on("mouseup", this.onMouseUp, this, {preventDefault:true}); 99 this.wrap.on("mousewheel", this.handleMouseWheel, this); 100 101 this.dd.setXConstraint(0, 0, 10) 102 this.dd.setYConstraint(1500, 1500, 10); 103 this.dd.endDrag = this.endDrag.createDelegate(this); 104 this.dd.startDrag = this.startDrag.createDelegate(this); 105 this.dd.onDrag = this.onDrag.createDelegate(this); 106 107 /* 108 jsakalos suggestion 109 http://extjs.com/forum/showthread.php?p=121850#post121850 */ 110 if('object' == typeof this.strategy && this.strategy.xtype) { 111 switch(this.strategy.xtype) { 112 case 'number': 113 this.strategy = new Ext.ux.form.Spinner.NumberStrategy(this.strategy); 114 break; 115 116 case 'date': 117 this.strategy = new Ext.ux.form.Spinner.DateStrategy(this.strategy); 118 break; 119 120 case 'time': 121 this.strategy = new Ext.ux.form.Spinner.TimeStrategy(this.strategy); 122 break; 123 124 default: 125 delete(this.strategy); 126 break; 127 } 128 delete(this.strategy.xtype); 129 } 130 131 if(this.strategy == undefined){ 132 this.strategy = new Ext.ux.form.Spinner.NumberStrategy(); 133 } 134 }, 135 136 //private 137 onMouseOver : function(){ 138 if(this.disabled){ 139 return; 140 } 141 var middle = this.getMiddle(); 142 this.__tmphcls = (Ext.EventObject.getPageY() < middle) ? 'x-form-spinner-overup' : 'x-form-spinner-overdown'; 143 this.trigger.addClass(this.__tmphcls); 144 }, 145 146 //private 147 onMouseOut : function(){ 148 this.trigger.removeClass(this.__tmphcls); 149 }, 150 151 //private 152 onMouseMove : function(){ 153 if(this.disabled){ 154 return; 155 } 156 var middle = this.getMiddle(); 157 if( ((Ext.EventObject.getPageY() > middle) && this.__tmphcls == "x-form-spinner-overup") || 158 ((Ext.EventObject.getPageY() < middle) && this.__tmphcls == "x-form-spinner-overdown")){ 159 } 160 }, 161 162 //private 163 onMouseDown : function(){ 164 if(this.disabled){ 165 return; 166 } 167 var middle = this.getMiddle(); 168 this.__tmpccls = (Ext.EventObject.getPageY() < middle) ? 'x-form-spinner-clickup' : 'x-form-spinner-clickdown'; 169 this.trigger.addClass(this.__tmpccls); 170 }, 171 172 //private 173 onMouseUp : function(){ 174 this.trigger.removeClass(this.__tmpccls); 175 }, 176 177 //private 178 onTriggerClick : function(){ 179 if(this.disabled || this.getEl().dom.readOnly){ 180 return; 181 } 182 var middle = this.getMiddle(); 183 var ud = (Ext.EventObject.getPageY() < middle) ? 'Up' : 'Down'; 184 this['onSpin'+ud](); 185 }, 186 187 //private 188 getMiddle : function(){ 189 var t = this.trigger.getTop(); 190 var h = this.trigger.getHeight(); 191 var middle = t + (h/2); 192 return middle; 193 }, 194 195 //private 196 //checks if control is allowed to spin 197 isSpinnable : function(){ 198 if(this.disabled || this.getEl().dom.readOnly){ 199 Ext.EventObject.preventDefault(); //prevent scrolling when disabled/readonly 200 return false; 201 } 202 return true; 203 }, 204 205 handleMouseWheel : function(e){ 206 //disable scrolling when not focused 207 if(this.wrap.hasClass('x-trigger-wrap-focus') == false){ 208 return; 209 } 210 211 var delta = e.getWheelDelta(); 212 if(delta > 0){ 213 this.onSpinUp(); 214 e.stopEvent(); 215 } else if(delta < 0){ 216 this.onSpinDown(); 217 e.stopEvent(); 218 } 219 }, 220 221 //private 222 startDrag : function(){ 223 this.proxy.show(); 224 this._previousY = Ext.fly(this.dd.getDragEl()).getTop(); 225 }, 226 227 //private 228 endDrag : function(){ 229 this.proxy.hide(); 230 }, 231 232 //private 233 onDrag : function(){ 234 if(this.disabled){ 235 return; 236 } 237 var y = Ext.fly(this.dd.getDragEl()).getTop(); 238 var ud = ''; 239 240 if(this._previousY > y){ud = 'Up';} //up 241 if(this._previousY < y){ud = 'Down';} //down 242 243 if(ud != ''){ 244 this['onSpin'+ud](); 245 } 246 247 this._previousY = y; 248 }, 249 250 //private 251 onSpinUp : function(){ 252 if(this.isSpinnable() == false) { 253 return; 254 } 255 if(Ext.EventObject.shiftKey == true){ 256 this.onSpinUpAlternate(); 257 return; 258 }else{ 259 this.strategy.onSpinUp(this); 260 } 261 this.fireEvent("spin", this); 262 this.fireEvent("spinup", this); 263 }, 264 265 //private 266 onSpinDown : function(){ 267 if(this.isSpinnable() == false) { 268 return; 269 } 270 if(Ext.EventObject.shiftKey == true){ 271 this.onSpinDownAlternate(); 272 return; 273 }else{ 274 this.strategy.onSpinDown(this); 275 } 276 this.fireEvent("spin", this); 277 this.fireEvent("spindown", this); 278 }, 279 280 //private 281 onSpinUpAlternate : function(){ 282 if(this.isSpinnable() == false) { 283 return; 284 } 285 this.strategy.onSpinUpAlternate(this); 286 this.fireEvent("spin", this); 287 this.fireEvent("spinup", this); 288 }, 289 290 //private 291 onSpinDownAlternate : function(){ 292 if(this.isSpinnable() == false) { 293 return; 294 } 295 this.strategy.onSpinDownAlternate(this); 296 this.fireEvent("spin", this); 297 this.fireEvent("spindown", this); 298 } 299 300 }); 301 302 Ext.reg('uxspinner', Ext.ux.form.Spinner); 303 304 /** 305 * Copyright (c) 2008, Steven Chim 306 * All rights reserved. 307 * 308 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 309 * 310 * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 311 * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 312 * * The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission. 313 * 314 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 315 */ 316 317 /*** 318 * Abstract Strategy 319 */ 320 Ext.ux.form.Spinner.Strategy = function(config){ 321 Ext.apply(this, config); 322 }; 323 324 Ext.extend(Ext.ux.form.Spinner.Strategy, Ext.util.Observable, { 325 defaultValue : 0, 326 minValue : undefined, 327 maxValue : undefined, 328 incrementValue : 1, 329 alternateIncrementValue : 5, 330 validationTask : new Ext.util.DelayedTask(), 331 332 onSpinUp : function(field){ 333 this.spin(field, false, false); 334 }, 335 336 onSpinDown : function(field){ 337 this.spin(field, true, false); 338 }, 339 340 onSpinUpAlternate : function(field){ 341 this.spin(field, false, true); 342 }, 343 344 onSpinDownAlternate : function(field){ 345 this.spin(field, true, true); 346 }, 347 348 spin : function(field, down, alternate){ 349 this.validationTask.delay(500, function(){field.validate()}); 350 //extend 351 }, 352 353 fixBoundries : function(value){ 354 return value; 355 //overwrite 356 } 357 358 }); 359 360 /*** 361 * Concrete Strategy: Numbers 362 */ 363 Ext.ux.form.Spinner.NumberStrategy = function(config){ 364 Ext.ux.form.Spinner.NumberStrategy.superclass.constructor.call(this, config); 365 }; 366 367 Ext.extend(Ext.ux.form.Spinner.NumberStrategy, Ext.ux.form.Spinner.Strategy, { 368 369 allowDecimals : true, 370 decimalPrecision : 2, 371 372 spin : function(field, down, alternate){ 373 Ext.ux.form.Spinner.NumberStrategy.superclass.spin.call(this, field, down, alternate); 374 375 var v = parseFloat(field.getValue()); 376 var incr = (alternate == true) ? this.alternateIncrementValue : this.incrementValue; 377 378 (down == true) ? v -= incr : v += incr ; 379 v = (isNaN(v)) ? this.defaultValue : v; 380 v = this.fixBoundries(v); 381 field.setRawValue(v); 382 }, 383 384 fixBoundries : function(value){ 385 var v = value; 386 387 if(this.minValue != undefined && v < this.minValue){ 388 v = this.minValue; 389 } 390 if(this.maxValue != undefined && v > this.maxValue){ 391 v = this.maxValue; 392 } 393 394 return this.fixPrecision(v); 395 }, 396 397 // private 398 fixPrecision : function(value){ 399 var nan = isNaN(value); 400 if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){ 401 return nan ? '' : value; 402 } 403 return value.toFixed(this.decimalPrecision); 404 } 405 }); 406 407 408 /*** 409 * Concrete Strategy: Date 410 */ 411 Ext.ux.form.Spinner.DateStrategy = function(config){ 412 Ext.ux.form.Spinner.DateStrategy.superclass.constructor.call(this, config); 413 }; 414 415 Ext.extend(Ext.ux.form.Spinner.DateStrategy, Ext.ux.form.Spinner.Strategy, { 416 defaultValue : new Date(), 417 format : "Y-m-d", 418 incrementValue : 1, 419 incrementConstant : Date.DAY, 420 alternateIncrementValue : 1, 421 alternateIncrementConstant : Date.MONTH, 422 423 spin : function(field, down, alternate){ 424 Ext.ux.form.Spinner.DateStrategy.superclass.spin.call(this); 425 426 var v = field.getRawValue(); 427 428 v = Date.parseDate(v, this.format); 429 var dir = (down == true) ? -1 : 1 ; 430 var incr = (alternate == true) ? this.alternateIncrementValue : this.incrementValue; 431 var dtconst = (alternate == true) ? this.alternateIncrementConstant : this.incrementConstant; 432 433 if(typeof this.defaultValue == 'string'){ 434 this.defaultValue = Date.parseDate(this.defaultValue, this.format); 435 } 436 437 v = (v) ? v.add(dtconst, dir*incr) : this.defaultValue; 438 439 v = this.fixBoundries(v); 440 field.setRawValue(Ext.util.Format.date(v,this.format)); 441 }, 442 443 //private 444 fixBoundries : function(date){ 445 var dt = date; 446 var min = (typeof this.minValue == 'string') ? Date.parseDate(this.minValue, this.format) : this.minValue ; 447 var max = (typeof this.maxValue == 'string') ? Date.parseDate(this.maxValue, this.format) : this.maxValue ; 448 449 if(this.minValue != undefined && dt < min){ 450 dt = min; 451 } 452 if(this.maxValue != undefined && dt > max){ 453 dt = max; 454 } 455 456 return dt; 457 } 458 459 }); 460 461 /*** 462 * Concrete Strategy: Time 463 */ 464 Ext.ux.form.Spinner.TimeStrategy = function(config){ 465 Ext.ux.form.Spinner.TimeStrategy.superclass.constructor.call(this, config); 466 }; 467 468 Ext.extend(Ext.ux.form.Spinner.TimeStrategy, Ext.ux.form.Spinner.DateStrategy, { 469 format : "H:i", 470 incrementValue : 1, 471 incrementConstant : Date.MINUTE, 472 alternateIncrementValue : 1, 473 alternateIncrementConstant : Date.HOUR 474 }); 475 476 Ext.tree.ColumnTree = Ext.extend(Ext.tree.TreePanel, { 477 lines:false, 478 borderWidth: Ext.isBorderBox ? 0 : 2, // the combined left/right border for each cell 479 cls:'x-column-tree', 480 481 onRender : function(){ 482 Ext.tree.ColumnTree.superclass.onRender.apply(this, arguments); 483 this.headers = this.body.createChild( 484 {cls:'x-tree-headers'},this.innerCt.dom); 485 486 var cols = this.columns, c; 487 var totalWidth = 0; 488 489 for(var i = 0, len = cols.length; i < len; i++){ 490 c = cols[i]; 491 totalWidth += c.width; 492 this.headers.createChild({ 493 cls:'x-tree-hd ' + (c.cls?c.cls+'-hd':''), 494 cn: { 495 cls:'x-tree-hd-text', 496 html: c.header 497 }, 498 style:'width:'+(c.width-this.borderWidth)+'px;' 499 }); 500 } 501 this.headers.createChild({cls:'x-clear'}); 502 // prevent floats from wrapping when clipped 503 this.headers.setWidth(totalWidth); 504 this.innerCt.setWidth(totalWidth); 505 } 506 }); 507 508 Ext.tree.ColumnTreeNode = Ext.extend(Ext.tree.TreeNode, { 509 510 setColumnValue: function(index, value) { 511 var t = this.getOwnerTree(); 512 var oldValue = this[t.columns[index].dataIndex]; 513 this[t.columns[index].dataIndex] = value; 514 this.attributes[[t.columns[index].dataIndex]] = value; 515 if (this.rendered) { 516 this.ui.onColumnValueChange(this, index, value, oldValue); 517 } 518 this.fireEvent('columnvaluechange', this, index, value, oldValue); 519 } 520 }); 521 522 Ext.tree.ColumnNodeUI = Ext.extend(Ext.tree.TreeNodeUI, { 523 focus: Ext.emptyFn, // prevent odd scrolling behavior 524 525 onColumnValueChange: function(n, colIndex, value, oldValue) { 526 if (this.rendered) { 527 var c = n.getOwnerTree().columns[colIndex]; 528 this.columnNodes[colIndex].innerHTML = (c.renderer ? c.renderer(value, n, null) : value); 529 } 530 }, 531 532 renderElements : function(n, a, targetNode, bulkRender){ 533 this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : ''; 534 535 var t = n.getOwnerTree(); 536 var cols = t.columns; 537 var bw = t.borderWidth; 538 var c = cols[0]; 539 540 var cb = typeof a.checked == 'boolean'; 541 var href = a.href ? a.href : Ext.isGecko ? "" : "#"; 542 543 var buf = [ 544 '<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">', 545 '<div class="x-tree-col" style="width:',c.width-bw,'px;">', 546 '<span class="x-tree-node-indent">',this.indentMarkup,"</span>", 547 '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow">', 548 '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />', 549 cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '', 550 '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ', 551 a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '>', 552 '<span unselectable="on">', n.text || (c.renderer ? c.renderer(a[c.dataIndex], n, a) : a[c.dataIndex]),"</span></a>", 553 "</div>"]; 554 for(var i = 1, len = cols.length; i < len; i++){ 555 c = cols[i]; 556 557 buf.push('<div class="x-tree-col ',(c.cls?c.cls:''),'" style="width:',c.width-bw,'px;">', 558 '<div class="x-tree-col-text">',(c.renderer ? c.renderer(a[c.dataIndex], n, a) : a[c.dataIndex]),"</div>", 559 "</div>"); 560 } 561 buf.push( 562 '<div class="x-clear"></div></div>', 563 '<ul class="x-tree-node-ct" style="display:none;"></ul>', 564 "</li>"); 565 566 if(bulkRender !== true && n.nextSibling && n.nextSibling.ui.getEl()){ 567 this.wrap = Ext.DomHelper.insertHtml("beforeBegin", 568 n.nextSibling.ui.getEl(), buf.join("")); 569 }else{ 570 this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf.join("")); 571 } 572 573 this.elNode = this.wrap.childNodes[0]; 574 this.ctNode = this.wrap.childNodes[1]; 575 var cs = this.elNode.firstChild.childNodes; 576 this.indentNode = cs[0]; 577 this.ecNode = cs[1]; 578 this.iconNode = cs[2]; 579 var index = 3; 580 if(cb){ 581 this.checkbox = cs[3]; 582 // fix for IE6 583 this.checkbox.defaultChecked = this.checkbox.checked; 584 index++; 585 } 586 this.anchor = cs[index]; 587 this.columnNodes = [cs[index].firstChild]; 588 for(var i = 1, len = cols.length; i < len; i++){ 589 this.columnNodes[i] = this.elNode.childNodes[i].firstChild; 590 } 591 } 592 }); 593 594 Ext.form.FileUploadField = Ext.extend(Ext.form.TextField, { 595 /** 596 * @cfg {String} buttonText The button text to display on the upload button (defaults to 597 * 'Browse...'). Note that if you supply a value for {@link #buttonCfg}, the buttonCfg.text 598 * value will be used instead if available. 599 */ 600 buttonText: 'Browse...', 601 /** 602 * @cfg {Boolean} buttonOnly True to display the file upload field as a button with no visible 603 * text field (defaults to false). If true, all inherited TextField members will still be available. 604 */ 605 buttonOnly: false, 606 /** 607 * @cfg {Number} buttonOffset The number of pixels of space reserved between the button and the text field 608 * (defaults to 3). Note that this only applies if {@link #buttonOnly} = false. 609 */ 610 buttonOffset: 3, 611 /** 612 * @cfg {Object} buttonCfg A standard {@link Ext.Button} config object. 613 */ 614 615 // private 616 readOnly: true, 617 618 /** 619 * @hide 620 * @method autoSize 621 */ 622 autoSize: Ext.emptyFn, 623 624 // private 625 initComponent: function(){ 626 Ext.form.FileUploadField.superclass.initComponent.call(this); 627 628 this.addEvents( 629 /** 630 * @event fileselected 631 * Fires when the underlying file input field's value has changed from the user 632 * selecting a new file from the system file selection dialog. 633 * @param {Ext.form.FileUploadField} this 634 * @param {String} value The file value returned by the underlying file input field 635 */ 636 'fileselected' 637 ); 638 }, 639 640 // private 641 onRender : function(ct, position){ 642 Ext.form.FileUploadField.superclass.onRender.call(this, ct, position); 643 644 this.wrap = this.el.wrap({cls:'x-form-field-wrap x-form-file-wrap'}); 645 this.el.addClass('x-form-file-text'); 646 this.el.dom.removeAttribute('name'); 647 648 this.fileInput = this.wrap.createChild({ 649 id: this.getFileInputId(), 650 name: this.name||this.getId(), 651 cls: 'x-form-file', 652 tag: 'input', 653 type: 'file', 654 size: 1 655 }); 656 657 var btnCfg = Ext.applyIf(this.buttonCfg || {}, { 658 text: this.buttonText 659 }); 660 this.button = new Ext.Button(Ext.apply(btnCfg, { 661 renderTo: this.wrap 662 })); 663 664 if(this.buttonOnly){ 665 this.el.hide(); 666 this.wrap.setWidth(this.button.getEl().getWidth()); 667 } 668 669 this.fileInput.on('change', function(){ 670 var v = this.fileInput.dom.value; 671 this.setValue(v); 672 this.fireEvent('fileselected', this, v); 673 }, this); 674 }, 675 676 // private 677 getFileInputId: function(){ 678 return this.id+'-file'; 679 }, 680 681 // private 682 onResize : function(w, h){ 683 Ext.form.FileUploadField.superclass.onResize.call(this, w, h); 684 685 this.wrap.setWidth(w); 686 687 if(!this.buttonOnly){ 688 var w = this.wrap.getWidth() - this.button.getEl().getWidth() - this.buttonOffset; 689 this.el.setWidth(w); 690 } 691 }, 692 693 // private 694 preFocus : Ext.emptyFn, 695 696 // private 697 getResizeEl : function(){ 698 return this.wrap; 699 }, 700 701 // private 702 getPositionEl : function(){ 703 return this.wrap; 704 }, 705 706 // private 707 alignErrorIcon : function(){ 708 this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]); 709 } 710 711 }); 712 Ext.reg('fileuploadfield', Ext.form.FileUploadField); 713 714 /** 715 * Ext.ux.FullProgressBar Class 716 * 717 * @author Damien Churchill <damoxc@gmail.com> 718 * @version 1.2 719 * 720 * @class Ext.deluge.ProgressBar 721 * @extends Ext.ProgressBar 722 * @constructor 723 * @param {Object} config Configuration options 724 */ 725 Ext.ux.FullProgressBar = Ext.extend(Ext.ProgressBar, { 726 initComponent: function() { 727 Ext.ux.FullProgressBar.superclass.initComponent.call(this); 728 }, 729 730 updateProgress: function(value, text, animate) { 731 this.value = value || 0; 732 if (text) { 733 this.updateText(text); 734 } 735 736 if (this.rendered) { 737 var w = Math.floor(value*this.el.dom.firstChild.offsetWidth / 100.0); 738 this.progressBar.setWidth(w, animate === true || (animate !== false && this.animate)); 739 if (this.textTopEl) { 740 //textTopEl should be the same width as the bar so overflow will clip as the bar moves 741 this.textTopEl.removeClass('x-hidden').setWidth(w); 742 } 743 } 744 this.fireEvent('update', this, value, text); 745 return this; 746 } 747 }); 748 Ext.reg('fullprogressbar', Ext.ux.FullProgressBar); 749 750 751 // Allow radiogroups to be treated as a single form element. 752 Ext.override(Ext.form.RadioGroup, { 753 754 afterRender: function() { 755 var that = this; 756 this.items.each(function(i) { 757 that.relayEvents(i, ['check']); 758 }); 759 Ext.form.RadioGroup.superclass.afterRender.call(this) 760 }, 761 762 getName: function() { 763 return this.items.first().getName(); 764 }, 765 766 getValue: function() { 767 var v; 768 769 this.items.each(function(item) { 770 v = item.getRawValue(); 771 return !item.getValue(); 772 }); 773 774 return v; 775 }, 776 777 setValue: function(v) { 778 if (!this.items.each) return; 779 this.items.each(function(item) { 780 item.setValue((item.getRawValue() === 'true') == v); 781 }); 782 } 783 }); 784