Lotus Image Gallery

Here's an example of lotus ImageGalleryCollectionView component. The x-lotus-image-gallery tag extends the Lotus.LotusHTMLElement tag. Our x-lotus-image-gallery is also mapped to a Lotus component in the call to context.componentMap.mapComponent('x-lotus-image-gallery', Lotus.LotusHTMLElement.prototype, Lotus.ImageGalleryCollectionView, xtag);.A new instance of Lotus.ImageGalleryCollectionView is attached to each tag instance. The component implements pagination by extending Lotus.AbstractRecordSetCollectionView. This component is designed to work with Lavender.RecordSet object and can have data lazy loaded into it's result set as results are fetched from a service. The lotusjs-mvw sample application includes a mock service and functional example of lazy loading data to support pagination.

Dynamically Change Skin

If your browser does not natively support web component (Safari) you will not see any change. See the xTag polyfill workaround below.

Changing the appearance of any image control instance is as simple as attaching a different skin using data-template-url="templates/imageGallery2.html". Below is the exact same custom set of tags with a different skin attached. All using the same set of selectors encapsulated with Shadow DOM. Imagine how many skins could be created without a single change to the component code.

xTag Pollyfill Workaround

Note: If your browser does not natively support web components you have to attach the new skin using a different tag. In this example we do the following: context.componentMap.mapComponent('x-lotus-image-gallery2', Lotus.LotusHTMLElement.prototype, Lotus.ImageGalleryCollectionView, xtag);. This is an issue with the xTag core and how it encapsulates styles using the tag name.

Mediating Components

The x-lotus-image-gallery tag exposes a single change event by default. In order to listen for that event you have to assign an event handler after the document loads. An example is below. However if you are serious about event mediation of we encourage you to check out lotusjs-mvw. This is a full blown MVW framework which comes with a mediator map for your components (and much more). This allows you to build application mediators that are mapped to your custom tags. Mediators can do all sorts of useful things like triggering business logic, dispatching application events to trigger commands, and setting up data binding within your surrounding application.

		
        var context = (function (xtag) {
            var context = new Lotus.Context(new Lavender.Config);
            context.componentMap.mapComponent('x-lotus-image-gallery', Lotus.LotusHTMLElement.prototype, Lotus.ImageGalleryCollectionView, xtag);
            context.componentMap.mapComponent('x-lotus-gallery-detail', Lotus.LotusHTMLElement.prototype, Lotus.ImageGalleryItemDetail, xtag);
            context.componentMap.mapComponent('x-lotus-image-gallery2', Lotus.LotusHTMLElement.prototype, Lotus.ImageGalleryCollectionView, xtag);
            return context;
        }(xtag));
        //Set up the sample data for the image gallery. Normally this would be loaded from a service.
        var json = JSON.parse('{"photos": [' +
                '{"id":"5464022a4e696302aa000000","url":"assets/photos/Sunset_2007-1.jpg","created_date":"2014-11-13","last_access_date":"2014-11-13", "source":"sampleAPI"},' +
                '{"id":"5464096b4e696303b2000000","url":"assets/photos/Sunset-socialphy.com_.jpg","created_date":"2014-11-13","last_access_date":"2014-11-13", "source":"sampleAPI"},' +
                '{"id":"5464096b4e696303b2000000","url":"assets/photos/sunset-birds1.jpg","created_date":"2014-11-13","last_access_date":"2014-11-13", "source":"sampleAPI"},' +
                '{"id":"5464096b4e696303b2000000","url":"assets/photos/62299_482695931808833_1546636354_n.jpg","created_date":"2017-11-15","last_access_date":"2017-11-23", "source":"sampleAPI"},' +
                '{"id":"5464096b4e696303b2000000","url":"assets/photos/408617_10200464782808570_96994658_n.jpg","created_date":"2017-11-12","last_access_date":"2017-11-30", "source":"sampleAPI"},' +
                '{"id":"5464096b4e696303b2000000","url":"assets/photos/1008582_10151493940252133_1002588658_o.jpg","created_date":"2017-12-12","last_access_date":"2017-12-30", "source":"sampleAPI"},' +
                '{"id":"5464096b4e696303b2000000","url":"assets/photos/FullMoon2010.jpg","created_date":"2014-11-13","last_access_date":"2014-11-13", "source":"sampleAPI"}]}');
        //Create the asset list, this is just a crude example of data abstraction
        var assets = [];
        for( var i=0; i < json.photos.length; i++ ){
            var asset = {};
            asset.id = json.photos[i].id;
            asset.url = json.photos[i].url;
            asset.thumbUrl = json.photos[i].url;//the api does not expose thumbnails to we just use the full size
            asset.createdDate = new Date(json.photos[i].created_date);
            asset.source = json.photos[i].source;
            asset.lastAccessDate = json.photos[i].last_access_date;
            asset.objectName = asset.url.substr(asset.url.lastIndexOf('/')+1);
            assets.push({addItemAt:i, item:asset});
        }
        assets.totalRecords = json.photos.length;
        //define our handler to set up the component when it loads.
        //Note you can avoid this if you use https://www.npmjs.com/package/lotusjs-mvw and take advantage of component mediators
        //mediators are attached to component instances at the moment of creation and receive callbacks for the ready evet automatially
        var handler={
            onReady:function(event){
                handler.initComponent(event.payload.target);
            },
            initComponent:function(component){
                //The image gallery component uses a recordset to page through data
                var recordSet = new Lavender.RecordSet(NaN, Lavender.ArrayList);
                recordSet.createdOn = new Date();
                recordSet.id = Lavender.UuidUtils.generateUUID();
                recordSet.recordsPerPage = 3;
                recordSet.results.allowDuplicates = true;
                recordSet.source = 'testSource';
                recordSet.totalRecords = assets.totalRecords;
                recordSet.results.addAll(assets, true);
                component.recordSet = recordSet;
                component.recordSet.selectedPage = 1;
            },
            addEventListeners:function (component) {
                //the lotus syntax for addEventListener is slightly different than that of DOM elements,
                //but it ensures the scope of this within a callback is always relative the the second parameter which is the object instance
                component.addEventListener(Lotus.InputEvent.CHANGE, handler, 'onChange');
                //Do not set up data providers until the component is ready!
                //if you use lotusjs-mvw you can take advantage of component mediators that have built in onReady callbacks
                if(!component.ready){
                    component.addEventListener(Lotus.ComponentEvent.READY, handler, 'onReady')
                }else{
                    handler.initComponent(component)
                }
            }
        }
        //the following is an example of how you can mediate the component events that are dispatched.
        //A better alternative is to use https://www.npmjs.com/package/lotusjs-mvw and take advantage of component mediators
        window.onload = function () {
            hljs.initHighlighting();
            var list = document.getElementsByTagName('x-lotus-image-gallery');
            for (var i = 0; i < list.length; i++) {
                handler.addEventListeners(list[i].lotusComponentInstance);
            }
            //set up work around for pollyfill issue with xTag core
            list = document.getElementsByTagName('x-lotus-image-gallery2');
            for (var i = 0; i < list.length; i++) {
                handler.addEventListeners(list[i].lotusComponentInstance);
            }
        };