1. #1
    Sencha User bastard's Avatar
    Join Date
    Aug 2011
    Location
    I'm in Cali baby!
    Posts
    65
    Answers
    2
    Vote Rating
    4
    bastard is on a distinguished road

      0  

    Default Answered: placeholder image while real image downloading

    Answered: placeholder image while real image downloading


    I have a contact list app which has a Ext.List which contains items of Name of person and their photo. Since I am packaging the app, I want to make it so that while the image is being downloaded from a server, the app shows a generic placeholder image. When the person's image is done downloading, I want the generic image should be swapped with the real image of the person WITHOUT causing the Ext.List to refresh/scroll to the top of the List.

    Ideas how to achieve this?

    Here is my itemtpl code right now:
    Code:
    <div> <img src="{imagelocation}"> </div><div>{lastname}, {firstname}</div>

  2. Couldn't you just have a class that had a placeholder image as a background class in your tpl? Something like:

    Code:
    itemTpl: [
                '<div class="backgroundclass">List Item {string}</div>'
            ]
        }
    :-)

  3. #2
    Sencha User
    Join Date
    Aug 2011
    Location
    London
    Posts
    407
    Answers
    17
    Vote Rating
    18
    digeridoopoo will become famous soon enough

      0  

    Default Try this...

    Try this...


    I don't have my laptop and code to hand....but the way I did it was to have a class called loading image, something like this:

    Code:
    .loadingimage {
    background-image:url('loading.gif');
    background-color:#cccccc;
    }
    The image was a small spinning gif. Then I set this class as the background class on the component. The images loaded as normal images (not background images) so loaded ontop of the placeholder.

    I didn't do his with a list though but sure this would be possible?

    Also see here: http://www.sencha.com/forum/showthre...ading-spinnies

    :-)

  4. #3
    Sencha User bastard's Avatar
    Join Date
    Aug 2011
    Location
    I'm in Cali baby!
    Posts
    65
    Answers
    2
    Vote Rating
    4
    bastard is on a distinguished road

      0  

    Default Ext.Img

    Ext.Img


    There is a class called Ext.img which has all sorts of events for doing just this. The problem is I have no idea how to use it in a Ext.List.

  5. #4
    Sencha User
    Join Date
    Aug 2011
    Location
    London
    Posts
    407
    Answers
    17
    Vote Rating
    18
    digeridoopoo will become famous soon enough

      0  

    Default background class in tpl?

    background class in tpl?


    Couldn't you just have a class that had a placeholder image as a background class in your tpl? Something like:

    Code:
    itemTpl: [
                '<div class="backgroundclass">List Item {string}</div>'
            ]
        }
    :-)

  6. #5
    Sencha User bastard's Avatar
    Join Date
    Aug 2011
    Location
    I'm in Cali baby!
    Posts
    65
    Answers
    2
    Vote Rating
    4
    bastard is on a distinguished road

      0  

    Default


    This is what I have and it doesn't work. I get a grey border but the image inside the border don't get displayed.

    Code:
    <div class="photoframe"><img class="photo" src="{photo_url}" width="40" height="40"/></div>
    <div class="personinfo">{lastname}, {firstname}<br><small>{position}</small></div>
    Code:
    .photoframe{
        float: left;
        border: 1px solid #ccc;
        width: 40px;
        height: 40px;
        background-image: url('greyman.jpg');
        margin: 0px 15px;
    }
    
    
    .personinfo{
    	line-height: 100%;
        white-space: normal;
        display: inline-block;
            
    }

  7. #6
    Sencha User bastard's Avatar
    Join Date
    Aug 2011
    Location
    I'm in Cali baby!
    Posts
    65
    Answers
    2
    Vote Rating
    4
    bastard is on a distinguished road

      0  

    Default


    wait, nevermind! I had some whitespace issues! Your suggestion worked!

  8. #7
    Sencha User
    Join Date
    May 2011
    Location
    Melbourne, Australia
    Posts
    89
    Answers
    5
    Vote Rating
    7
    Greg Arnott is on a distinguished road

      1  

    Default


    Large application where sometimes you need a placeholder, the old trick is to define one:


    Code:
    Ext.BLANK_IMAGE_URL = './ext/resources/images/default/s.gif';



    This is something I use when I get sick of Architect nagging for an image src for one to be dynamically loaded, else set src : ''.


    Another method - which is perfect for images loaded from a slower call, such as AJAX profile data. An image with "mode: background" will create a div, and set the image to be the background. Set the div's class in the CSS to properties required, such as width and height of 40px in this case. The div operates as the placeholder structurally until the image loads. The best part is what you can do with the image's class through native CSS. background-size can be 'Xpx Ypx' as well as 2 very helpful keywords - cover and contain which keep the image in proportion; contain will grow/shrink until the entire image is visible, contained within the size of div (will create a letterbox effect in most cases), while cover fills the div cropping the longer dimension. "background-position: 50% 50%;" is useful in the latter case for positioning the image so edges are cropped evenly from both sides.


    Code:
    var image = new Ext.create('Ext.Img', {
       src     : null,
       mode : 'background',
       cls     : 'banner'
    });
    image.setSrc(this.getSrc());
    component.add(image); // ie component such as carousel, container etc.



    Equivalent to previous post template, yet showing a range of ways to populate template values, using native getter functions from config values, variables defined earlier in function, and possibly the data return from an AJAX call. NB: This formatting technique is mainly for singleton uses, such as profile info at top of a page, not lists.

    Code:
    // string.format method
    Code:
    var html = Ext.String.format({
        [
            '<div class="photoframe">',
            '<img src="{0}" class="{1}">',
            '<div class="personinfo">{2}<small>{3}</small></div>',
            '</div>'
        ].join(''),
        this.getSrc(),
        Ext.BaseCls + 'photo',
        data.lastname + ', ' + data.firstname,
        data.position
    });
    target.setHtml(html);
    
    // dynamic template method (better) using a multidimensional data source for example technique
    data: {
        profiles: [{
            photo_url: '/path/to/image.jpg', 
            name: {
                firstname: 'John',
                lastname : 'Smith',
                position : 'Manager'
            }
        }, { ... other profiles same structure...}]
    },
    
    tpl: Ext.create('Ext.XTemplate', '<tpl for="profiles">',
        '<div class="{#}-profile photoframe"><img src="{photo_url}" class="photo"></div>',
        '<div class="personinfo">{name:this.join}</div>',
        '</tpl>', {
        join: function(value) {
            return '<h4>' + name.lastname + ', ' + name.firstname + '</h4><span>' + name.position + '</span>';
        }
    
    
    


    The last technique, I've added a better method for the maintext (name) and subtext (position) structure, without using BR tag - Hx tags inherently clear to the right.

    If each one was going to be its own component, here is a format for creating using vbox for text layout and docking image to the left for layout.

    Code:
    Ext.define('App.view.PhotoGallery', {
        extend: 'Ext.Container',
        xtype: 'photogallery',
        config: {
            layout: {
                type: 'vbox'
            },
            cls   : 'photoframe',
            items : [{
                    xtype  : 'image',
                    cls    : 'photo',
                    mode   : 'background',
                    docked : 'left',
                    src    : null
                }, {
                    xtype  : 'component',
                    flex   : 1,
                    itemId : 'profilename',
                    html   : 'lastname, firstname' // filler text
                }, {
                    xtype  : 'component',
                    flex   : 1,
                    itemId : 'position',
                    html   : 'position' // filler text 
                }
            ]
        }
    });

Thread Participants: 2

Tags for this Thread