Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: "Choose an Image" with Uploader?

  1. #1

    Default "Choose an Image" with Uploader?

    This is a modification of the image chooser dialog that includes an uploader.

    Does anybody have suggestions on the user interface or a better method to do this?



    I just added the following to chooser.js:

    Code:
    var up = layout.add('south', new Ext.ContentPanel('uploaddiv', {
    	title: 'Upload a New Image',
    	autoCreate : true,
    	fitToFrame:true
    }));
    
    // Create a self-reference so scoping doesn't prevent us from calling a private method
    var that = this;
    
    document.getElementById('uploadform').onsubmit = function() {
    	return AIM.submit(document.forms[0], {'onComplete' : function(response) {
    		that.load();
    	}});
    }
    Along with the AIM library:

    Code:
    AIM = {
        frame : function(c) {
            var n = 'f' + Math.floor(Math.random() * 99999);
            var d = document.createElement('DIV');
            d.innerHTML = '<iframe style="display:none" src="about:blank" id="'+n+'" name="'+n+'" onload="AIM.loaded(\''+n+'\')"></iframe>';
            document.body.appendChild(d);
    
            var i = document.getElementById(n);
            if (c && typeof(c.onComplete) == 'function') {
                i.onComplete = c.onComplete;
            }
    
            return n;
        },
    
        form : function(f, name) {
            f.setAttribute('target', name);
        },
    
        submit : function(f, c) {
            AIM.form(f, AIM.frame(c));
            if (c && typeof(c.onStart) == 'function') {
                return c.onStart();
            } else {
                return true;
            }
        },
    	
        loaded : function(id) {
            var i = document.getElementById(id);
            if (i.contentDocument) {
                var d = i.contentDocument;
            } else if (i.contentWindow) {
                var d = i.contentWindow.document;
            } else {
                var d = window.frames[id].document;
            }
            if (d.location.href == "about:blank") {
                return;
            }
    
            if (typeof(i.onComplete) == 'function') {
                i.onComplete(d.body.innerHTML);
            }
        }
    }
    And a the upload form

    Code:
    <style type="text/css">
    	.upload_panel {
    		background-color: #d9e8fb;
    		width: 100%;
    		height: 100%;
    		padding: 5px;
    	}
    </style>
    
    <div id="uploaddiv" class="x-layout-inactive-content">
        <form name="form1" method="post" action="test.aspx" id="uploadform" class="upload_panel" enctype="multipart/form-data">
            <input type="file" name="FileUpload1" id="FileUpload1" />
            <input type="submit" name="UploadButton1" value="Upload" id="UploadButton1" />
        </form>
    </div>

  2. #2
    Ext Premium Member BernardChhun's Avatar
    Join Date
    Mar 2007
    Location
    Quebec, Canada
    Posts
    831

    Default

    I wouldn't force the upload input to the user. I'd put it in a collapsible inner south region just so that users can see it when they want to use it. Using an appropriate icon in the collapsed region should be good too

  3. #3
    Ext JS Premium Member
    Join Date
    Mar 2007
    Location
    NL
    Posts
    608

    Default

    I've modified the sample by adding a button "Upload".. Clicking the button will show a modal dialog with page with an html upload control inside an iframe. The dialog is closed after submitting and the view is reloaded.

    Thanks

    Marco

  4. #4
    Ext User amon's Avatar
    Join Date
    Apr 2007
    Location
    Budapest
    Posts
    109

    Default

    I created a menu button for the upload in the head toolbar of chooser (see attachment), and I've created inside a form and an input(file), on onchange, it upload the file in a created iframe, then (the response html /javascript/) run a callback method, what sent in a parameter.
    This method closes the menu, make empty the input field and reload the jsonview.
    Attached Images Attached Images

  5. #5
    Sencha User Animal's Avatar
    Join Date
    Mar 2007
    Location
    Bédoin/Nottingham
    Posts
    30,892

    Default

    Youi don't need the AIM library. Ext handles file uploads. (Well, I know it does with the YUI adapter because YUI handles file uploads)

  6. #6

    Default

    Amon: could you please share your code.. It looks like something I could really use..

  7. #7
    Ext User amon's Avatar
    Join Date
    Apr 2007
    Location
    Budapest
    Posts
    109

    Default

    Of course, here is the code, but It's a little chaotic, and It's not too Object Oriented (It's the testing version, I work on the final version...).:

    [HTML]var ImageChooser = function(config){
    // create the dialog from scratch
    var dlg = new Ext.LayoutDialog(config.id || Ext.id(), {
    autoCreate : true,
    minWidth:400,
    minHeight:300,
    syncHeightBeforeShow: true,
    shadow:true,
    fixedcenter:true,
    center:{autoScroll:false},
    east:{split:true,initialSize:150,minSize:150,maxSize:250},
    modal:true
    });
    dlg.setTitle('Change picture');
    dlg.getEl().addClass('ychooser-dlg');
    dlg.addKeyListener(27, dlg.hide, dlg);

    // add some buttons
    this.ok = dlg.addButton('Save', this.doCallback, this);
    this.ok.disable();
    dlg.setDefaultButton(dlg.addButton('Cancel', dlg.hide, dlg));
    dlg.on('show', this.load, this);
    this.dlg = dlg;
    var layout = dlg.getLayout();

    // filter/sorting toolbar
    this.tb = new Ext.Toolbar(this.dlg.body.createChild({tag:'div'}),[
    {text:'Upload',menu:{}},'-',
    {text:'Refresh',handler:this.reload.bind(this)},'-',
    {text:'Delete',disabled:true,handler:this.deleteImage.bind(this)},'-'
    ]);
    this.sortSelect = Ext.DomHelper.append(this.dlg.body.dom, {
    tag:'select', children: [
    {tag: 'option', value:'name', selected: 'true', html:'Name'},
    {tag: 'option', value:'size', html:'Size'},
    {tag: 'option', value:'lastmod', html:'Modify'}
    ]
    }, true);
    this.tb.items.items[0].menu.getEl().createChild({
    tag: 'form', id: 'uiform',
    style: 'margin:0px;padding:0px;display:inline',
    method:'post',
    enctype: 'multipart/form-data',
    target:'uiframe',
    action:'index.php?module=uploadimage',
    autocomplete:'off',
    cn: {
    id: 'uiFile',
    name:'uiFile',
    tag:'input',
    type:'file',
    style:'margin:3px',
    readonly:true,
    onchange:this.uploadImage.bind(this)
    }
    });
    $('uiFile').readonly = true;
    $('uiFile').onchange = this.uploadImage.bind(this);
    this.sortSelect.on('change', this.sortImages, this, true);

    this.txtFilter = Ext.DomHelper.append(this.dlg.body.dom, {
    tag:'input', type:'text', size:'12'}, true);

    this.txtFilter.on('focus', function(){this.dom.select();});
    this.txtFilter.on('keyup', this.filter, this, {buffer:500});

    this.tb.add(
    'Filter:',
    this.txtFilter.dom,
    'separator',
    'Sort:',
    this.sortSelect.dom);

    // add the panels to the layout
    layout.beginUpdate();
    var vp = layout.add('center', new Ext.ContentPanel(Ext.id(), {
    autoCreate : true,
    toolbar: this.tb,
    fitToFrame:true
    }));
    var dp = layout.add('east', new Ext.ContentPanel(Ext.id(), {
    autoCreate : true,
    fitToFrame:true
    }));
    layout.endUpdate();

    var bodyEl = vp.getEl();
    bodyEl.appendChild(this.tb.getEl());
    var viewBody = bodyEl.createChild({tag:'div', cls:'ychooser-view'});
    vp.resizeEl = viewBody;

    this.detailEl = dp.getEl();

    // create the required templates
    this.thumbTemplate = new Ext.Template(
    '<div class="thumb-wrap" id="{name}">' +
    '<div class="thumb"><img src="{url}" title="{name}"></div>' +
    '<span>{shortName}</span></div>'
    );
    this.thumbTemplate.compile();

    this.detailsTemplate = new Ext.Template(
    '<div class="details"><center><img src="{origurl}" width="120"></center><div class="details-info">' +
    '<b>Filename:</b>' +
    '<span>{name}</span>' +
    '<b>Size:</b>' +
    '<span>{sizeString}</span>' +
    '<b>Last modify:</b>' +
    '<span>{dateString}</span></div></div>'
    );
    this.detailsTemplate.compile();

    // initialize the View
    this.view = new Ext.JsonView(viewBody, this.thumbTemplate, {
    singleSelect: true,
    jsonRoot: 'images',id: 'name',
    emptyText : '<div style="padding:10px;">Nincs k

  8. #8
    Ext User amon's Avatar
    Join Date
    Apr 2007
    Location
    Budapest
    Posts
    109

    Default

    The refresh imagelist backend:
    PHP Code:
    <?php
    if(!$_POST['directory') exit;
    if(isset(
    $_POST['deleteimage']) && file_exists($config->path['img_product'].$_POST['deleteimage'])) {
    @
    unlink($config->path['img_product'].$_POST['directory'].DIRECTORY_SEPARATOR.$_POST['deleteimage']);
    }

    header('Content-Type:text/javascript; charset=UTF-8');
    $temp = array();
    $dir glob($config->path['img_product'].$_POST['directory'].DIRECTORY_SEPARATOR."thmb_*");
    if(
    $dir) {
        foreach (
    $dir as $key => $value) {
            
    $valuefn str_replace($config->path['img_product'],'',$value);
            if(
    $valuefn != 'nopicture.jpg') {
                
    $temp[] = '{"name":"'.str_replace($_POST['directory'].DIRECTORY_SEPARATOR.'thmb_','',$valuefn).'",'.
                
    '"size":'.filesize($value).','.
                
    '"lastmod":'.filemtime($value).','.
                
    '"url":"'.str_replace("/","\/",$config->url['img_product']).str_replace("'","\'",$valuefn).'"}';
            }
        }
    }
    exit(
    '{"images":['.implode(',',$temp).']}');
    ?>
    Here is a $config object. It must be changed for some config option.
    The $config->path['img_product'] is the absolute path to the images root (the directories are in it)
    The $config->url['img_product'] options is the base url to the path directory.

  9. #9
    Ext User amon's Avatar
    Join Date
    Apr 2007
    Location
    Budapest
    Posts
    109

    Default

    The upload handling
    PHP Code:
    <?php if(!isset($_GET['directory'])) exit; ?>
    <script type="text/javascript">
    <?php

    $image_types 
    = array(
        
    'image/gif' => array('imagecreatefromgif','imagegif'),
        
    'image/jpg' => array('imagecreatefromjpeg','imagejpeg'),
        
    'image/jpeg' => array('imagecreatefromjpeg','imagejpeg'),
        
    'image/png' => array('imagecreatefrompng','imagepng')
    );

    if(isset(
    $_FILES['uiFile']) && is_uploaded_file($_FILES['uiFile']['tmp_name']) && $_FILES['uiFile']['error'] == UPLOAD_ERR_OK &&
        
    in_array(mime_content_type($_FILES['uiFile']['tmp_name']),array_keys($image_types))) {
        
    $crfunc $image_types[mime_content_type($_FILES['uiFile']['tmp_name'])][0];
        if(
    $tmpimg $crfunc($_FILES['uiFile']['tmp_name'])) {
            
            
    $info getimagesize($_FILES['uiFile']['tmp_name']);
            
    // original
            
    if($info[0]>$info[1]) {
                
    $newX $info[0]>120 120 $info[0];
                if(
    $newX==$info[0]) {$newY $info[1];} else {$newY round($info[1] * ($newX/$info[0]));}
            } else {
                
    $newY $info[1]>170 170 $info[1];
                if(
    $newY==$info[1]) {$newX $info[0];} else {$newX round($info[0] * ($newY/$info[1]));}
            }
            
    // create original
            
    $newImage imagecreatetruecolor($newX,$newY);
            
    imagecopyresampled($newImage,$tmpimg,0,0,0,0,$newX,$newY,$info[0],$info[1]);
            
    $svfunc $image_types[mime_content_type($_FILES['uiFile']['tmp_name'])][1];
            @
    unlink($config->path['img_product'].$_GET['directory'].DIRECTORY_SEPARATOR.$_FILES['uiFile']['name']);
            
    $svfunc($newImage,$config->path['img_product'].$_GET['directory'].DIRECTORY_SEPARATOR.$_FILES['uiFile']['name']);
            
    imagedestroy($newImage);
            
            
    // thumbnail
            
    $newY $info[1]>80 80 $info[1];
            if(
    $newY==$info[1]) {$newX $info[0];} else {$newX round($info[0] * ($newY/$info[1]));}
            
    // create thmb
            
    $newImage imagecreatetruecolor($newX,$newY);
            
    imagecopyresampled($newImage,$tmpimg,0,0,0,0,$newX,$newY,$info[0],$info[1]);
            
    $svfunc $image_types[mime_content_type($_FILES['uiFile']['tmp_name'])][1];
            @
    unlink($config->path['img_product'].$_GET['directory'].DIRECTORY_SEPARATOR.'thmb_'.$_FILES['uiFile']['name']);
            
    $svfunc($newImage,$config->path['img_product'].$_GET['directory'].DIRECTORY_SEPARATOR.'thmb_'.$_FILES['uiFile']['name']);
            
    imagedestroy($newImage);
            
    imagedestroy($tmpimg);
        }
    }
    ?>
    </script>
    <script type="text/javascript">
        parent.window.$('uiFile').value = '';
        parent.window.chooser.tb.items.items[0].menu.hide();
        parent.window.chooser.reload();
    </script>
    Do not forget it, this code runs in the IFrame!

    I think, this will be not working for the first time, because (I wrote it in the first post) it is not OO, and there are some hacking, some relations to my active project.
    If you can change these lines, it can be working. Or you can wait some days, and I will post this OO version of this turbo image chooser.
    There is some hardcoded image sizes... 120width and 170height maximum. It resizes to the longer side and keep the aspect. BTW, it create a thumbnail too (thmb_*) and these thumbnails will showing up in the body of the chooser. It's 80pixel height max.

  10. #10
    Ext User
    Join Date
    Mar 2007
    Posts
    102

    Default

    This is cool but there is still the limitation of choosing one file at a time using the input control.
    This may be one case where it makes sense to use a signed java applet to allow multiple selection drag and drop of files/folders into the upload area. One such java applet is Rad Upload available from http://www.radinks.com/upload/.
    The free version supports files up to 512Kb.

Page 1 of 2 12 LastLast

Similar Threads

  1. Where are animate classes: "Actor" , "Animato
    By Young in forum Ext 2.x: Help & Discussion
    Replies: 13
    Last Post: 25 Jul 2007, 4:00 AM
  2. "FireFox2 kills cursor" and text-select in toolbar
    By brian in forum Ext 1.x: Bugs
    Replies: 8
    Last Post: 7 Jun 2007, 12:12 AM
  3. Firebug and enctype="multipart/form-data"
    By Domitian in forum Ext 1.x: Help & Discussion
    Replies: 1
    Last Post: 21 Feb 2007, 2:56 PM
  4. Show "Loading" message before load a Grid
    By cadudecastroalves in forum Ext 1.x: Help & Discussion
    Replies: 1
    Last Post: 11 Dec 2006, 6:43 AM
  5. Help with "auto"-height rows displaying images
    By next2you in forum Ext 1.x: Help & Discussion
    Replies: 5
    Last Post: 6 Dec 2006, 12:20 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •