Image gallery enhancement PDP

The PDP image gallery section is upgraded by adding the extra features mentioned below. 

  • The PDP’s main image have arrows to scroll the images. 
  • The main image is expanded and displayed on the popup when clicking on it. 
  • The main image shown on the website will be from the item record field “LARGE IMAGE 0”. 
  • For slider, the images need to be displayed from the fields ALTIMAGE1, ALTIMAGE2, etc. 
  • We need to be able to add additional images in the slider if needed. 

The customization is done by using an extension.

1.Entry pioint file

 var pdp = container.getComponent('PDP');                
                var sliderview
                if (pdp) {
                    pdp.on('afterShowContent', function () {
                        sliderview = new SliderView(container)
                        console.log('sliderview--1',sliderview)
                        _.defer(function () {
                            jQuery('.product-details-image-gallery').replaceWith(sliderview.render().$el.html());
                        });
                    });             
                };

2.View file

return Backbone.View.extend({


        template: jj_slider_slider_tpl,


        initialize: function (options) {
            this.view = options.getLayout().currentView;
            console.log("this.view",this.view)
            this.pdp = options.getComponent('PDP');
            this.item = this.pdp.getItemInfo();
            this.index = 0;
            Backbone.Events.off("showSliderModal");
            Backbone.Events.on("showSliderModal", this.showSliderModal, this);
            Backbone.Events.off("closeModelImage");
            Backbone.Events.on("closeModelImage", this.closeModelImage, this);
            var self = this;            
            var itemImageArray = [];
            this.fromNav = false;
            var showBadge = this.item.item.custitem_special;
            var badgeLabel = SC.CONFIGURATION.get('Badge.label');
            this.on("afterViewRender", function () {
                _.defer(function () {
                    if (!!showBadge) {
                        $('.product-details-image-gallery-block').append('<div class="ribbon ribbon-top-left"><span>' + badgeLabel + '</span></div>');
                    }
                })
            });
            this.images = this.view.model.getImages();
            var customFiedlsArray = SC.CONFIGURATION.get('Slidersubtab.items');
            var imageIdArray = customFiedlsArray.map(item => item.fieldid);
            imageIdArray.forEach(function (imageId) {
                var altImage = self.item.item ? self.item.item[imageId] : "";
                if (!!altImage) {
                    itemImageArray.push({ url: altImage, altimagetext: "" });
                }
            });
            if (itemImageArray.length > 0) {
                this.images = itemImageArray;
            }
            var data = self.item.options
            var itemoptionid = [];


            var option = _.each(_.where(data, {
                isMandatory: true
            }), function (line) {
                itemoptionid.push(line.itemOptionId)
            })


            //ON LOAD
            var imagesizes = _.filter(SC.ENVIRONMENT.siteSettings.imagesizes, function (value) {
                return value.name == "tinythumb"
            })[0].urlsuffix || ''
            if (this.item.item.itemoptions_detail.matrixtype) {
                let data = self.pdp.getSelectedMatrixChilds();
                let indexes = []
                _.each(self.images, function (line, index) {
                    if (line.url.includes(data[0].internalid)) {
                        indexes.push(index)
                    }
                })
                self.Onload = indexes
            }
            this.pdp.on('afterOptionSelection', function () {
                let data = self.pdp.getSelectedMatrixChilds();
                let imglist = []
                let trigger = false
                _.each(self.images, function (line) {
                    if (line.url.includes(data[0].internalid) && !trigger) {
                        imglist.push(line.url + '?' + imagesizes)
                        trigger = true
                    }
                })
                imglist = _.sortBy(imglist)
                if (!_.isEmpty(imglist)) {
                    self.triggerClick(imglist)
                }
            })


            function loadScript(url, callback) {
                var script = document.createElement("script")
                script.type = "text/javascript";
                if (script.readyState) { // only required for IE <9
                    script.onreadystatechange = function () {
                        if (script.readyState === "loaded" || script.readyState === "complete") {
                            script.onreadystatechange = null;
                            callback();
                        }
                    };
                } else {
                    script.onload = function () {                   
                        callback();
                    };
                }
                script.src = url;
                document.getElementsByTagName("head")[0].appendChild(script);
            }
            loadScript('https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/owl.carousel.min.js', function () {
                _.defer(function () {
                    var sync1 = $("#sync1");
                    var sync2 = $("#sync2");
                    var sync3 = $("#product-details-custom-slider");
                    var sync4 = $("#sync4");
                    var closeModal =  $("div#modal-slider-block");
                    var nomberOfSlides = SC.CONFIGURATION.get('Slidersubtab.noofslide');
                    var slidesPerPage = nomberOfSlides; //globaly define number of elements in slide


                    sync1.owlCarousel({
                        startPosition: self.index,
                        items: 1,
                        slideSpeed: 2000,
                        nav: true,
                        autoplay: false,
                        dots: false,
                        responsiveRefreshRate: 200,
                        navText: ['<a class="product-details-image-gallery-prev-icon" data-action="prev-image"></a>',
                            '<a class="product-details-image-gallery-next-icon" data-action="next-image"></a>'
                        ],
                    }).on('changed.owl.carousel', syncPosition);
                    sync4.owlCarousel({
                        startPosition: self.index,
                        items: 1,
                        slideSpeed: 2000,
                        nav: true,
                        autoplay: false,
                        dots: false,
                        responsiveRefreshRate: 200,
                        navText: ['<a class="product-details-image-gallery-prev-icon" data-action="prev-image"></a>',
                            '<a class="product-details-image-gallery-next-icon" data-action="next-image"></a>'
                        ],
                    }).on('changed.owl.carousel', syncPosition);


                    sync2.on('initialized.owl.carousel', function () {
                        sync2.find(".owl-item").eq(0).addClass("current");
                    }).owlCarousel({
                        startPosition: self.index,
                        items: slidesPerPage,
                        dots: false,
                        nav: true,
                        smartSpeed: 200,
                        slideSpeed: 500,
                        slideBy: slidesPerPage,
                        responsiveRefreshRate: 100
                    }).on('changed.owl.carousel', syncPosition2);
                    
                    function syncPosition(el) {
                        var current = el.item.index;
                        sync2.data('owl.carousel').to(current, 100, true);
                        sync2
                            .find(".owl-item")
                            .removeClass("current")
                            .eq(current)
                            .addClass("current");
                        self.fromNav = false
                    }
                    if (!_.isEmpty(self.Onload)) {
                        var load = self.Onload[0]
                        sync2
                            .find(".owl-item")
                            .removeClass("current")
                            .eq(load)
                            .addClass("current");
                        sync1.data('owl.carousel').to(load, 100, true);
                        self.Onload = []
                    }


                    function syncPosition2(el) {
                        self.fromNav = true
                        self.number = el.item.index;
                        $('#sync2 .owl-prev,#sync2 .owl-next').on("click", function (e) {
                            if (self.fromNav) {
                                e.preventDefault();
                                self.fromNav = false
                                sync2
                                    .find(".owl-item")
                                    .removeClass("current")
                                    .eq(self.number)
                                    .addClass("current");
                                sync1.data('owl.carousel').to(self.number, 100, true);  
                                sync4.data('owl.carousel').to(self.number, 100, true);                              
                            }
                        })
                    }
                    sync2.on("click", ".owl-item", function (e) {
                        e.preventDefault();
                        var number1 = $(this).index();
                        sync1.data('owl.carousel').to(number1, 300, true);
                        sync4.data('owl.carousel').to(number1, 300, true);
                    });
                    sync1.on("click", ".pdp-slider-item", function (e) {                    
                        Backbone.Events.trigger("showSliderModal", e);
                    });
                    sync3.on("click", ".product-details-image-gallery-detailed-image", function (e) {
                        Backbone.Events.trigger("showSliderModal", e);
                    });
                    closeModal.on("click", ".pdp-image-closeicon", function (e) {                    
                        Backbone.Events.trigger("closeModelImage", e);
                        e.preventDefault();
                        var number1 = $(this).index();
                        sync1.data('owl.carousel').to(number1, 300, true);                  
                    });
                })
            })


        },


        closeModelImage: function(e) {
            _.defer(function () {      
            $('#modal-slider-block').css('display', 'none');
            $('.site-search-input-icon').css('display', 'block');
            $('.site-search-content::before').css('display', 'block');
            })
        },


        showSliderModal: function (e) { 
            _.defer(function () {
            $('#modal-slider-block').css('display', 'block');
            $('.owl-carousel').css('display', 'block');
            $('.site-search-input-icon').css('display', 'none');
            $('.site-search-content::before').css('display', 'none');
            })                  
        },


        triggerClick: function triggerClick(imglist) {
            var sync1 = $("#sync1");
            var sync2 = $("#sync2");
            var url = imglist[0]
            self = this
            _.defer(function () {
                var index = jQuery('#sync2 img[src="' + url + '"]').parents('.owl-stage .owl-item').index()
                var selectedItem = jQuery('#sync2 .owl-item')[index]
                if (!_.isEmpty(sync1.data('owl.carousel'))) {
                    sync1.data('owl.carousel').to(index, 300, true);
                }
                sync2.data('owl.carousel').to(index, 100, true)
                sync2
                    .find(".owl-item")
                    .removeClass("current")
                    .eq(index)
                    .addClass("current");
            })
        },


        getContext: function getContext() {


            return {
                images: this.images,
                firstImage: this.images[0] || {},
                showImages: this.images.length > 0,
                showImageSlider: this.images.length > 1
            };
        }
    });

