Search code examples
javascriptruby-on-railsextjsextjs4

Using the DataView Example to create a photo gallery


I am building a web application using ExtJS. In my web application, the users can upload photos to the server directory. In addition, I also save the file path to a database table along with the user id so I know whose photo a certain photo is. Naturally, I would also want them to be able to view it. I can fetch the database rows properly based on the logged in user. However, the difficulty I'm having right now concerns showing the user his or her photos.

Upon searching the web, I saw this example provided by Sencha. Upon looking at the code, it seemed simple enough to integrate to my existing application.

Upon examining the provided data-view.js file, I saw that it uses 2 plugins that were already provided in the ext/src/ux/ subdirectory so I saw no purpose in adding them and my app.js file looks like this:

requires: [
    'Ext.Loader',
    'Ext.layout.container.Absolute',
    'Ext.layout.container.Column',
    'Ext.grid.*',
    'Ext.ux.DataView.DragSelector',
    'Ext.ux.DataView.LabelEditor'
],

Now, I also have my own model and my own store.

My model looks like:

Ext.define('app.model.ciGallery', {
extend: 'Ext.data.Model',

requires: [
    'Ext.data.Field'
],

fields: [
    {
        name: 'image_path'
    },
    {
        name: 'description'
    },
    {
        name: 'upload_date'
    },
    {
        name: 'upload_time'
    }
]
});

And my store looks like a standard store used to do CRUD on database.

Now, in order to create the photo gallery example, what I did was to get the panel where I want the gallery to appear on and made a function for its afterrender property. In that after render function, what I basically did was to copy paste the entire example starting from Ext.create(....

It looks like this:

var store = Ext.getStore("ciGallery");

Ext.create('Ext.Panel', {
    id: 'images-view',
    frame: true,
    collapsible: true,
    width: 200,
    renderTo: 'dataview-example',
    title: 'Simple DataView (0 items selected)',
    items: Ext.create('Ext.view.View', {
        store: store,
        tpl: [
            '<tpl for=".">',
            '<div class="thumb-wrap" id="{name}">',
            '<div class="thumb"><img src="{url}" title="{name}"></div>',
            '<span class="x-editable">{shortName}</span></div>',
            '</tpl>',
            '<div class="x-clear"></div>'
        ],
        multiSelect: true,
        height: 310,
        trackOver: true,
        overItemCls: 'x-item-over',
        itemSelector: 'div.thumb-wrap',
        emptyText: 'No images to display',
        plugins: [
            Ext.create('Ext.ux.DataView.DragSelector', {}),
            Ext.create('Ext.ux.DataView.LabelEditor', {dataIndex: 'name'})
        ],

        prepareData: function(data) {
            Ext.apply(data, {
                shortName: Ext.util.Format.ellipsis(data.image_path, 15),
                sizeString: Ext.util.Format.fileSize(data.upload_date),
                dateString: Ext.util.Format.date(data.upload_time)
            });
            return data;
        },

        listeners: {
            selectionchange: function(dv, nodes ){
                var l = nodes.length,
                    s = l !== 1 ? 's' : '';
                this.up('panel').setTitle('Simple DataView (' + l + ' item' + s + ' selected)');
            }
        }
    })
});

Where ciGallery is my store, dataview-example is the id property of the parent panel, as well as adjustments to the prepareData function to match the properties of the model I use.

However, when I run my application and go to that panel, it seems like nothing rendered properly because I don't see anything, not even a blank panel.


Solution

  • Okay. Here's what I did. The View and Panel components are readily available at Sencha Architect. I just added them onto the panel where I want the gallery to be in, and then set as much properties I can from the example to the components. I think the only thing I didn't use was the renderTo property of the View in the example.

    Now, when you make your View, you have to adjust the tpl code as well as the prepareData function to match your model that your store use. Here's what I did with my tpl:

    tpl: [
        '<tpl for=".">',
        '<div class="thumb"><img src="{image_path}"></div>',
        '</tpl>',
        '<div class="x-clear"></div>',
        ''
    ]
    

    I went with a simple image gallery, contrary to what the sample showed (it had file names). To achieve that, I simply removed the other div and span objects.