1. #711
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,506
    Vote Rating
    373
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    Thank you for the info, I'll take deeper look when porting it to Ext 3.x final version.
    Jozef Sakalos, aka Saki

    Education, extensions and services for developers at new http://extjs.eu
    News: Grid Search Plugin, ExtJS 5 Complex Data Binding using MVVM


  2. #712
    Ext JS Premium Member Foggy's Avatar
    Join Date
    Apr 2007
    Location
    Switzerland
    Posts
    477
    Vote Rating
    0
    Foggy is on a distinguished road

      0  

    Default


    Thank you for the info
    You are very welcome...

    I was playing around with your extension today. Done some changes, espacielly for the upload progress of much files, wich works fine for me now. On your demo page, if i choose, let me say 4 files, just the last one get the upload state.
    When you porting this extension and you would like to see my file, just let me know please.
    I would like it if my code helps you anyway

    BTW: i just played with the upload extension...

  3. #713
    Ext JS Premium Member Foggy's Avatar
    Join Date
    Apr 2007
    Location
    Switzerland
    Posts
    477
    Vote Rating
    0
    Foggy is on a distinguished road

      0  

    Default


    I decide to post my changes right here. Think some stuff is much asked in this thread.
    Maybe other guys can confirm that this version work well for they too..

    To see what i have done, just do a search with "@Foggy" as term.
    Should be good commented...

    So here are my changes in FilePanel.js
    PHP Code:
    // vim: ts=4:sw=4:nu:fdc=4:nospell
    /**
     * Ext.ux.form.UploadPanel
     *
     * @author  Ing. Jozef Sakáloš
     * @version $Id: Ext.ux.UploadPanel.js 310 2008-08-14 17:23:48Z jozo $
     * @date    13. March 2008
     *
     * @license Ext.ux.form.UploadPanel is licensed under the terms of
     * the Open Source LGPL 3.0 license.  Commercial use is permitted to the extent
     * that the code/component(s) do NOT become part of another Open Source or Commercially
     * licensed development library or toolkit without explicit permission.
     * 
     * License details: http://www.gnu.org/licenses/lgpl.html
     */

    /*global Ext */

    /**
     * @class Ext.ux.UploadPanel
     * @extends Ext.Panel
     */
    Ext.ux.UploadPanel Ext.extend(Ext.Panel, {

        
    // configuration options overridable from outside
        // {{{
        /**
         * @cfg {String} addIconCls icon class for add (file browse) button
         */
         
    addIconCls:'icon-add'

        
    /**
         * @cfg {String} addText Text on Add button
         */
        
    ,addText:'Add'

        
    /**
         * @cfg {Object} baseParams This object is not used directly by FileTreePanel but it is
         * propagated to lower level objects instead. Included here for convenience.
         */

        /**
         * @cfg {String} bodyStyle style to use for panel body
         */
        
    ,bodyStyle:'padding:2px'

        
    /**
         * @cfg {String} buttonsAt Where buttons are placed. Valid values are tbar, bbar, body (defaults to 'tbar')
         */
        
    ,buttonsAt:'tbar'

        
    /**
         * @cfg {String} clickRemoveText
         */
        
    ,clickRemoveText:'Click to remove'

        
    /**
         * @cfg {String} clickStopText
         */
        
    ,clickStopText:'Click to stop'

        
    /**
         * @cfg {String} emptyText empty text for dataview
         */
        
    ,emptyText:'No files'

        
    /**
         * @cfg {Boolean} enableProgress true to enable querying server for progress information
         * Passed to underlying uploader. Included here for convenience.
         */
        
    ,enableProgress:true

        
    /**
         * @cfg {String} errorText
         */
        
    ,errorText:'Error'

        
    /**
         * @cfg {String} fileCls class prefix to use for file type classes
         */
        
    ,fileCls:'file'

        
    /**
         * @cfg {String} fileQueuedText File upload status text
         */
        
    ,fileQueuedText:'File <b>{0}</b> is queued for upload' 

        
    /**
         * @cfg {String} fileDoneText File upload status text
         */
        
    ,fileDoneText:'File <b>{0}</b> has been successfully uploaded'

        
    /**
         * @cfg {String} fileFailedText File upload status text
         */
        
    ,fileFailedText:'File <b>{0}</b> failed to upload'

        
    /**
         * @cfg {String} fileStoppedText File upload status text
         */
        
    ,fileStoppedText:'File <b>{0}</b> stopped by user'

        
    /**
         * @cfg {String} fileUploadingText File upload status text
         */
        
    ,fileUploadingText:'Uploading file <b>{0}</b>'

        
    /**
         * @cfg {Number} maxFileSize Maximum upload file size in bytes
         * This config property is propagated down to uploader for convenience
         */
        
    ,maxFileSize:524288

        
    /**
         * @cfg {Number} Maximum file name length for short file names
         */
        
    ,maxLength:18

        
    /**
         * @cfg {String} removeAllIconCls iconClass to use for Remove All button (defaults to 'icon-cross'
         */
        
    ,removeAllIconCls:'icon-cancel'

        
    /**
         * @cfg {String} removeAllText text to use for Remove All button tooltip
         */
        
    ,removeAllText:'Remove All'

        
    /**
         * @cfg {String} removeIconCls icon class to use for remove file icon
         */
        
    ,removeIconCls:'icon-delete'

        
    /**
         * @cfg {String} removeText Remove text
         */
        
    ,removeText:'Remove'

        
    /**
         * @cfg {String} selectedClass class for selected item of DataView
         */
        
    ,selectedClass:'ux-up-item-selected'

        
    /**
         * @cfg {Boolean} singleUpload true to upload files in one form, false to upload one by one
         * This config property is propagated down to uploader for convenience
         */
        
    ,singleUpload:false

        
    /**
         * @cfg {String} stopAllText
         */
        
    ,stopAllText:'Stop All'

        
    /** 
         * @cfg {String} stopIconCls icon class to use for stop
         */
        
    ,stopIconCls:'icon-cancel'

        
    /**
         * @cfg {String/Ext.XTemplate} tpl Template for DataView.
         */

        /**
         * @cfg {String} uploadText Upload text
         */
        
    ,uploadText:'Upload'

        
    /**
         * @cfg {String} uploadIconCls icon class to use for upload button
         */
        
    ,uploadIconCls:'icon-upload'

        
    /**
         * @cfg {String} workingIconCls iconClass to use for busy indicator
         */
        
    ,workingIconCls:'icon-loading'

        
    // }}}

        // overrides
        // {{{
        
    ,initComponent:function() {
            
    // {{{
            // create buttons
            // add (file browse button) configuration
            
    var addCfg = {
                 
    xtype:'browsebutton'
                
    ,text:this.addText '...'
                
    ,iconCls:this.addIconCls
                
    ,scope:this
                
    ,handler:this.onAddFile
            
    };

            
    // upload button configuration
            
    var upCfg = {
                 
    xtype:'button'
                
    ,iconCls:this.uploadIconCls
                
    ,text:this.uploadText
                
    ,scope:this
                
    ,handler:this.onUpload
                
    ,disabled:true
            
    };

            
    // remove all button configuration
            
    var removeAllCfg = {
                 
    xtype:'button'
                
    ,iconCls:this.removeAllIconCls
                
    ,tooltip:this.removeAllText
                
    ,scope:this
                
    ,handler:this.onRemoveAllClick
                
    ,disabled:true
            
    };

            
    // todo: either to cancel buttons in body or implement it
            
    if('body' !== this.buttonsAt) {
                
    this[this.buttonsAt] = [addCfgupCfg'->'removeAllCfg];
            }
            
    // }}}
            // {{{
            // create store
            // fields for record
            
    var fields = [
                 {
    name:'id'type:'text'system:true}
                ,{
    name:'shortName'type:'text'system:true}
                ,{
    name:'fileName'type:'text'system:true}
                ,{
    name:'filePath'type:'text'system:true}
                ,{
    name:'fileCls'type:'text'system:true}
                ,{
    name:'input'system:true}
                ,{
    name:'form'system:true}
                ,{
    name:'state'type:'text'system:true}
                ,{
    name:'error'type:'text'system:true}
                ,{
    name:'progressId'type:'int'system:true}
                ,{
    name:'bytesTotal'type:'int'system:true}
                ,{
    name:'bytesUploaded'type:'int'system:true}
                ,{
    name:'estSec'type:'int'system:true}
                ,{
    name:'filesUploaded'type:'int'system:true}
                ,{
    name:'speedAverage'type:'int'system:true}
                ,{
    name:'speedLast'type:'int'system:true}
                ,{
    name:'timeLast'type:'int'system:true}
                ,{
    name:'timeStart'type:'int'system:true}
                ,{
    name:'pctComplete'type:'int'system:true}
            ];

            
    // add custom fields if passed
            
    if(Ext.isArray(this.customFields)) {
                
    fields.push(this.customFields);
            }

            
    // create store
            
    this.store = new Ext.data.SimpleStore({
                 
    id:0
                
    ,fields:fields
                
    ,data:[]
            });
            
    // }}}
            // {{{
            // create view
            
    Ext.apply(this, {
                
    items:[{
                     
    xtype:'dataview'
                    
    ,itemSelector:'div.ux-up-item'
                    
    ,store:this.store
                    
    ,selectedClass:this.selectedClass
                    
    ,singleSelect:true
                    
    ,emptyText:this.emptyText
                    
    ,tplthis.tpl || new Ext.XTemplate(
                          
    '<tpl for=".">'
                        
    '<div class="ux-up-item">'
    //                    + '<div class="ux-up-indicator"> </div>'
                        
    '<div class="ux-up-icon-file {fileCls}"> </div>'
                        
    '<div class="ux-up-text x-unselectable" qtip="{fileName}">{shortName}</div>'
                        
    '<div id="remove-{[values.input.id]}" class="ux-up-icon-state ux-up-icon-{state}"'
                        
    'qtip="{[this.scope.getQtip(values)]}"> </div>'
                        
    '</div>'
                        
    '</tpl>'
                        
    , {scope:this}
                    )
                    ,
    listeners:{click:{scope:thisfn:this.onViewClick}}

                }]
            });
            
    // }}}

            // call parent
            
    Ext.ux.UploadPanel.superclass.initComponent.apply(thisarguments);

            
    // save useful references
            
    this.view this.items.itemAt(0);

            
    // {{{
            // add events
            
    this.addEvents(
                
    /**
                 * Fires before the file is added to store. Return false to cancel the add
                 * @event beforefileadd
                 * @param {Ext.ux.UploadPanel} this
                 * @param {Ext.Element} input (type=file) being added
                 */
                
    'beforefileadd'
                
    /**
                 * Fires after the file is added to the store
                 * @event fileadd
                 * @param {Ext.ux.UploadPanel} this
                 * @param {Ext.data.Store} store
                 * @param {Ext.data.Record} Record (containing the input) that has been added to the store
                 */
                
    ,'fileadd'
                
    /**
                 * Fires before the file is removed from the store. Return false to cancel the remove
                 * @event beforefileremove
                 * @param {Ext.ux.UploadPanel} this
                 * @param {Ext.data.Store} store
                 * @param {Ext.data.Record} Record (containing the input) that is being removed from the store
                 */
                
    ,'beforefileremove'
                
    /**
                 * Fires after the record (file) has been removed from the store
                 * @event fileremove
                 * @param {Ext.ux.UploadPanel} this
                 * @param {Ext.data.Store} store
                 */
                
    ,'fileremove'
                
    /**
                 * Fires before all files are removed from the store (queue). Return false to cancel the clear.
                 * Events for individual files being removed are suspended while clearing the queue.
                 * @event beforequeueclear
                 * @param {Ext.ux.UploadPanel} this
                 * @param {Ext.data.Store} store
                 */
                
    ,'beforequeueclear'
                
    /**
                 * Fires after the store (queue) has been cleared
                 * Events for individual files being removed are suspended while clearing the queue.
                 * @event queueclear
                 * @param {Ext.ux.UploadPanel} this
                 * @param {Ext.data.Store} store
                 */
                
    ,'queueclear'
                
    /**
                 * Fires after the upload button is clicked but before any upload is started
                 * Return false to cancel the event
                 * @param {Ext.ux.UploadPanel} this
                 */
                
    ,'beforeupload'
            
    );
            
    // }}}
            // {{{
            // relay view events
            
    this.relayEvents(this.view, [
                 
    'beforeclick'
                
    ,'beforeselect'
                
    ,'click'
                
    ,'containerclick'
                
    ,'contextmenu'
                
    ,'dblclick'
                
    ,'selectionchange'
            
    ]);
            
    // }}}

            // create uploader
            
    var config = {
                 
    store:this.store
                
    ,singleUpload:this.singleUpload
                
    ,maxFileSize:this.maxFileSize
                
    ,enableProgress:this.enableProgress
                
    ,url:this.url
                
    ,path:this.path
            
    };
            if(
    this.baseParams) {
                
    config.baseParams this.baseParams;
            }

            if(
    this.progressUrl) {
                
    config.progressUrl this.progressUrl;
            }

            if(
    this.progressBaseParams) {
                
    config.progressBaseParams this.progressBaseParams;
            }
            
            
    this.uploader = new Ext.ux.FileUploader(config);

            
    // relay uploader events
            
    this.relayEvents(this.uploader, [
                 
    'beforeallstart'
                
    ,'allfinished'
                
    ,'progress'
            
    ]);

            
    // install event handlers
            
    this.on({
                 
    beforeallstart:{scope:thisfn:function() {
                     
    this.uploading true;
                    
    this.updateButtons();
                }}
                ,
    allfinished:{scope:thisfn:function() {
                    
    this.uploading false;
                    
    this.updateButtons();
                }}
                ,
    progress:{fn:this.onProgress.createDelegate(this)}
            });
        } 
    // eo function initComponent
        // }}}
        // {{{
        /**
         * onRender override, saves references to buttons
         * @private
         */
        
    ,onRender:function() {
            
    // call parent
            
    Ext.ux.UploadPanel.superclass.onRender.apply(thisarguments);

            
    // save useful references
            
    var tb 'tbar' === this.buttonsAt this.getTopToolbar() : this.getBottomToolbar();
            
    this.addBtn Ext.getCmp(tb.items.first().id);
            
    this.uploadBtn Ext.getCmp(tb.items.itemAt(1).id);
            
    this.removeAllBtn Ext.getCmp(tb.items.last().id);
        } 
    // eo function onRender
        // }}}

        // added methods
        // {{{
        /**
         * called by XTemplate to get qtip depending on state
         * @private
         * @param {Object} values XTemplate values
         */
        
    ,getQtip:function(values) {
            var 
    qtip '';
            switch(
    values.state) {
                case 
    'queued':
                    
    qtip String.format(this.fileQueuedTextvalues.fileName);
                    
    qtip += '<br>' this.clickRemoveText;
                break;

                case 
    'uploading':
                    
    qtip String.format(this.fileUploadingTextvalues.fileName);
                    
    qtip += '<br>' values.pctComplete '% done';
                    
    qtip += '<br>' this.clickStopText;
                break;

                case 
    'done':
                    
    qtip String.format(this.fileDoneTextvalues.fileName);
                    
    qtip += '<br>' this.clickRemoveText;
                break;

                case 
    'failed':
                    
    qtip String.format(this.fileFailedTextvalues.fileName);
                    
    qtip += '<br>' this.errorText ':' values.error;
                    
    qtip += '<br>' this.clickRemoveText;
                break;

                case 
    'stopped':
                    
    qtip String.format(this.fileStoppedTextvalues.fileName);
                    
    qtip += '<br>' this.clickRemoveText;
                break;
            }
            return 
    qtip;
        } 
    // eo function getQtip
        // }}}
        // {{{
        /**
         * get file name
         * @private
         * @param {Ext.Element} inp Input element containing the full file path
         * @return {String}
         */
        
    ,getFileName:function(inp) {
            return 
    inp.getValue().split(/[\/\\]/).pop();
        } 
    // eo function getFileName
        // }}}
        // {{{
        /**
         * get file size in byte or 0
         *
         * @Foggy        added file size check for supoorted browser
         *
         * @private
         * @param {Ext.Element} inp Input element containing the full file
         * @return {Int}
         */
        
    ,getFileBytes:function(inp) {
            var 
    size 0;
            if (
    Ext.isMozilla) {
                var 
    size inp.dom.files[0].fileSize;
            } else if (
    Ext.isSafari) {
                
    /*console.log(inp.dom.PROCESSING_INSTRUCTION_NODE);    
                for (var p in inp.dom) {
                    console.log(p);    
                }*/
            
    } else if (Ext.isOpera) {
                
            } else if (
    Ext.isIE) {
                
            }
            return 
    size;
        } 
    // eo function getFileBytes
        // }}}
        // {{{
        /**
         * get file path (excluding the file name)
         * @private
         * @param {Ext.Element} inp Input element containing the full file path
         * @return {String}
         */
        
    ,getFilePath:function(inp) {
            return 
    inp.getValue().replace(/[^\/\\]+$/,'');
        } 
    // eo function getFilePath
        // }}}
        // {{{
        /**
         * returns file class based on name extension
         * @private
         * @param {String} name File name to get class of
         * @return {String} class to use for file type icon
         */
        
    ,getFileCls: function(name) {
            var 
    atmp name.split('.');
            if(
    === atmp.length) {
                return 
    this.fileCls;
            }
            else {
                return 
    this.fileCls '-' atmp.pop().toLowerCase();
            }
        }
        
    // }}}
        // {{{
        /**
         * called when file is added - adds file to store
         *
         * @Foggy        added file size check for supoorted browser
         *
         * @private
         * @param {Ext.ux.BrowseButton}
         */
        
    ,onAddFile:function(bb) {
            if(
    true !== this.eventsSuspended && false === this.fireEvent('beforefileadd'thisbb.getInputFile())) {
                return;
            }
            var 
    inp bb.detachInputFile();
            
    inp.addClass('x-hidden');
            var 
    fileName this.getFileName(inp);
            
            
    //@Foggy added -->
            
    var fileBytes this.getFileBytes(inp);
            if (
    fileBytes this.maxFileSize) {
                
    //@todo        got this in the localization file
                
    Ext.Msg.alert('Error''Your choosen file is too large. ' Ext.util.Format.fileSize(this.maxFileSize) + ' is maximum size allowed!');
                return;
            }
            
    //@Foggy added <--
            
            // create new record and add it to store
            
    var rec = new this.store.recordType({
                 
    input:inp
                
    ,fileName:fileName
                
    ,filePath:this.getFilePath(inp)
                ,
    shortNameExt.util.Format.ellipsis(fileNamethis.maxLength)
                ,
    fileCls:this.getFileCls(fileName)
                ,
    state:'queued'
            
    }, inp.id);
            
    rec.commit();
            
    this.store.add(rec);

            
    this.syncShadow();

            
    this.uploadBtn.enable();
            
    this.removeAllBtn.enable();

            if(
    true !== this.eventsSuspended) {
                
    this.fireEvent('fileadd'thisthis.storerec);
            }

            
    this.doLayout();
        } 
    // eo onAddFile
        // }}}
        // {{{
        /**
         * destroys child components
         * @private
         */
        
    ,onDestroy:function() {
            
    // destroy uploader
            
    if(this.uploader) {
                
    this.uploader.stopAll();
                
    this.uploader.purgeListeners();
                
    this.uploader null;
            }

            
    // destroy view
            
    if(this.view) {
                
    this.view.purgeListeners();
                
    this.view.destroy();
                
    this.view null;
            }

            
    // destroy store
            
    if(this.store) {
                
    this.store.purgeListeners();
                
    this.store.destroy();
                
    this.store null;
            }
        } 
    // eo function onDestroy
        // }}}
        // {{{
        /**
         * progress event handler
         * @private
         * @param {Ext.ux.FileUploader} uploader
         * @param {Object} data progress data
         * @param {Ext.data.Record} record
         */
        
    ,onProgress:function(uploaderdatarecord) {
            var 
    bytesTotalbytesUploadedpctCompletestateidxitemwidthpgWidth;
            if(
    record) {
                
    state record.get('state');
                
    bytesTotal record.get('bytesTotal') || 1;
                
    bytesUploaded record.get('bytesUploaded') || 0;
                if(
    'uploading' === state) {
                    
    pctComplete Math.round(1000 bytesUploaded/bytesTotal) / 10;
                }
                else if(
    'done' === state) {
                    
    pctComplete 100;
                }
                else {
                    
    pctComplete 0;
                }
                
    record.set('pctComplete'pctComplete);

                
    idx this.store.indexOf(record);
                
    item Ext.get(this.view.getNode(idx));
                if(
    item) {
                    
    width item.getWidth();
                    
    item.applyStyles({'background-position':width pctComplete 100 'px'});
                }
            }
        } 
    // eo function onProgress
        // }}}
        // {{{
        /**
         * called when file remove icon is clicked - performs the remove
         * @private
         * @param {Ext.data.Record}
         */
        
    ,onRemoveFile:function(record) {
            if(
    true !== this.eventsSuspended && false === this.fireEvent('beforefileremove'thisthis.storerecord)) {
                return;
            }

            
    // remove DOM elements
            
    var inp record.get('input');
            var 
    wrap inp.up('em');
            
    inp.remove();
            if(
    wrap) {
                
    wrap.remove();
            }

            
    // remove record from store
            
    this.store.remove(record);

            var 
    count this.store.getCount();
            
    this.uploadBtn.setDisabled(!count);
            
    this.removeAllBtn.setDisabled(!count);

            if(
    true !== this.eventsSuspended) {
                
    this.fireEvent('fileremove'thisthis.store);
                
    this.syncShadow();
            }
        } 
    // eo function onRemoveFile
        // }}}
        // {{{
        /**
         * Remove All/Stop All button click handler
         * @private
         */
        
    ,onRemoveAllClick:function(btn) {
            if(
    true === this.uploading) {
                
    this.stopAll();
            }
            else {
                
    this.removeAll();
            }
        } 
    // eo function onRemoveAllClick

        
    ,stopAll:function() {
            
    this.uploader.stopAll();
        } 
    // eo function stopAll
        // }}}
        // {{{
        /**
         * DataView click handler
         * @private
         */
        
    ,onViewClick:function(viewindexnodee) {
            var 
    e.getTarget('div:any(.ux-up-icon-queued|.ux-up-icon-failed|.ux-up-icon-done|.ux-up-icon-stopped)');
            if(
    t) {
                
    this.onRemoveFile(this.store.getAt(index));
            }
            
    e.getTarget('div.ux-up-icon-uploading');
            if(
    t) {
                
    this.uploader.stopUpload(this.store.getAt(index));
            }
        } 
    // eo function onViewClick
        // }}}
        // {{{
        /**
         * tells uploader to upload
         * @private
         */
        
    ,onUpload:function() {
            if(
    true !== this.eventsSuspended && false === this.fireEvent('beforeupload'this)) {
                return 
    false;
            }
            
    this.uploader.upload();
        } 
    // eo function onUpload
        // }}}
        // {{{
        /**
         * url setter
         */
        
    ,setUrl:function(url) {
            
    this.url url;
            
    this.uploader.setUrl(url);
        } 
    // eo function setUrl
        // }}}
        // {{{
        /**
         * path setter
         */
        
    ,setPath:function(path) {
            
    this.uploader.setPath(path);
        } 
    // eo function setPath
        // }}}
        // {{{
        /**
         * Updates buttons states depending on uploading state
         * @private
         */
        
    ,updateButtons:function() {
            if(
    true === this.uploading) {
                
    this.addBtn.disable();
                
    this.uploadBtn.disable();
                
    this.removeAllBtn.setIconClass(this.stopIconCls);
                
    this.removeAllBtn.getEl().child(this.removeAllBtn.buttonSelector).dom[this.removeAllBtn.tooltipType] = this.stopAllText;
            }
            else {
                
    this.addBtn.enable();
                
    this.uploadBtn.enable();
                
    this.removeAllBtn.setIconClass(this.removeAllIconCls);
                
    this.removeAllBtn.getEl().child(this.removeAllBtn.buttonSelector).dom[this.removeAllBtn.tooltipType] = this.removeAllText;
            }
        } 
    // eo function updateButtons
        // }}}
        // {{{
        /**
         * Removes all files from store and destroys file inputs
         */
        
    ,removeAll:function() {
            var 
    suspendState this.eventsSuspended;
            if(
    false !== this.eventsSuspended && false === this.fireEvent('beforequeueclear'thisthis.store)) {
                return 
    false;
            }
            
    this.suspendEvents();

            
    this.store.each(this.onRemoveFilethis);

            
    this.eventsSuspended suspendState;
            if(
    true !== this.eventsSuspended) {
                
    this.fireEvent('queueclear'thisthis.store);
            }
            
    this.syncShadow();
        } 
    // eo function removeAll
        // }}}
        // {{{
        /**
         * synchronize context menu shadow if we're in contextmenu
         * @private
         */
        
    ,syncShadow:function() {
            if(
    this.contextmenu && this.contextmenu.shadow) {
                
    this.contextmenu.getEl().shadow.show(this.contextmenu.getEl());
            }
        } 
    // eo function syncShadow
        // }}}

    }); // eo extend

    // register xtype
    Ext.reg('uploadpanel'Ext.ux.UploadPanel);

    // eof 
    FileUploader.js
    PHP Code:
    // vim: ts=4:sw=4:nu:fdc=4:nospell
    /**
     * Ext.ux.FileUploader
     *
     * @author  Ing. Jozef Sakáloš
     * @version $Id: Ext.ux.FileUploader.js 302 2008-08-03 20:57:33Z jozo $
     * @date    15. March 2008
     *
     * @license Ext.ux.FileUploader is licensed under the terms of
     * the Open Source LGPL 3.0 license.  Commercial use is permitted to the extent
     * that the code/component(s) do NOT become part of another Open Source or Commercially
     * licensed development library or toolkit without explicit permission.
     * 
     * License details: http://www.gnu.org/licenses/lgpl.html
     */

    /*global Ext */

    /**
     * @class Ext.ux.FileUploader
     * @extends Ext.util.Observable
     * @constructor
     */
    Ext.ux.FileUploader = function(config) {
        
    Ext.apply(thisconfig);

        
    // call parent
        
    Ext.ux.FileUploader.superclass.constructor.apply(thisarguments);

        
    // add events
        // {{{
        
    this.addEvents(
            
    /**
             * @event beforeallstart
             * Fires before an upload (of all files) is started. Return false to cancel the event.
             * @param {Ext.ux.FileUploader} this
             */
             
    'beforeallstart'
            
    /**
             * @event allfinished
             * Fires after upload (of all files) is finished
             * @param {Ext.ux.FileUploader} this
             */
            
    ,'allfinished'
            
    /**
             * @event beforefilestart
             * Fires before the file upload is started. Return false to cancel the event.
             * Fires only when singleUpload = false
             * @param {Ext.ux.FileUploader} this
             * @param {Ext.data.Record} record upload of which is being started
             */
            
    ,'beforefilestart'
            
    /**
             * @event filefinished
             * Fires when file finished uploading.
             * Fires only when singleUpload = false
             * @param {Ext.ux.FileUploader} this
             * @param {Ext.data.Record} record upload of which has finished
             */
            
    ,'filefinished'
            
    /**
             * @event progress
             * Fires when progress has been updated
             * @param {Ext.ux.FileUploader} this
             * @param {Object} data Progress data object
             * @param {Ext.data.Record} record Only if singleUpload = false
             */
            
    ,'progress'
        
    );
        
    // }}}
    }; // eo constructor

    Ext.extend(Ext.ux.FileUploaderExt.util.Observable, {
        
        
    // configuration options
        // {{{
        /**
         * @cfg {Object} baseParams baseParams are sent to server in each request.
         */
         
    baseParams:{}

        
    // configuration options for progress request
        // {{{
        /**
         * @cfg {Object} baseParams baseParams are sent to server in each progress request.
         *
         * @Foggy        added base params for progress request as well
         *
         */
         
    ,progressBaseParams:{}

        
    /**
         * @cfg {Boolean} concurrent true to start all requests upon upload start, false to start
         * the next request only if previous one has been completed (or failed). Applicable only if
         * singleUpload = false
         */
        
    ,concurrent:true

        
    /**
         * @cfg {Boolean} enableProgress true to enable querying server for progress information
         */
        
    ,enableProgress:true

        
    /**
         * @cfg {String} jsonErrorText Text to use for json error
         */
        
    ,jsonErrorText:'Cannot decode JSON object'

        
    /**
         * @cfg {Number} Maximum client file size in bytes
         */
        
    ,maxFileSize:524288

        
    /**
         * @cfg {String} progressIdName Name to give hidden field for upload progress identificator
         */
        
    ,progressIdName:'UPLOAD_IDENTIFIER'

        
    /**
         * @cfg {Number} progressInterval How often (in ms) is progress requested from server
         */
        
    ,progressInterval:2000

        
    /**
         * @cfg {String} progressUrl URL to request upload progress from
         */
        
    ,progressUrl:'progress.php'

        
    /**
         * @cfg {Object} progressMap Mapping of received progress fields to store progress fields
         */
        
    ,progressMap:{
             
    bytes_total:'bytesTotal'
            
    ,bytes_uploaded:'bytesUploaded'
            
    ,est_sec:'estSec'
            
    ,files_uploaded:'filesUploaded'
            
    ,speed_average:'speedAverage'
            
    ,speed_last:'speedLast'
            
    ,time_last:'timeLast'
            
    ,time_start:'timeStart'
        
    }
        
    /**
         * @cfg {Boolean} singleUpload true to upload files in one form, false to upload one by one
         */
        
    ,singleUpload:false
        
        
    /**
         * @cfg {Ext.data.Store} store Mandatory. Store that holds files to upload
         */

        /**
         * @cfg {String} unknownErrorText Text to use for unknow error
         */
        
    ,unknownErrorText:'Unknown error'

        
    /**
         * @cfg {String} url Mandatory. URL to upload to
         */

        // }}}

        // private
        // {{{
        /**
         * uploads in progress count
         * @private
         */
        
    ,upCount:0
        
    // }}}

        // methods
        // {{{
        /**
         * creates form to use for upload.
         * @private
         * @return {Ext.Element} form
         */
        
    ,createForm:function(record) {
            var 
    progressId parseInt(Math.random() * 1e1010);
            var 
    form Ext.getBody().createChild({
                 
    tag:'form'
                
    ,action:this.url
                
    ,method:'post'
                
    ,cls:'x-hidden'
                
    ,id:Ext.id()
                ,
    cn:[{
                     
    tag:'input'
                    
    ,type:'hidden'
                    
    ,name:'APC_UPLOAD_PROGRESS'
                    
    ,value:progressId
                
    },{
                     
    tag:'input'
                    
    ,type:'hidden'
                    
    ,name:this.progressIdName
                    
    ,value:progressId
                
    },{
                     
    tag:'input'
                    
    ,type:'hidden'
                    
    ,name:'MAX_FILE_SIZE'
                    
    ,value:this.maxFileSize
                
    }]
            });
            if(
    record) {
                
    record.set('form'form);
                
    record.set('progressId'progressId);
            }
            else {
                
    this.progressId progressId;
            }
            return 
    form;
        } 
    // eo function createForm
        // }}}
        // {{{
        
    ,deleteForm:function(formrecord) {
            
    form.remove();
            if(
    record) {
                
    record.set('form'null);
            }
        } 
    // eo function deleteForm
        // }}}
        // {{{
        /**
         * Fires event(s) on upload finish/error
         * @private
         */
        
    ,fireFinishEvents:function(options) {
            if(
    true !== this.eventsSuspended && !this.singleUpload) {
                
    this.fireEvent('filefinished'thisoptions && options.record);
            }
            if(
    true !== this.eventsSuspended && === this.upCount) {
                
    this.stopProgress();
                
    this.fireEvent('allfinished'this);
            }
        } 
    // eo function fireFinishEvents
        // }}}
        // {{{
        /**
         * Geg the iframe identified by record
         * @private
         * @param {Ext.data.Record} record
         * @return {Ext.Element} iframe or null if not found
         */
        
    ,getIframe:function(record) {
            var 
    iframe null;
            var 
    form record.get('form');
            if(
    form && form.dom && form.dom.target) {
                
    iframe Ext.get(form.dom.target);
            }
            return 
    iframe;
        } 
    // eo function getIframe
        // }}}
        // {{{
        /**
         * returns options for Ajax upload request
         * @private
         * @param {Ext.data.Record} record
         * @param {Object} params params to add
         */
        
    ,getOptions:function(recordparams) {
            var 
    = {
                 
    url:this.url
                
    ,method:'post'
                
    ,isUpload:true
                
    ,scope:this
                
    ,callback:this.uploadCallback
                
    ,record:record
                
    ,params:this.getParams(recordparams)
            };
            return 
    o;
        } 
    // eo function getOptions
        // }}}
        // {{{
        /**
         * get params to use for request
         * @private
         * @return {Object} params
         */
        
    ,getParams:function(recordparams) {
            var 
    = {path:this.path};
            
    Ext.apply(pthis.baseParams || {}, params || {});
            return 
    p;
        }
        
    // }}}
        // {{{
        /**
         * processes success response
         * @private
         * @param {Object} options options the request was called with
         * @param {Object} response request response object
         * @param {Object} o decoded response.responseText
         */
        
    ,processSuccess:function(optionsresponseo) {
            var 
    record false;

            
    // all files uploadded ok
            
    if(this.singleUpload) {
                
    this.store.each(function(r) {
                    
    r.set('state''done');
                    
    r.set('error''');
                    
    r.commit();
                });
            }
            else {
                
    record options.record;
                
    record.set('state''done');
                
    record.set('error''');
                
    record.commit();
            }

            
    this.deleteForm(options.formrecord);
        } 
    // eo processSuccess
        // }}}
        // {{{
        /**
         * processes failure response
         *
         * @Foggy        catch server errors
         *
         * @private
         * @param {Object} options options the request was called with
         * @param {Object} response request response object
         * @param {String/Object} error Error text or JSON decoded object. Optional.
         */
        
    ,processFailure:function(optionsresponseerror) {
            var 
    record options.record;
            var 
    records;

            
    // singleUpload - all files uploaded in one form
            
    if(this.singleUpload) {
                
    // some files may have been successful
                
    records this.store.queryBy(function(r){
                    
    //@Foggy changed -->
                    // changed that, im a bit curios, cause on your demo page, this seem to work well
                    // but my logic says, no, there is no way ;)
                    // anyhow, this way, it works for me
                    
    return error.errors error.errors[r.id] : false;
                    
    //@Foggy changed <--
                
    });
                
                
    records.each(function(record) {
                    var 
    error.errors error.errors[record.id] : this.unknownErrorText;
                    if(
    e) {
                        
    record.set('state''failed');
                        
    record.set('error'e);
                        
    Ext.getBody().appendChild(record.get('input'));
                    }
                    else {
                        
    record.set('state''done');
                        
    record.set('error''');
                    }
                    
    record.commit();
                }, 
    this);

                
    this.deleteForm(options.form);
            }
            
    // multipleUpload - each file uploaded in it's own form
            
    else {
                if(
    error && 'object' === Ext.type(error)) {
                    
    record.set('error'error.errors && error.errors[record.id] ? error.errors[record.id] : this.unknownErrorText);
                }
                else if(
    error) {
                    
    record.set('error'error);
                }
                else if(
    response && response.responseText) {
                    
    record.set('error'response.responseText);
                }
                else {
                    
    record.set('error'this.unknownErrorText);
                }
                
    record.set('state''failed');
                
    record.commit();
            }
        } 
    // eof processFailure
        // }}}
        // {{{
        /**
         * Delayed task callback
         *
         * @Foggy        changed some stuff to work with more files - Changes documented in code as well
         *
         */
        
    ,requestProgress:function() {
            var 
    recordsp;
            var 
    = {
                 
    url:this.progressUrl
                
    ,method:'post'
                
    ,paramsthis.progressBaseParams
                
    ,scope:this
                
    ,callback:function(optionssuccessresponse) {
                    var 
    o;
                    if(
    true !== success) {
                        return;
                    }
                    try {
                        
    Ext.decode(response.responseText);
                    }
                    catch(
    e) {
                        return;
                    }
                    if(
    'object' !== Ext.type(o) || true !== o.success) {
                        return;
                    }

                    if(
    this.singleUpload) {
                        
    this.progress = {};
                        for(
    p in o) {
                            if(
    this.progressMap[p]) {
                                
    this.progress[this.progressMap[p]] = parseInt(o[p], 10);
                            }
                        }
                        if(
    true !== this.eventsSuspended) {
                            
    this.fireEvent('progress'thisthis.progress);
                        }

                    }
                    else {
                        
    //@Foggy changed -->
                        // of some reason i got here the last record in store for every call in options.record
                        // so i decide to send back progressId from server to choose the correct record here
                        
    var recs this.store.queryBy(function(r){
                            return 
    r.get('progressId') == o.progressId;
                        });
                        
    // get first, cause just one record can be found
                        
    var rec recs.first();
                        
    // append progressMap like you have done it
                        
    for(p in o) {
                            if(
    this.progressMap[p] && rec) {
                                
    rec.set(this.progressMap[p], parseInt(o[p], 10));
                            }
                        }
                        if(
    rec) {
                            
    rec.commit();
                            if(
    true !== this.eventsSuspended) {
                                
    this.fireEvent('progress'thisrec.datarec);
                            }
                        }
                        
    //@Foggy changed <--
                    
    }
                    
    this.progressTask.delay(this.progressInterval);
                }
            };
            if(
    this.singleUpload) {
                
    o.params[this.progressIdName] = this.progressId;
                
    o.params.APC_UPLOAD_PROGRESS this.progressId;
                
    Ext.Ajax.request(o);
            }
            else {
                
    records this.store.query('state''uploading');
                
    records.each(function(r) {
                    
    o.params[this.progressIdName] = r.get('progressId');
                    
    o.params.APC_UPLOAD_PROGRESS o.params[this.progressIdName];
                    
    // i wouldn't need that anymore
                    
    o.record r;
                    
    //@Foggy changed -->
                    // commented out the timeout, cause in this 250ms o will be overwritten in this loop.
                    // this is cause o is instantiated outside, but thats just my opinion... ;)
                    // anyway, w/o the defer it works with the correct progressId
                    //(function() {
                        
    Ext.Ajax.request(o);
                    
    //}).defer(250);
                    //@Foggy changed <--
                
    }, this);
            }
        } 
    // eo function requestProgress
        // }}}
        // {{{
        /**
         * path setter
         * @private
         */
        
    ,setPath:function(path) {
            
    this.path path;
        } 
    // eo setPath
        // }}}
        // {{{
        /**
         * url setter
         * @private
         */
        
    ,setUrl:function(url) {
            
    this.url url;
        } 
    // eo setUrl
        // }}}
        // {{{
        /**
         * Starts progress fetching from server
         * @private
         */
        
    ,startProgress:function() {
            if(!
    this.progressTask) {
                
    this.progressTask = new Ext.util.DelayedTask(this.requestProgressthis);
            }
            
    this.progressTask.delay.defer(this.progressInterval 2this.progressTask, [this.progressInterval]);
        } 
    // eo function startProgress
        // }}}
        // {{{
        /**
         * Stops progress fetching from server
         * @private
         */
        
    ,stopProgress:function() {
            if(
    this.progressTask) {
                
    this.progressTask.cancel();
            }
        } 
    // eo function stopProgress
        // }}}
        // {{{
        /**
         * Stops all currently running uploads
         */
        
    ,stopAll:function() {
            var 
    records this.store.query('state''uploading');
            
    records.each(this.stopUploadthis);
        } 
    // eo function stopAll
        // }}}
        // {{{
        /**
         * Stops currently running upload
         * @param {Ext.data.Record} record Optional, if not set singleUpload = true is assumed
         * and the global stop is initiated
         */
        
    ,stopUpload:function(record) {
            
    // single abord
            
    var iframe false;
            if(
    record) {
                
    iframe this.getIframe(record);
                
    this.stopIframe(iframe);
                
    this.upCount--;
                
    this.upCount this.upCount this.upCount;
                
    record.set('state''stopped');
                
    this.fireFinishEvents({record:record});
            }
            
    // all abort
            
    else if(this.form) {
                
    iframe Ext.fly(this.form.dom.target);
                
    this.stopIframe(iframe);
                
    this.upCount 0;
                
    this.fireFinishEvents();
            }
        } 
    // eo function abortUpload
        // }}}
        // {{{
        /**
         * Stops uploading in hidden iframe
         * @private
         * @param {Ext.Element} iframe
         */
        
    ,stopIframe:function(iframe) {
            if(
    iframe) {
                try {
                    
    iframe.dom.contentWindow.stop();
                    
    iframe.remove.defer(250iframe);
                }
                catch(
    e){}
            }
        } 
    // eo function stopIframe
        // }}}
        // {{{
        /**
         * Main public interface function. Preforms the upload
         */
        
    ,upload:function() {
            var 
    records this.store.queryBy(function(r){return 'done' !== r.get('state');});
            if(!
    records.getCount()) {
                return;
            }

            
    // fire beforeallstart event
            
    if(true !== this.eventsSuspended && false === this.fireEvent('beforeallstart'this)) {
                return;
            }
            if(
    this.singleUpload) {
                
    this.uploadSingle();
            }
            else {
                
    records.each(this.uploadFilethis);
            }
            
            if(
    true === this.enableProgress) {
                
    this.startProgress();
            }
        } 
    // eo function upload
        // }}}
        // {{{
        /**
         * called for both success and failure. Does nearly nothing
         * @private
         * but dispatches processing to processSuccess and processFailure functions
         */
        
    ,uploadCallback:function(optionssuccessresponse) {
            var 
    o;
            
    this.upCount--;
            
    this.form false;
            
    console.log(this);
            
    // process ajax success
            
    if(true === success) {
                try {
                    
    Ext.decode(response.responseText);
                }
                catch(
    e) {
                    
    this.processFailure(optionsresponsethis.jsonErrorText);
                    
    this.fireFinishEvents(options);
                    return;
                }
                
    // process command success
                
    if(true === o.success) {
                    
    this.processSuccess(optionsresponseo);
                }
                
    // process command failure
                
    else {
                    
    this.processFailure(optionsresponseo);
                }
            }
            
    // process ajax failure
            
    else {
                
    this.processFailure(optionsresponse);
            }

            
    this.fireFinishEvents(options);
        } 
    // eo function uploadCallback
        // }}}
        // {{{
        /**
         * Uploads one file
         * @param {Ext.data.Record} record
         * @param {Object} params Optional. Additional params to use in request.
         */
        
    ,uploadFile:function(recordparams) {
            
    // fire beforestart event
            
    if(true !== this.eventsSuspended && false === this.fireEvent('beforefilestart'thisrecord)) {
                return;
            }

            
    // create form for upload
            
    var form this.createForm(record);

            
    // append input to the form
            
    var inp record.get('input');
            
    inp.set({name:inp.id});
            
    form.appendChild(inp);

            
    // get params for request
            
    var this.getOptions(recordparams);
            
    o.form form;

            
    // set state 
            
    record.set('state''uploading');
            
    record.set('pctComplete'0);

            
    // increment active uploads count
            
    this.upCount++;

            
    // request upload
            
    Ext.Ajax.request(o);

            
    // todo:delete after devel
            
    this.getIframe.defer(100this, [record]);
        } 
    // eo function uploadFile
        // }}}
        // {{{
        /**
         * Uploads all files in single request
         */
        
    ,uploadSingle:function() {
            
    // get records to upload
            
    var records this.store.queryBy(function(r){return 'done' !== r.get('state');});
            if(!
    records.getCount()) {
                return;
            }

            
    // create form and append inputs to it
            
    var form this.createForm();
            
    records.each(function(record) {
                var 
    inp record.get('input');
                
    inp.set({name:inp.id});
                
    form.appendChild(inp);
                
    record.set('state''uploading');
            }, 
    this);

            
    // create options for request
            
    var this.getOptions();
            
    o.form form;

            
    // save form for stop
            
    this.form form;

            
    // increment active uploads counter
            
    this.upCount++;

            
    // request upload
            
    Ext.Ajax.request(o);
        } 
    // eo function uploadSingle
        // }}}

    }); // eo extend

    // register xtype
    Ext.reg('fileuploader'Ext.ux.FileUploader);

     
    // eof 
    That should send correct progressId for each record. Just keep in mind to send that progressId back from the server. It is needed in the progressCallback now to setup the correct record...

    Thanks Saki for this great UX...

  4. #714
    Sencha User calavera's Avatar
    Join Date
    Jan 2008
    Posts
    119
    Vote Rating
    0
    calavera is on a distinguished road

      0  

    Default Filetree and div in west panel

    Filetree and div in west panel


    I am configuring my filetree like this:

    Code:
    treepanel = new Ext.ux.FileTreePanel({
    		 height:300
    		,autoWidth:true
    		,id:'ftp'
    		,rootPath:'../root'
    		,topMenu:true
    		,autoScroll:true
    		,enableProgress:false
    		,singleExpand:true
    	});
    I am using the filetree in a viewport, on the west region. I am trying to display one div under the filetree panel, both inside the west region like this:

    Code:
     items: [treepanel,{
    				 height:100,
                                     id:'newdiv',
    				 border:false,
    				 title:'New div',
    				 autoScroll:true,
    				 html: 'basic html here'
    			}]
                    }
    My filetree panel is displayed correctly but the div not. I can inspect the west region element and I can see a div with the ID "newdiv" created but the filetree panel gets all the height space I think and the div don't have room to fit.. What should I change ?
    Can anybody help ?

    Thank you.

  5. #715
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,506
    Vote Rating
    373
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    What is layout of your west? If you're on Ext 2.x RowFit layout should do the job. See http://extjs.com/deploy/ext-2.2/exam...t-browser.html
    Jozef Sakalos, aka Saki

    Education, extensions and services for developers at new http://extjs.eu
    News: Grid Search Plugin, ExtJS 5 Complex Data Binding using MVVM


  6. #716
    Sencha User calavera's Avatar
    Join Date
    Jan 2008
    Posts
    119
    Vote Rating
    0
    calavera is on a distinguished road

      0  

    Default


    Quote Originally Posted by jsakalos View Post
    What is layout of your west? If you're on Ext 2.x RowFit layout should do the job. See http://extjs.com/deploy/ext-2.2/exam...t-browser.html
    Thanks, Saki. It works with the Rowfit layout.

  7. #717
    Ext User
    Join Date
    Jun 2009
    Posts
    102
    Vote Rating
    0
    js_coder is on a distinguished road

      0  

    Default


    When do you think we'll have a 3.x port for this great extension?

  8. #718
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,506
    Vote Rating
    373
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    I do not want to promise a date but FileTreePanel is at the top of my priorities. I'm going to port my application soon and it cannot work w/o FTP.
    Jozef Sakalos, aka Saki

    Education, extensions and services for developers at new http://extjs.eu
    News: Grid Search Plugin, ExtJS 5 Complex Data Binding using MVVM


  9. #719
    Ext User
    Join Date
    Jun 2009
    Posts
    102
    Vote Rating
    0
    js_coder is on a distinguished road

      0  

    Default


    Cool, let me know if there's anything I can help with.

  10. #720
    Sencha Premium Member
    Join Date
    May 2007
    Posts
    57
    Vote Rating
    0
    tchitani is on a distinguished road

      0  

    Default


    Hi

    Is it possible to expand tree to the specified path on, for example, button or grid row click and send path string?

    var path = '/root/a/b/c';
    Ext.getCmp('FileTree').getRootNode().reload(function(callback){
    Ext.getCmp('FileTree').getRootNode().on({
    load:{single:true, scope:this, fn:function() {
    Ext.getCmp('FileTree').expandPath(path);
    }}
    })
    });

    This does not seem to work

    Thanks

