Bootstrap Carousel breaking on Variant Images only

  • Posts: 303
  • Thank you received: 18
7 years 7 months ago #278303

-- url of the page with the problem -- : www.mojooutdoors.com/index.php/spinning-...by-mojo-drake-or-hen
-- HikaShop version -- : 2.6.3
-- Joomla version -- : 3.6

Very odd problem with the display of product images if the product contains variants. I have implemented a simple bootstrap carousel that only display on mobile. Works fine for every product that doesn't contain a variant. For example: www.mojooutdoors.com/index.php/products/new-products

However, there seems to be some issue with products that contain variants. (1) the images won't display properly in the carousel and (2) the images are duplicated and displayed at the bottom of the page. For example: www.mojooutdoors.com/index.php/spinning-...by-mojo-drake-or-hen

For the carousel, i just duplicated the code in product/show_block_img (which is probably the issue):

<div id="carousel-example-generic" class="carousel slide hidden-desktop" data-ride="carousel">
  <!-- Indicators -->
  <ol class="carousel-indicators" style="visibility:hidden;">
    <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
    <li data-target="#carousel-example-generic" data-slide-to="1"></li>
    <li data-target="#carousel-example-generic" data-slide-to="2"></li>
  </ol>

  <!-- Wrapper for slides -->
  <div class="carousel-inner" role="listbox">
   
  <div class="item active">
  
    <?php
			if(!empty ($this->element->images)){
				$image = reset($this->element->images);
			}
			$height = (int)$this->config->get('product_image_y');
			$width = (int)$this->config->get('product_image_x');
			if(empty($height)) $height = (int)$this->config->get('thumbnail_y');
			if(empty($width)) $width = (int)$this->config->get('thumbnail_x');
			$divWidth = $width;
			$divHeight = $height;
			$this->image->checkSize($divWidth,$divHeight,$image);

			if (!$this->config->get('thumbnail')) {
				if(!empty ($this->element->images)){
					echo '<img src="' . $this->image->uploadFolder_url . $image->file_path . '" alt="' . $image->file_name . '" id="hikashop_main_image" class="JMProductImgMain" style="vertical-align:middle" />';
				}
			} else {
				$style = '';
				if (!empty ($this->element->images) && count($this->element->images) > 1) {
					if (!empty($height)) {
						$style = ' style="height:' . ($height + 20) . 'px;"';
					}
				}
				$variant_name='';
				if(isset($this->variant_name)){
					$variant_name=$this->variant_name;
				}

				?>

				<div class="hikashop_product_main_image_thumb" id="hikashop_image_main_thumb_div<?php echo $variant_name;?>" <?php echo $style;?> >
					<div style="<?php if(!empty($divHeight)){ echo 'height:'.($divHeight+20).'px;'; } ?>text-align:center;clear:both;" class="hikashop_product_main_image">
						<div style="position:relative;text-align:center;clear:both;<?php if(!empty($divWidth)){ echo 'width:'.$divWidth.'px;'; } ?>margin: auto; max-width:100%;" class="hikashop_product_main_image_subdiv">
						<?php
							if($this->image->override) {
								echo $this->image->display(@$image->file_path,true,@$image->file_name,'id="hikashop_main_image'.$variant_name.'" class="JMProductImgMain" style="margin-top:10px;margin-bottom:10px;display:inline-block;vertical-align:middle"','id="hikashop_main_image_link"', $width,  $height);
							} else {
								if(empty($this->popup))
									$this->popup = hikashop_get('helper.popup');
								$image_options = array('default' => true);
								$img = $this->image->getThumbnail(@$image->file_path, array('width' => $width, 'height' => $height), $image_options);
								if($img->success) {
									$attr = '';
									if (!empty ($this->element->images) && count($this->element->images) > 1) {
										$attr = 'onclick="return window.localPage.openImage(\'hikashop_main_image\');"';
									}
									$html = '<img id="hikashop_main_image'.$variant_name.'" class="JMProductImgMain" style="vertical-align:middle" title="'.$this->escape(@$image->file_description).'" alt="'.$this->escape(@$image->file_name).'" src="'.$img->url.'"/>';
									if(!empty($this->element->badges))
										$html .= $this->classbadge->placeBadges($this->image, $this->element->badges, '0', '0',false);

									echo $this->popup->image($html, $img->origin_url, null, $attr);
								}
							}
						?>
						</div>
					</div>
				</div>
			<?php
			}
			?>
    
    
  </div>

However, it's very strange it works for most all product pages, except the ones with variants. Also, there are no errors that show in the chrome inspector console?