3.template file

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.carousel.min.css" />
<div class="pdp-image-slider" id="product-details-custom-slider">
  {{#if showImages}}
  {{#if showImageSlider}}
  <div class="owl-carousel owl-theme" id="sync1">
    {{#each images}}
    <div class="pdp-slider-item">
      <div class="product-details-image-gallery-detailed-image">
        <div class="image-wrapper">
          <a>
            <img src="{{resizeImage url 'slider'}}" alt="{{url}}" />
          </a>
        </div>
      </div>
    </div>
    {{/each}}
  </div>
  <div class="owl-carousel owl-theme " id="sync2">
    {{#each images}}
    <a href="{{fullurl}}">
      <div class="pdp-slider-item">
        <div class="image-wrapper">
          <img src="{{resizeImage url 'tinythumb'}}" alt="{{url}}" />
        </div>
      </div>
    </a>
    {{/each}}
  </div>
  {{else}}
  {{#with firstImage}}
  <div class="product-details-image-gallery-detailed-image">
    <img class="center-block" src="{{resizeImage url 'slider'}}" alt="{{altimagetext}}" itemprop="image"
      data-loader="false">
  </div>
  {{/with}}
  {{/if}}
  {{/if}}
</div>


<!-- modal data -->
<div id="modal-slider-block" class="pdp-image-modal" style="display: none;">
  <div class="pdp-image-slider" id="product-details-custom-slider">
    <a style="cursor: default;" data-action="image-close">
      <span class="pdp-image-closeicon" id="closeimage">×</span>
    </a>
    {{#if showImages}}
    {{#if showImageSlider}}
    <div class="owl-carousel owl-theme" id="sync4">
      {{#each images}}
      <div class="pdp-slider-item">
        <div class="modal-product-details-image-gallery-detailed-image">
          <div class="image-wrapper">
            <a>
              <img src="{{resizeImage url 'main'}}" alt="{{url}}" />
            </a>
          </div>
        </div>
      </div>
      {{/each}}
    </div>
    {{else}}
    {{#with firstImage}}
    <div class="modal-product-details-image-gallery-detailed-image">
      <img class="center-block" src="{{resizeImage url 'main'}}" alt="{{altimagetext}}" itemprop="image"
        data-loader="false">
    </div>
    {{/with}}
    {{/if}}
    {{/if}}
  </div>
</div>

Modal view

Leave a comment

Your email address will not be published. Required fields are marked *