Thread Participants: 173

  1. danvega (10 Posts)
  2. jay@moduscreate.com (1 Post)
  3. jweber (1 Post)
  4. jt (1 Post)
  5. slacker775 (2 Posts)
  6. vmorale4 (12 Posts)
  7. stever (2 Posts)
  8. Dumbledore (9 Posts)
  9. ismoore (1 Post)
  10. mystix (8 Posts)
  11. sdrew (3 Posts)
  12. mxracer (1 Post)
  13. Foggy (3 Posts)
  14. madrabaz (8 Posts)
  15. Thorsten (4 Posts)
  16. Fabyo (1 Post)
  17. mschaefer (11 Posts)
  18. tchitani (3 Posts)
  19. loeppky (11 Posts)
  20. damsfx (1 Post)
  21. cmendez21 (7 Posts)
  22. anjelika (3 Posts)
  23. randcasburn (3 Posts)
  24. mjlecomte (3 Posts)
  25. esoteric (10 Posts)
  26. pravin_bluebird (1 Post)
  27. ZooKeeper (4 Posts)
  28. george.antoniadis (1 Post)
  29. fermo111 (1 Post)
  30. glaforge (2 Posts)
  31. Spirit (1 Post)
  32. newc_k (1 Post)
  33. adam.jimenez (9 Posts)
  34. juandj (10 Posts)
  35. rballman (2 Posts)
  36. Michelangelo (6 Posts)
  37. kk_kkk (7 Posts)
  38. issomesmo (5 Posts)
  39. mashiki (1 Post)
  40. juljupy (2 Posts)
  41. cafebabe (1 Post)
  42. ferrenliu (1 Post)
  43. smartlit (14 Posts)
  44. chunkT (1 Post)
  45. mankz (6 Posts)
  46. luisparada (4 Posts)
  47. iDevelopment (4 Posts)
  48. cblin (9 Posts)
  49. ljaeren (2 Posts)
  50. endlichstudent (9 Posts)
  51. RacingTomcat (1 Post)
  52. lobo-tuerto (5 Posts)
  53. maximumcoder (1 Post)
  54. calavera (3 Posts)
  55. ningle (5 Posts)
  56. jbird526 (4 Posts)
  57. sekundek (8 Posts)
  58. GokhanNL (1 Post)
  59. markkl (1 Post)
  60. basshcm (2 Posts)
  61. dbraiden (2 Posts)
  62. incaic (2 Posts)
  63. silcreval (6 Posts)
  64. sirioz10 (2 Posts)
  65. iulian (2 Posts)
  66. hsurya (7 Posts)
  67. johnrembo (2 Posts)
  68. fraric (4 Posts)
  69. Silver Paladin (5 Posts)
  70. Rafael (2 Posts)
  71. treqx (1 Post)
  72. spectrus (6 Posts)
  73. JoyfulBobHome (2 Posts)
  74. fxlacroix (3 Posts)
  75. jove4015 (1 Post)
  76. rtrocc (12 Posts)
  77. carl23934 (1 Post)
  78. ClemsonJeeper (1 Post)
  79. lagos.tout (2 Posts)
  80. craigharmonic (3 Posts)
  81. siebertm (3 Posts)
  82. zombeerose (11 Posts)
  83. keckeroo (1 Post)
  84. dotchris (7 Posts)
  85. fallenone (4 Posts)
  86. yhwh (1 Post)
  87. harirama (2 Posts)
  88. scroll (1 Post)
  89. mlim1972 (4 Posts)
  90. Arthur.Blake (1 Post)
  91. nileshgund (1 Post)
  92. blow (1 Post)
  93. piyushjain7 (1 Post)
  94. njeriextjs (3 Posts)
  95. hileon (1 Post)
  96. bomka (15 Posts)
  97. --maty (1 Post)
  98. WhiteRussian (1 Post)
  99. kpopov (1 Post)
  100. captainfish (5 Posts)
  101. Gosa (5 Posts)
  102. extjsF4n (1 Post)
  103. Chida (1 Post)
  104. Nthalk (2 Posts)
  105. nescha (2 Posts)
  106. jorgemuza (3 Posts)
  107. Eric24 (1 Post)
  108. edui (1 Post)
  109. shadoi (4 Posts)
  110. acidfilez (1 Post)
  111. BrainDrain (2 Posts)
  112. dimitrij.zub (1 Post)
  113. ixnixnixn (2 Posts)
  114. calicoder (2 Posts)
  115. wes (1 Post)
  116. mammerman (1 Post)
  117. Voronchuk (3 Posts)
  118. jwmianzu (3 Posts)
  119. gnomie (2 Posts)
  120. pflammer (2 Posts)
  121. The0s (2 Posts)
  122. gogogo521 (1 Post)
  123. tegel (2 Posts)
  124. wulfshayde (2 Posts)
  125. mikecx (2 Posts)
  126. paul@demiduk.com (1 Post)
  127. romulodelazzari (1 Post)
  128. sabline (2 Posts)
  129. mikecc (8 Posts)
  130. dan.plifeye (2 Posts)
  131. JGALFO (1 Post)
  132. Stephan Schrade (3 Posts)
  133. khurri.saleem (1 Post)
  134. voidus (1 Post)
  135. Shockdoc1 (1 Post)
  136. dport (3 Posts)
  137. jahman (3 Posts)
  138. Pachat (4 Posts)
  139. BIS (1 Post)
  140. sanraj (4 Posts)
  141. deemonas (1 Post)
  142. jpipas (2 Posts)
  143. martinrame (2 Posts)
  144. MrEnirO (2 Posts)
  145. elona (1 Post)
  146. cwford (6 Posts)
  147. triptonemeister (2 Posts)
  148. gonzalez (1 Post)
  149. wallacer (1 Post)
  150. Natalie (2 Posts)
  151. Phatnine (2 Posts)
  152. js_coder (3 Posts)
  153. Bobrovnik (4 Posts)
  154. kender (1 Post)
  155. avsomeren (2 Posts)
  156. rkulkarni (2 Posts)
  157. lxfliu (2 Posts)
  158. pbaker99 (2 Posts)
  159. naf305 (2 Posts)
  160. cybervirax (1 Post)
  161. AmrMostafa (1 Post)
  162. tumbochka (1 Post)
  163. exdelierium (1 Post)
  164. toubeau (4 Posts)
  165. nosferatum (1 Post)
  166. Boy.Kortman (1 Post)
  167. erlinis (1 Post)
  168. nhocoi (2 Posts)
  169. varunach (1 Post)
  170. _DR_ (1 Post)
  171. rodenp (1 Post)
  172. tutuianu_daniel (1 Post)
  173. Shabneez (2 Posts)