Item Alternate Image Features in e-commerce site. (#15044)

* [ADD] Added Item Alternate Image Features in e-commerce site.

* [IMP] Improved Code for Item Alternate Image Feature.

* [IMP] Improved code for Item alternative image functionality.

* Remove .css file and make a build for erpnext-web.css

* Cleanup styling for item alternate image, also add delegated handler

* Spaces -> Tabs

* Spaces -> Tabs in item.html
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 999ece9..7bf948e 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -21,7 +21,7 @@
 app_include_js = "assets/js/erpnext.min.js"
 app_include_css = "assets/css/erpnext.css"
 web_include_js = "assets/js/erpnext-web.min.js"
-web_include_css = "assets/erpnext/css/website.css"
+web_include_css = "assets/css/erpnext-web.css"
 
 doctype_js = {
 	"Communication": "public/js/communication.js",
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index ed4ebab..75809ce 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -1,49 +1,52 @@
 {
-    "css/erpnext.css": [
-        "public/less/erpnext.less",
-        "public/less/hub.less"
-    ],
-    "js/erpnext-web.min.js": [
-        "public/js/website_utils.js",
-        "public/js/shopping_cart.js"
-    ],
-    "js/erpnext.min.js": [
-        "public/js/conf.js",
-        "public/js/utils.js",
-        "public/js/queries.js",
-        "public/js/sms_manager.js",
-        "public/js/utils/party.js",
-        "public/js/templates/address_list.html",
-        "public/js/templates/contact_list.html",
-        "public/js/controllers/stock_controller.js",
-        "public/js/payment/payments.js",
-        "public/js/controllers/taxes_and_totals.js",
-        "public/js/controllers/transaction.js",
-        "public/js/pos/pos.html",
-        "public/js/pos/pos_bill_item.html",
-        "public/js/pos/pos_bill_item_new.html",
-        "public/js/pos/pos_selected_item.html",
-        "public/js/pos/pos_item.html",
-        "public/js/pos/pos_tax_row.html",
-        "public/js/pos/customer_toolbar.html",
-        "public/js/pos/pos_invoice_list.html",
-        "public/js/payment/pos_payment.html",
-        "public/js/payment/payment_details.html",
-        "public/js/templates/item_selector.html",
-				"public/js/templates/employees_to_mark_attendance.html",
-        "public/js/utils/item_selector.js",
-        "public/js/help_links.js",
-        "public/js/agriculture/ternary_plot.js",
-        "public/js/templates/item_quick_entry.html",
-        "public/js/utils/item_quick_entry.js",
-	"public/js/utils/customer_quick_entry.js",
-        "public/js/education/student_button.html",
-        "public/js/education/assessment_result_tool.html",
-        "public/js/hub/hub_factory.js"
-    ],
-    "js/item-dashboard.min.js": [
-        "stock/dashboard/item_dashboard.html",
-        "stock/dashboard/item_dashboard_list.html",
-        "stock/dashboard/item_dashboard.js"
-    ]
+	"css/erpnext.css": [
+		"public/less/erpnext.less",
+		"public/less/hub.less"
+	],
+	"js/erpnext-web.min.js": [
+		"public/js/website_utils.js",
+		"public/js/shopping_cart.js"
+	],
+	"css/erpnext-web.css": [
+		"public/less/website.less"
+	],
+	"js/erpnext.min.js": [
+		"public/js/conf.js",
+		"public/js/utils.js",
+		"public/js/queries.js",
+		"public/js/sms_manager.js",
+		"public/js/utils/party.js",
+		"public/js/templates/address_list.html",
+		"public/js/templates/contact_list.html",
+		"public/js/controllers/stock_controller.js",
+		"public/js/payment/payments.js",
+		"public/js/controllers/taxes_and_totals.js",
+		"public/js/controllers/transaction.js",
+		"public/js/pos/pos.html",
+		"public/js/pos/pos_bill_item.html",
+		"public/js/pos/pos_bill_item_new.html",
+		"public/js/pos/pos_selected_item.html",
+		"public/js/pos/pos_item.html",
+		"public/js/pos/pos_tax_row.html",
+		"public/js/pos/customer_toolbar.html",
+		"public/js/pos/pos_invoice_list.html",
+		"public/js/payment/pos_payment.html",
+		"public/js/payment/payment_details.html",
+		"public/js/templates/item_selector.html",
+		"public/js/templates/employees_to_mark_attendance.html",
+		"public/js/utils/item_selector.js",
+		"public/js/help_links.js",
+		"public/js/agriculture/ternary_plot.js",
+		"public/js/templates/item_quick_entry.html",
+		"public/js/utils/item_quick_entry.js",
+		"public/js/utils/customer_quick_entry.js",
+		"public/js/education/student_button.html",
+		"public/js/education/assessment_result_tool.html",
+		"public/js/hub/hub_factory.js"
+	],
+	"js/item-dashboard.min.js": [
+		"stock/dashboard/item_dashboard.html",
+		"stock/dashboard/item_dashboard_list.html",
+		"stock/dashboard/item_dashboard.js"
+	]
 }
diff --git a/erpnext/public/css/website.css b/erpnext/public/css/website.css
deleted file mode 100644
index 9ac9aac..0000000
--- a/erpnext/public/css/website.css
+++ /dev/null
@@ -1,270 +0,0 @@
-.web-long-description {
-  font-size: 18px;
-  line-height: 200%;
-}
-.web-page-content {
-  margin-bottom: 30px;
-}
-.item-stock {
-  margin-bottom: 10px !important;
-}
-.product-link {
-  display: block;
-  text-align: center;
-}
-@media (max-width: 767px) {
-  .product-image {
-    height: 0px;
-    padding: 0px 0px 100%;
-    overflow: hidden;
-  }
-}
-.product-image-square {
-  width: 100%;
-  height: 0;
-  padding: 50% 0px;
-  background-size: cover;
-  background-repeat: no-repeat;
-  background-position: center top;
-}
-.product-image.missing-image {
-  width: 100%;
-  height: 0;
-  padding: 50% 0px;
-  background-size: cover;
-  background-repeat: no-repeat;
-  background-position: center top;
-  position: relative;
-  background-color: #EBEFF2;
-}
-.product-image.missing-image .octicon {
-  font-size: 32px;
-  color: #d1d8dd;
-}
-.product-search {
-  margin-bottom: 15px;
-}
-@media (max-width: 767px) {
-  .product-search {
-    width: 100%;
-  }
-}
-.borderless td,
-.borderless th {
-  border-bottom: 1px solid #EBEFF2;
-  padding-left: 0px !important;
-  line-height: 1.8em !important;
-}
-.item-desc {
-  border-top: 2px solid #EBEFF2;
-  padding-top: 10px;
-}
-.featured-products {
-  border-top: 1px solid #EBEFF2;
-}
-.transaction-list-item .indicator {
-  font-weight: inherit;
-  color: #8D99A6;
-}
-.transaction-list-item .transaction-time {
-  margin-top: 5px;
-}
-.transaction-subheading .indicator {
-  font-weight: inherit;
-  color: #8D99A6;
-}
-.order-container {
-  margin: 50px 0px;
-}
-.order-container .order-item-header .h6 {
-  padding: 7px 15px;
-}
-.order-container .order-items {
-  margin: 30px 0px 0px;
-}
-.order-container .order-item-table {
-  margin: 0px -15px;
-}
-.order-container .order-item-header {
-  border-bottom: 1px solid #d1d8dd;
-}
-.order-container .order-image-col {
-  padding-right: 0px;
-}
-.order-container .order-image {
-  max-width: 55px;
-  max-height: 55px;
-  margin-top: -5px;
-}
-.order-container .order-taxes {
-  margin-top: 30px;
-}
-.order-container .order-taxes .row {
-  margin-top: 15px;
-}
-.order-container .tax-grand-total-row {
-  padding-top: 15px;
-  padding-bottom: 30px;
-}
-.order-container .tax-grand-total {
-  display: inline-block;
-  font-size: 16px;
-  font-weight: bold;
-  margin-top: 5px;
-}
-.cart-container {
-  margin: 50px 0px;
-}
-.cart-container .checkout {
-  margin-bottom: 15px;
-}
-.cart-container .cart-item-header .h6 {
-  padding: 7px 15px;
-}
-.cart-container .cart-items {
-  margin: 30px 0px 0px;
-}
-.cart-container .cart-item-table {
-  margin: 0px -15px;
-}
-.cart-container .cart-item-header {
-  border-bottom: 1px solid #d1d8dd;
-}
-.cart-container .cart-image-col {
-  padding-right: 0px;
-}
-.cart-container .cart-image {
-  max-width: 55px;
-  max-height: 55px;
-  margin-top: -5px;
-}
-.cart-container .cart-taxes {
-  margin-top: 30px;
-}
-.cart-container .cart-taxes .row {
-  margin-top: 15px;
-}
-.cart-container .tax-grand-total-row {
-  border-top: 1px solid #d1d8dd;
-  padding-top: 15px;
-}
-.cart-container .cart-addresses {
-  margin-top: 50px;
-}
-.cart-items-dropdown .cart-dropdown,
-.item_name_dropdown {
-  display: none;
-}
-.cart-dropdown-container {
-  width: 400px;
-  padding: 15px;
-}
-.cart-dropdown-container .item-price {
-  display: block !important;
-  padding-bottom: 10px;
-}
-.cart-dropdown-container .cart-item-header {
-  border-bottom: 1px solid #d1d8dd;
-}
-.cart-dropdown-container .cart-items-dropdown {
-  max-height: 350px;
-}
-.cart-dropdown-container .cart-items-dropdown .cart-dropdown {
-  display: block;
-  margin-top: 15px;
-}
-.cart-dropdown-container .item_name_dropdown {
-  display: block;
-}
-.cart-dropdown-container .item-description,
-.cart-dropdown-container .cart-items .checkout,
-.cart-dropdown-container .item_name_and_description {
-  display: none;
-}
-.cart-dropdown-container .checkout-btn {
-  padding-bottom: 25px;
-}
-.cart-dropdown-container .col-name-description {
-  margin-bottom: 8px;
-}
-.number-spinner {
-  width: 100px;
-  margin-top: 5px;
-}
-.cart-btn {
-  border-color: #ccc;
-}
-.cart-qty {
-  text-align: center;
-}
-.product-list-link .row {
-  border-bottom: 1px solid #EBEFF2;
-}
-.product-list-link .row:hover {
-  background-color: #fafbfc;
-}
-.product-list-link .row > div {
-  padding-top: 15px;
-  padding-bottom: 15px;
-}
-.product-list-link:first-child .row {
-  border-top: 1px solid #EBEFF2;
-}
-.item-group-nav-buttons {
-  margin-top: 15px;
-}
-.footer-subscribe .btn-default {
-  background-color: transparent;
-  border: 1px solid #d1d8dd;
-}
-@media (min-width: 992px) {
-  .footer-subscribe {
-    max-width: 350px;
-  }
-}
-.item-group-content {
-  margin-top: 30px;
-}
-.product-image-img {
-  border: 1px solid #EBEFF2;
-  border-radius: 3px;
-}
-.product-text {
-  border-top: 1px solid #EBEFF2;
-  padding: 15px;
-  word-wrap: break-word;
-  height: 75px;
-  display: block;
-  /* Fallback for non-webkit */
-  display: -webkit-box;
-  max-width: 100%;
-  margin: 0 auto;
-  -webkit-line-clamp: 3;
-  -webkit-box-orient: vertical;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-.product-image-wrapper {
-  padding-bottom: 40px;
-}
-.duration-bar {
-  display: inline-block;
-  color: white;
-  background: #8FD288;
-  padding: 3px;
-}
-.duration-invisible {
-  visibility: hidden;
-}
-.duration-value {
-  float: right;
-}
-.bar-outer-text {
-  color: #8FD288;
-  background: none;
-  float: none;
-  border: none;
-}
-.bom-spec {
-  margin-bottom: 20px;
-}
diff --git a/erpnext/public/less/website.less b/erpnext/public/less/website.less
index 14d033c..448bd3b 100644
--- a/erpnext/public/less/website.less
+++ b/erpnext/public/less/website.less
@@ -1,7 +1,4 @@
-@border-color: #d1d8dd;
-@light-border-color: #EBEFF2;
-@text-muted: #8D99A6;
-@light-bg: #fafbfc;
+@import "variables.less";
 
 .web-long-description {
 	font-size: 18px;
@@ -21,6 +18,12 @@
 	text-align: center;
 }
 
+
+.product-image img {
+	max-height: 500px;
+	margin: 0 auto;
+}
+
 @media (max-width: 767px) {
 	.product-image {
 		height: 0px;
@@ -221,7 +224,7 @@
 
 	.cart-items-dropdown .cart-dropdown {
 		display:block;
-	   	margin-top:15px;
+		margin-top:15px;
 	}
 
 	.item_name_dropdown {
@@ -342,4 +345,14 @@
 
 .bom-spec {
 	margin-bottom: 20px;
-}
\ No newline at end of file
+}
+
+// For Item Alternate Image
+.item-alternative-image {
+	padding: 5px;
+	margin-bottom: 5px;
+
+	&:hover {
+		border-color: @brand-primary;
+	}
+}
diff --git a/erpnext/templates/generators/item.html b/erpnext/templates/generators/item.html
index 0e09f58..3220722 100644
--- a/erpnext/templates/generators/item.html
+++ b/erpnext/templates/generators/item.html
@@ -8,108 +8,130 @@
 
 {% block page_content %}
 {% from "erpnext/templates/includes/macros.html" import product_image %}
-<div class="item-content" style="margin-top:20px;">
+<div class="item-content">
 	<div class="product-page-content" itemscope itemtype="http://schema.org/Product">
 		<div class="row">
-			<div class="col-sm-6">
+			<div class="row">
 				{% if slideshow %}
-					{% include "templates/includes/slideshow.html" %}
-				{% else %}
-					{{ product_image(website_image, "product-full-image") }}
-				{% endif %}
-			</div>
-			<div class="col-sm-6" style="padding-left:20px;">
-				 <h2 itemprop="name" style="margin-top: 0px;">{{ item_name }}</h2>
-
-				<p class="text-muted">
-					{{ _("Item Code") }}: <span itemprop="productID">{{ variant and variant.name or name }}</span></p>
-				<br>
-				<div class="item-attribute-selectors">
-					{% if has_variants %}
-					{% for d in attributes %}
-					{% if attribute_values[d.attribute] -%}
-					<div class="item-view-attribute {% if (attribute_values[d.attribute] | len)==1 -%} hidden {%- endif %}"
-							style="margin-bottom: 10px;">
-						<h6 class="text-muted">{{ _(d.attribute) }}</h6>
-						<select class="form-control"
-							style="max-width: 140px"
-							data-attribute="{{ d.attribute }}">
-						{% for value in attribute_values[d.attribute] %}
-						<option value="{{ value }}"
-						{% if selected_attributes and selected_attributes[d.attribute]==value -%}
-							selected
-						{%- elif disabled_attributes and value in disabled_attributes.get(d.attribute, []) -%}
-							disabled
-						{%- endif %}>
-							{{ _(value) }}
-						</option>
-						{% endfor %}
-						</select>
+				{% set slideshow_items = frappe.get_list(doctype="Website Slideshow Item",  fields=["image"], filters={ "parent": doc.slideshow }) %}
+				<div class="col-md-1">
+				{%- for slideshow_item in slideshow_items -%}
+					{% set image_src = slideshow_item['image'] %}
+					{% if image_src %}
+					<div class="item-alternative-image border">
+						<img src="{{ image_src }}" height="50" weight="50" />
 					</div>
-					{%- endif %}
-					{% endfor %}
 					{% endif %}
+				{% endfor %}
 				</div>
-				<br>
-				<div style="min-height: 100px; margin: 10px 0;">
-					<div itemprop="offers" itemscope itemtype="http://schema.org/Offer">
-						<h4 class="item-price hide" itemprop="price"></h4>
-						<div class="item-stock hide" itemprop="availability"></div>
+				<div class="col-md-5">
+					<div class="item-image">
+						{% set first_image = slideshow_items[0]['image'] %}
+						{{ product_image(first_image, "product-full-image") }}
 					</div>
-					<div class="item-cart hide">
-						<div id="item-spinner">
-							<span style="display: inline-block">
-								<div class="input-group number-spinner">
-									<span class="input-group-btn">
-										<button class="btn btn-default cart-btn" data-dir="dwn">
-											–</button>
-									</span>
-									<input class="form-control text-right cart-qty"	value="1">
-									<span class="input-group-btn">
-										<button class="btn btn-default cart-btn" data-dir="up" style="margin-left:-2px;">
+				</div>
+				{% else %}
+				<div class="col-md-6">
+					{{ product_image(website_image, "product-full-image") }}
+				</div>
+				{% endif %}
+				<div class="col-sm-6">
+					<h2 itemprop="name">{{ item_name }}</h2>
+					<p class="text-muted">
+						{{ _("Item Code") }}: <span itemprop="productID">{{ variant and variant.name or name }}</span>
+					</p>
+					<br>
+					<div class="item-attribute-selectors">
+						{% if has_variants and attributes %}
+						{{ attributes }}
+						{#
+
+						{% for d in attributes %}
+						{% if attribute_values[d.attribute] -%}
+						<div class="item-view-attribute {% if (attribute_values[d.attribute] | len)==1 -%} hidden {%- endif %}"
+								style="margin-bottom: 10px;">
+							<h6 class="text-muted">{{ _(d.attribute) }}</h6>
+							<select class="form-control"
+								style="max-width: 140px"
+								data-attribute="{{ d.attribute }}">
+							{% for value in attribute_values[d.attribute] %}
+							<option value="{{ value }}"
+							{% if selected_attributes and selected_attributes[d.attribute]==value -%}
+								selected
+							{%- elif disabled_attributes and value in disabled_attributes.get(d.attribute, []) -%}
+								disabled
+							{%- endif %}>
+								{{ _(value) }}
+							</option>
+							{% endfor %}
+							</select>
+						</div>
+						{%- endif %}
+						{% endfor %}
+
+						#}
+						{% endif %}
+					</div>
+					<br>
+					<div>
+						<div itemprop="offers" itemscope itemtype="http://schema.org/Offer">
+							<h4 class="item-price hide" itemprop="price"></h4>
+							<div class="item-stock hide" itemprop="availability"></div>
+						</div>
+						<div class="item-cart hide">
+							<div id="item-spinner">
+								<span style="display: inline-block">
+									<div class="input-group number-spinner">
+										<span class="input-group-btn">
+											<button class="btn btn-default cart-btn" data-dir="dwn">
+												–</button>
+										</span>
+										<input class="form-control text-right cart-qty" value="1">
+										<span class="input-group-btn">
+											<button class="btn btn-default cart-btn" data-dir="up" style="margin-left:-2px;">
 											+</button>
-									</span>
-								</div>
-							</span>
-						</div>
-						<div id="item-add-to-cart">
-							<button class="btn btn-primary btn-sm">
-								{{ _("Add to Cart") }}</button>
-						</div>
-						<div id="item-update-cart" style="display: none;">
-							<a href="/cart" class='btn btn-sm btn-default'>
-								<i class='octicon octicon-check'></i>
-								{{ _("View in Cart") }}</a>
+										</span>
+									</div>
+								</span>
+							</div>
+							<div id="item-add-to-cart">
+								<button class="btn btn-primary btn-sm">
+									{{ _("Add to Cart") }}</button>
+							</div>
+							<div id="item-update-cart" style="display: none;">
+								<a href="/cart" class='btn btn-sm btn-default'>
+									<i class='octicon octicon-check'></i>
+									{{ _("View in Cart") }}</a>
+							</div>
 						</div>
 					</div>
 				</div>
 			</div>
-		</div>
-		<div class="row item-website-description" style="margin-top:30px; margin-bottom:20px">
-			<div class="col-md-12">
-		<div class="h6 text-uppercase">{{ _("Description") }}</div>
-		<div itemprop="description" class="item-desc">
-		{{ web_long_description or description or _("No description given") }}
-		</div>
-		</div>
-		</div>
-
-		{% if website_specifications -%}
-		<div class="row item-website-specification" style="margin-top: 40px">
-			<div class="col-md-12">
-				<div class="h6 text-uppercase">{{ _("Specifications") }}</div>
-
-				<table class="table borderless" style="width: 100%">
-				{% for d in website_specifications -%}
-					<tr>
-						<td class="text-muted" style="width: 30%;">{{ d.label }}</td>
-						<td>{{ d.description }}</td>
-					</tr>
-				{%- endfor %}
-				</table>
+			<div class="row item-website-description margin-top">
+				<div class="col-md-12">
+					<div class="h6 text-uppercase">{{ _("Description") }}</div>
+					<div itemprop="description" class="item-desc">
+					{{ web_long_description or description or _("No description given") }}
+					</div>
+				</div>
 			</div>
+			{% if website_specifications -%}
+			<div class="row item-website-specification margin-top">
+				<div class="col-md-12">
+					<div class="h6 text-uppercase">{{ _("Specifications") }}</div>
+
+					<table class="table">
+					{% for d in website_specifications -%}
+						<tr>
+							<td class="text-muted" style="width: 30%;">{{ d.label }}</td>
+							<td>{{ d.description }}</td>
+						</tr>
+					{%- endfor %}
+					</table>
+				</div>
+			</div>
+			{%- endif %}
 		</div>
-		{%- endif %}
 	</div>
 </div>
 <script>
diff --git a/erpnext/templates/includes/product_page.js b/erpnext/templates/includes/product_page.js
index 798a6cf..ef69e20 100644
--- a/erpnext/templates/includes/product_page.js
+++ b/erpnext/templates/includes/product_page.js
@@ -109,6 +109,13 @@
 
 		window.location.href = window.location.pathname + "?variant=" + item_code;
 	});
+
+	// change the item image src when alternate images are hovered
+	$(document.body).on('mouseover', '.item-alternative-image', (e) => {
+		const $alternative_image = $(e.currentTarget);
+		const src = $alternative_image.find('img').prop('src');
+		$('.item-image img').prop('src', src);
+	});
 });
 
 var toggle_update_cart = function(qty) {