Ideally, i would like to pull the first image and put it in a separate div than the remaining images. With the carousel, i must declare one of them the "item active" and the subsequent images are just "tem" in the carousel.

Maybe there's a more elegant way to call the images (even for variants)?? Any help would be greatly appreciated!

Please Log in or Create an account to join the conversation.

  • Posts: 26226
  • Thank you received: 4035
  • MODERATOR
7 years 7 months ago #278346

Hello,

You should not specify specific images for your variants.
Otherwise, HikaShop will pre-generate the content for each variant and it perform some JS actions when you change the characteristics in order to push the select content in the product page (product name, prices, images, etc).
Because that content is pushed, all the Javascript that you place in these "blocks" will not be processed (unless you add some extra code to perform the re-initialization of your content after the update of the blocks).

Regards,


Jerome - Obsidev.com
HikaMarket & HikaSerial developer / HikaShop core dev team.

Also helping the HikaShop support team when having some time or couldn't sleep.
By the way, do not send me private message, use the "contact us" form instead.

Please Log in or Create an account to join the conversation.

  • Posts: 303
  • Thank you received: 18
7 years 7 months ago #278384

Hi Jerome,

I removed the images from the variants. The carousel still exhibits this strange behavior (doesn't show other images and carousel is being duplicated at the bottom of the page). Is the problem specifically because i have product variants?

How should i reinitialize the JS within this view file?

Please Log in or Create an account to join the conversation.

  • Posts: 303
  • Thank you received: 18
7 years 7 months ago #278404

I guess the better question is how can I load all of the images outside of this file? For example, I can just put this carousel inside show_default but I'm not sure how to pull the images one by one. Should be simple to do with php? Don't really need the variant images and have even removed them.

Also, I need to count the total number of images as well.

Please Log in or Create an account to join the conversation.

  • Posts: 26226
  • Thank you received: 4035
  • MODERATOR
7 years 7 months ago #278388

Hello,

If you have the carousel still display at the bottom of the page ; it means that you have one variant with images.
Just take a look at the view "product / show" and you will see the code which process the variant data for the different parts of the products (cf previous message) while the main data of the product page is in the layout (show_default or show_tabular...)

Regards,


Jerome - Obsidev.com
HikaMarket & HikaSerial developer / HikaShop core dev team.

Also helping the HikaShop support team when having some time or couldn't sleep.
By the way, do not send me private message, use the "contact us" form instead.

Please Log in or Create an account to join the conversation.

  • Posts: 303
  • Thank you received: 18
7 years 7 months ago #278497

I understand this. I have two variants for this product. Only the main product page has images. There are NO images set to the variants (see screenshots).



Something else is breaking this carousel? Or the carousel is breaking hika?

Attachments:

Please Log in or Create an account to join the conversation.

  • Posts: 83671
  • Thank you received: 13542
  • MODERATOR
7 years 7 months ago #278512

Hi,

If you don't have any image in the variants, then you should just remove the piece handling the display of the images of the variants in the product / show.php view file:

$this->setLayout('show_block_img');
		echo $this->loadTemplate();

Please Log in or Create an account to join the conversation.

  • Posts: 303
  • Thank you received: 18
7 years 7 months ago #278559

That worked for removing the duplicate carousel. HOWEVER, there is still only one image showing in the carousel, even though there are two images assigned to the main product. Again, this works fine on products without variants. The images are loading properly on the desktop version (no carousel), but just not on the mobile carousel. Any ideas?

Please Log in or Create an account to join the conversation.

  • Posts: 83671
  • Thank you received: 13542
  • MODERATOR
7 years 7 months ago #278560

Hi,

If you look at the HTML of the page in a small window with your browser's developer tool, you can see that the width of the image is set at 0px: monosnap.com/file/xoHBZwscU7Qe0C3EOfRSlGosa7FAk4
That's your problem.
If you deactivate that with for example:
.hikashop_main_image{ width: auto !important; }
it will display.

Please Log in or Create an account to join the conversation.

  • Posts: 303
  • Thank you received: 18
7 years 7 months ago #278594

Unfortunately that's not the issue. That is a consequence of changing from desktop to mobile display through the developer tools of your browser. With mobile version turned on, refresh the page and it displays the carousel. See screenshot below:



However, still there is only one image showing in the carousel instead of the 2 that are set for that product. Again, works properly on all other page except those with variants.

Attachments:

Please Log in or Create an account to join the conversation.

  • Posts: 83671
  • Thank you received: 13542
  • MODERATOR
7 years 7 months ago #278624

Hi,

Well, I don't know.
The code you provided in your first message is only for the main image of the product, not for the other images.
If you needed it to work for several images, you would have to have a foreach on $this->element->images or something like that.
So either you didn't provide all the code modifications or your code works the same for products with variants and products without: it only display the main image in the carousel and not the others.

Please Log in or Create an account to join the conversation.

  • Posts: 303
  • Thank you received: 18
7 years 7 months ago #278694

Here is the full code for the display file "show_block_img":

<?php
/**
 * @package	HikaShop for Joomla!
 * @version	2.6.1
 * @author	hikashop.com
 * @copyright	(C) 2010-2016 HIKARI SOFTWARE. All rights reserved.
 * @license	GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
 */
defined('_JEXEC') or die('Restricted access');
?><?php
$variant_name = '';
$variant_main = '_main';
$display_mode = '';
if(!empty($this->variant_name)) {
	$variant_name = $this->variant_name;
	if(substr($variant_name, 0, 1) != '_')
		$variant_name = '_' . $variant_name;
	$variant_main = $variant_name;
	$display_mode = 'display:none;';
}
?>
<div id="hikashop_product_image<?php echo $variant_main;?>" class="show_block_img row-fluid hikashop_global_image_div hidden-phone hidden-tablet" style="<?php echo $display_mode;?>">
	<div id="hikashop_small_image_div<?php echo $variant_name;?>" class="JMProductThumbImg span2 hidden-phone hidden-tablet">
      <?php if (count($this->element->images) == 1) { ?> &nbsp; <?php }?>
		<?php
			if (!empty ($this->element->images) && count($this->element->images) > 1) {
				$firstThunb = true;
				foreach ($this->element->images as $image) {
					if($this->image->override) {
						echo $this->image->display($image->file_path, 'hikashop_main_image'.$variant_name, $image->file_name, 'class="JMProductImgList"','', $width,  $height);
					} else {
						if(empty($this->popup))
							$this->popup = hikashop_get('helper.popup');
						$img = $this->image->getThumbnail(@$image->file_path, array('width' => $width, 'height' => $height), $image_options);
						if($img->success) {
							$id = null;
							if($firstThunb) {
								$id = 'hikashop_first_thumbnail';
								$firstThunb = false;
							}
							$attr = 'class="" onmouseover="return window.localPage.changeImage(this, \'hikashop_main_image'.$variant_name.'\', \''.$img->url.'\', '.$img->width.', '.$img->height.', \''.@$image->file_description.'\', \''.@$image->file_name.'\');"';
							$html = '<img class="JMProductImgList" title="'.$this->escape(@$image->file_description).'" alt="'.$this->escape(@$image->file_name).'" src="'.$img->url.'"/>';
							echo $this->popup->image($html, $img->origin_url, $id, $attr, array('gallery' => 'hikashop_main_image'.$variant_name));
						}
					}
				}
			}

			?>
		</div>
  
  
  
  
  
  <div id="hikashop_main_image_div<?php echo $variant_name;?>" class="JMProductMainImg span10">
		<?php
			if(!empty ($this->element->images)){
				$image = reset($this->element->images);
			}
			$height = (int)$this->config->get('product_image_y');
			$width = (int)$this->config->get('product_image_x');
			if(empty($height)) $height = (int)$this->config->get('thumbnail_y');
			if(empty($width)) $width = (int)$this->config->get('thumbnail_x');
			$divWidth = $width;
			$divHeight = $height;
			$this->image->checkSize($divWidth,$divHeight,$image);

			if (!$this->config->get('thumbnail')) {
				if(!empty ($this->element->images)){
					echo '<img src="' . $this->image->uploadFolder_url . $image->file_path . '" alt="' . $image->file_name . '" id="hikashop_main_image" class="JMProductImgMain" style="vertical-align:middle" />';
				}
			} else {
				$style = '';
				if (!empty ($this->element->images) && count($this->element->images) > 1) {
					if (!empty($height)) {
						$style = ' style="height:' . ($height + 20) . 'px;"';
					}
				}
				$variant_name='';
				if(isset($this->variant_name)){
					$variant_name=$this->variant_name;
				}

				?>

				<div class="hikashop_product_main_image_thumb" id="hikashop_image_main_thumb_div<?php echo $variant_name;?>" <?php echo $style;?> >
					<div style="<?php if(!empty($divHeight)){ echo 'height:'.($divHeight+20).'px;'; } ?>text-align:center;clear:both;" class="hikashop_product_main_image">
						<div style="position:relative;text-align:center;clear:both;<?php if(!empty($divWidth)){ echo 'width:'.$divWidth.'px;'; } ?>margin: auto; max-width:100%;" class="hikashop_product_main_image_subdiv">
						<?php
							if($this->image->override) {
								echo $this->image->display(@$image->file_path,true,@$image->file_name,'id="hikashop_main_image'.$variant_name.'" class="JMProductImgMain" style="margin-top:10px;margin-bottom:10px;display:inline-block;vertical-align:middle"','id="hikashop_main_image_link"', $width,  $height);
							} else {
								if(empty($this->popup))
									$this->popup = hikashop_get('helper.popup');
								$image_options = array('default' => true);
								$img = $this->image->getThumbnail(@$image->file_path, array('width' => $width, 'height' => $height), $image_options);
								if($img->success) {
									$attr = '';
									if (!empty ($this->element->images) && count($this->element->images) > 1) {
										$attr = 'onclick="return window.localPage.openImage(\'hikashop_main_image\');"';
									}
									$html = '<img id="hikashop_main_image'.$variant_name.'" class="JMProductImgMain" style="vertical-align:middle" title="'.$this->escape(@$image->file_description).'" alt="'.$this->escape(@$image->file_name).'" src="'.$img->url.'"/>';
									if(!empty($this->element->badges))
										$html .= $this->classbadge->placeBadges($this->image, $this->element->badges, '0', '0',false);

									echo $this->popup->image($html, $img->origin_url, null, $attr);
								}
							}
						?>
						</div>
					</div>
				</div>
			<?php
			}
			?>
			</div>



</div>


<div id="carousel-example-generic" class="carousel slide hidden-desktop" data-ride="carousel">
  <!-- Indicators -->
  <ol class="carousel-indicators" style="visibility:hidden;">
    <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
    <li data-target="#carousel-example-generic" data-slide-to="1"></li>
    <li data-target="#carousel-example-generic" data-slide-to="2"></li>
  </ol>

  <!-- Wrapper for slides -->
  <div class="carousel-inner" role="listbox">
   
  <div class="item active">
  
    <?php
			if(!empty ($this->element->images)){
				$image = reset($this->element->images);
			}
			$height = (int)$this->config->get('product_image_y');
			$width = (int)$this->config->get('product_image_x');
			if(empty($height)) $height = (int)$this->config->get('thumbnail_y');
			if(empty($width)) $width = (int)$this->config->get('thumbnail_x');
			$divWidth = $width;
			$divHeight = $height;
			$this->image->checkSize($divWidth,$divHeight,$image);

			if (!$this->config->get('thumbnail')) {
				if(!empty ($this->element->images)){
					echo '<img src="' . $this->image->uploadFolder_url . $image->file_path . '" alt="' . $image->file_name . '" id="hikashop_main_image" class="JMProductImgMain" style="vertical-align:middle" />';
				}
			} else {
				$style = '';
				if (!empty ($this->element->images) && count($this->element->images) > 1) {
					if (!empty($height)) {
						$style = ' style="height:' . ($height + 20) . 'px;"';
					}
				}
				$variant_name='';
				if(isset($this->variant_name)){
					$variant_name=$this->variant_name;
				}

				?>

				<div class="hikashop_product_main_image_thumb" id="hikashop_image_main_thumb_div<?php echo $variant_name;?>" <?php echo $style;?> >
					<div style="<?php if(!empty($divHeight)){ echo 'height:'.($divHeight+20).'px;'; } ?>text-align:center;clear:both;" class="hikashop_product_main_image">
						<div style="position:relative;text-align:center;clear:both;<?php if(!empty($divWidth)){ echo 'width:'.$divWidth.'px;'; } ?>margin: auto; max-width:100%;" class="hikashop_product_main_image_subdiv">
						<?php
							if($this->image->override) {
								echo $this->image->display(@$image->file_path,true,@$image->file_name,'id="hikashop_main_image'.$variant_name.'" class="JMProductImgMain" style="margin-top:10px;margin-bottom:10px;display:inline-block;vertical-align:middle"','id="hikashop_main_image_link"', $width,  $height);
							} else {
								if(empty($this->popup))
									$this->popup = hikashop_get('helper.popup');
								$image_options = array('default' => true);
								$img = $this->image->getThumbnail(@$image->file_path, array('width' => $width, 'height' => $height), $image_options);
								if($img->success) {
									$attr = '';
									if (!empty ($this->element->images) && count($this->element->images) > 1) {
										$attr = 'onclick="return window.localPage.openImage(\'hikashop_main_image\');"';
									}
									$html = '<img id="hikashop_main_image'.$variant_name.'" class="JMProductImgMain" style="vertical-align:middle" title="'.$this->escape(@$image->file_description).'" alt="'.$this->escape(@$image->file_name).'" src="'.$img->url.'"/>';
									if(!empty($this->element->badges))
										$html .= $this->classbadge->placeBadges($this->image, $this->element->badges, '0', '0',false);

									echo $this->popup->image($html, $img->origin_url, null, $attr);
								}
							}
						?>
						</div>
					</div>
				</div>
			<?php
			}
			?>
    
    
  </div>  
    
    
    
    
    

    
      
      <?php
		if (!empty ($this->element->images) && count($this->element->images) > 2) {
				$firstThunb = true;
                $thumbs = $this->element->images;
                array_shift($thumbs);
                foreach($thumbs as $image){

						if(empty($this->popup))
							$this->popup = hikashop_get('helper.popup');
						$img = $this->image->getThumbnail(@$image->file_path, array('width' => $width, 'height' => $height), $image_options);
						if($img->success) {
							$id = null;

							if($firstThunb) {
								$id = 'hikashop_first_thumbnail';
								$firstThunb = true;							}


							$attr = 'class="item"';
							$html = '<img class="JMProductImgList" title="'.$this->escape(@$image->file_description).'" alt="'.$this->escape(@$image->file_name).'" src="'.$img->url.'"/>';
							echo $this->popup->image($html, $img->origin_url, $id, $attr, array('gallery' => 'hikashop_main_image'.$variant_name));
						}
					
				}
			}

		?>
      

  
  </div>

  <!-- Controls -->
  <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
    <span class="fa fa-angle-left glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
    <span class="fa fa-angle-right glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>






<script type="text/javascript">
if(!window.localPage)
	window.localPage = {};
if(!window.localPage.images)
	window.localPage.images = {};
window.localPage.changeImage = function(el, id, url, width, height, title, alt) {
	var d = document, target = d.getElementById(id);
	if(!target) return false;
	target.src = url;
	target.width = width;
	target.height = height;
	target.title = title;
	target.alt = alt;
	window.localPage.images[id] = el;
	return false;
};
window.localPage.openImage = function(id) {
	if(!window.localPage.images[id])
		window.localPage.images[id] = document.getElementById('hikashop_first_thumbnail');
	window.localPage.images[id].click();
	return false;
};
</script>

The mobile carousel works for ALL products without variants and displays multiple pictures. For example, this one has no variants and 5 images: www.mojooutdoors.com/index.php/spinning-.../mojo-flockaflickers

On mobile, the carousel displays properly.

However, here is a product with variants and 2 images added to the main: www.mojooutdoors.com/index.php/spinning-...by-mojo-drake-or-hen

As you can see, the mobile carousel only displays 1 image instead of 2. This seems to be an issue with either (1) variants or (2) how i'm looping over images for the carousel.

However, it's strange that it will work for all products without variants though?

If there's an easier way to pull the images into the carousel, I'm open to suggestions.

Please Log in or Create an account to join the conversation.

  • Posts: 83671
  • Thank you received: 13542
  • MODERATOR
7 years 7 months ago #278709

Hi,

The error comes from that code:
if (!empty ($this->element->images) && count($this->element->images) > 2) {
It should be:
if (!empty ($this->element->images) && count($this->element->images) >= 2) {
Otherwise, when you have exactly 2 images in the product it won't add the second image, only the main one.
That's the same issue for products with and without variants.

The following user(s) said Thank You: mojooutdoors-holden

Please Log in or Create an account to join the conversation.

  • Posts: 303
  • Thank you received: 18
7 years 7 months ago #278732

That was exactly the issue! Didn't even notice that! Problem fixed across all product pages now.

Thanks for all of your help! Might be something to add to a patch of Hikashop for mobile display since Hika already has options for bootstrap? Lots of little tools that are prebuilt in bootstrap that might make the product display much more attractive to users who are looking for a more flexible frontend display.

Please Log in or Create an account to join the conversation.

  • Posts: 83671
  • Thank you received: 13542
  • MODERATOR
7 years 7 months ago #278756

Hi,

We actually want to get away from bootstrap because different templates use different versions of bootstrap and thus we can't make a generic solution. We had a lot of issues with that with HikaShop 2.x as it relied on bootstrap 2.x (like joomla 3) and many templates didn't include it.
So we'll definitely won't go with a bootstrap approach.
We actually embed our own carousel system with HikaShop 3.2.0 for the carousel system we're using on listing modules. So it could indeed be interesting to add it as an alternative on the product page.

The following user(s) said Thank You: mojooutdoors-holden

Please Log in or Create an account to join the conversation.

Time to create page: 0.106 seconds
Powered by Kunena Forum