原标题:opencart 3.0版本购物车优化
导读:
本篇文章为大家opencart讲解购物车的一个功能优化,这个功能的优化很多客户都说用户体验非常好,下面让我们直入主题。使用过opencart3.0版本的程序,我们都知道它这个购...
本篇文章为大家opencart讲解购物车的一个功能优化,这个功能的优化很多客户都说用户体验非常好,下面让我们直入主题。
使用过opencart3.0版本的程序,我们都知道它这个购物车页面 在更新或者删除单个商品的时候刷新整个网页,虽然对购物流程没有什么影响,但是如果
购物车商品很多,那么用户在改个数量或者删除的时候,页面反复刷新,客户也需要从新再去找到需要修改的商品,这个过程就有些复杂了。

下面我们通过修改程序,让这个页面不全部更新,这样用户也不用反复的去查找商品了。 点击查看测试demo
下面代码是路径catalog\view\theme\default\template\checkout\cart.twig 我修改后的代码,由于这里修改讲解较为复杂,所以大家可以比对一下原来的
文件和我这个文件有代码不一样的地方。 这里给大家提供一个代码对比的网站工具。
{{ header }}
<div id="checkout-cart" class="container">
<ul class="breadcrumb">
{% for breadcrumb in breadcrumbs %}
<li><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
{% endfor %}
</ul>
{% if attention %}
<div class="alert alert-info"><i class="fa fa-info-circle"></i> {{ attention }}
<button type="button" class="close" data-dismiss="alert">×</button>
</div>
{% endif %}
{% if success %}
<div class="alert alert-success alert-dismissible"><i class="fa fa-check-circle"></i> {{ success }}
<button type="button" class="close" data-dismiss="alert">×</button>
</div>
{% endif %}
{% if error_warning %}
<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> {{ error_warning }}
<button type="button" class="close" data-dismiss="alert">×</button>
</div>
{% endif %}
<div class="row">{{ column_left }}
{% if column_left and column_right %}
{% set class = 'col-sm-6' %}
{% elseif column_left or column_right %}
{% set class = 'col-sm-9' %}
{% else %}
{% set class = 'col-sm-12' %}
{% endif %}
<div id="content" class="{{ class }}">{{ content_top }}
<h1>{{ heading_title }}
{% if weight %}
({{ weight }})
{% endif %} </h1>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<td class="text-center">{{ column_image }}</td>
<td class="text-left">{{ column_name }}</td>
<td class="text-left">{{ column_model }}</td>
<td class="text-left">{{ column_quantity }}</td>
<td class="text-right">{{ column_price }}</td>
<td class="text-right">{{ column_total }}</td>
</tr>
</thead>
<tbody>
{% for product in products %}
<tr class="product-thumb">
<td class="text-center">{% if product.thumb %} <a href="{{ product.href }}"><img src="{{ product.thumb }}" alt="{{ product.name }}" title="{{ product.name }}" class="img-thumbnail" /></a> {% endif %}</td>
<td class="text-left"><a href="{{ product.href }}">{{ product.name }}</a> {% if not product.stock %} <span class="text-danger">***</span> {% endif %}
{% if product.option %}
{% for option in product.option %} <br />
<small>{{ option.name }}: {{ option.value }}</small> {% endfor %}
{% endif %}
{% if product.reward %} <br />
<small>{{ product.reward }}</small> {% endif %}
{% if product.recurring %} <br />
<span class="label label-info">{{ text_recurring_item }}</span> <small>{{ product.recurring }}</small> {% endif %}</td>
<td class="text-left">{{ product.model }}</td>
<td class="text-left"><div class="input-group btn-block" style="max-width: 200px;">
<input type="text" name="quantity[{{ product.cart_id }}]" value="{{ product.quantity }}" size="1" class="form-control" />
<div class="input-group-btn">
<button type="button" data-toggle="tooltip" title="{{ button_update }}" class="btn btn-primary update-cart"><i class="fa fa-refresh"></i></button>
<button type="button" data-toggle="tooltip" title="{{ button_remove }}" data-cart-id="{{ product.cart_id }}" class="btn btn-danger remove-cart"><i class="fa fa-times-circle"></i></button>
</div></div></td>
<td class="text-right">{{ product.price }}</td>
<td class="text-right">{{ product.total }}</td>
</tr>
{% endfor %}
{% for voucher in vouchers %}
<tr>
<td></td>
<td class="text-left">{{ voucher.description }}</td>
<td class="text-left"></td>
<td class="text-left"><div class="input-group btn-block" style="max-width: 200px;">
<input type="text" name="" value="1" size="1" disabled="disabled" class="form-control" />
<div class="input-group-btn">
<button type="button" data-toggle="tooltip" title="{{ button_remove }}" class="btn btn-danger" onclick="voucher.remove('{{ voucher.key }}');"><i class="fa fa-times-circle"></i></button>
</div></div></td>
<td class="text-right">{{ voucher.amount }}</td>
<td class="text-right">{{ voucher.amount }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% if modules %}
<h2>{{ text_next }}</h2>
<p>{{ text_next_choice }}</p>
<div class="panel-group" id="accordion"> {% for module in modules %}
{{ module }}
{% endfor %} </div>
{% endif %} <br />
<div class="row">
<div class="col-sm-4 col-sm-offset-8">
<table class="table table-bordered total-table">
{% for total in totals %}
<tr>
<td class="text-right"><strong>{{ total.title }}:</strong></td>
<td class="text-right">{{ total.text }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
<div class="buttons clearfix">
<div class="pull-left"><a href="{{ continue }}" class="btn btn-default">{{ button_shopping }}</a></div>
<div class="pull-right"><a href="{{ checkout }}" class="btn btn-primary">{{ button_checkout }}</a></div>
</div>
{{ content_bottom }}</div>
{{ column_right }}</div>
</div>
<!--添加更新和删除JS-->
<script type="text/javascript">
$('.update-cart').on('click',function(){
$.ajax({
url: 'index.php?route=checkout/cart/edit',
type: 'post',
data: $('input[name^=\'quantity\']'),
dataType: 'json',
beforeSend: function() {
$(".update-cart").attr('disabled',true);
},
complete: function() {
$(".update-cart").attr('disabled',false);
},
success: function(json) {
if(json['success']){
$('.alert-success').fadeOut();
$('.breadcrumb').after('<div class="alert alert-success"><i class="fa fa-check-circle"></i>'+json['success']+'<button type="button" class="close" data-dismiss="alert"> × </button></div>');
$('#cart > button').html('<span id="cart-total"><i class="fa fa-shopping-cart"></i> ' + json['total'] + '</span>');
$('#cart > ul').load('index.php?route=common/cart/info ul li');
}
html = '';
if (json['totals'] != '') {
for (i = 0; i < json['totals'].length; i++) {
html += '<tr> <td class="text-right"><strong>' + json['totals'][i]['title'] +'</strong></td><td class="text-right">' + json['totals'][i]['text'] +'</td> </tr>';
}
$('.total-table').html(html);
}
if(json['update']){
location = 'index.php?route=checkout/cart';
}
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
}
})
});
//删除商品js
$(".remove-cart").on('click',function(){
var cart_id = $(this).attr('data-cart-id');
var elv = $(this).parents('.product-thumb');
$.ajax({
url: 'index.php?route=checkout/cart/remove',
type: 'post',
data: 'key=' + cart_id,
dataType: 'json',
beforeSend: function() {
$(".remove-cart").attr('disabled',true);
},
complete: function() {
$(".remove-cart").attr('disabled',false);
},
success: function(json) {
if(json['success']){
elv.fadeOut();
$('.alert-success').remove();
$('.breadcrumb').after('<div class="alert alert-success"><i class="fa fa-check-circle"></i> '+json['success']+'<button type="button" class="close" data-dismiss="alert"> × </button></div>');
$('#cart > button').html('<span id="cart-total"><i class="fa fa-shopping-cart"></i> ' + json['total'] + '</span>');
$('#cart > ul').load('index.php?route=common/cart/info ul li');
}
html = '';
if (json['totals'] != '') {
for (i = 0; i < json['totals'].length; i++) {
html += '<tr> <td class="text-right"><strong>' + json['totals'][i]['title'] +'</strong></td><td class="text-right">' + json['totals'][i]['text'] +'</td> </tr>';
}
$('.total-table').html(html);
}
if(json['update']){
location = 'index.php?route=checkout/cart';
}
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
}
});
});
</script>
<!--添加更新和删除JSend-->
{{ footer }}下面是控制器文件(路径catalog\controller\checkout\cart.php),我只摘要了需要修改的两个代码方法片段,一个是public function edit ()方法一个是public function remove ()方法
public function edit() {
$this->load->language('checkout/cart');
$json = array();
// Update
if (!empty($this->request->post['quantity'])) {
foreach ($this->request->post['quantity'] as $key => $value) {
$this->cart->update($key, $value);
}
$this->session->data['success'] = $this->language->get('text_remove');
$json['success'] = $this->language->get('text_remove');//添加更新说明
unset($this->session->data['shipping_method']);
unset($this->session->data['shipping_methods']);
unset($this->session->data['payment_method']);
unset($this->session->data['payment_methods']);
unset($this->session->data['reward']);
//添加金额计算
// Totals
$this->load->model('setting/extension');
$totals = array();
$taxes = $this->cart->getTaxes();
$total = 0;
// Because __call can not keep var references so we put them into an array.
$total_data = array(
'totals' => &$totals,
'taxes' => &$taxes,
'total' => &$total
);
// Display prices
if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
$sort_order = array();
$results = $this->model_setting_extension->getExtensions('total');
foreach ($results as $key => $value) {
$sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order');
}
array_multisort($sort_order, SORT_ASC, $results);
foreach ($results as $result) {
if ($this->config->get('total_' . $result['code'] . '_status')) {
$this->load->model('extension/total/' . $result['code']);
// We have to put the totals in an array so that they pass by reference.
$this->{'model_extension_total_' . $result['code']}->getTotal($total_data);
}
}
$sort_order = array();
foreach ($totals as $key => $value) {
$sort_order[$key] = $value['sort_order'];
}
array_multisort($sort_order, SORT_ASC, $totals);
}
$json['total'] = sprintf($this->language->get('text_items'), $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0), $this->currency->format($total, $this->session->data['currency']));
$json['totals'] = array();
foreach ($totals as $total) {
$json['totals'][] = array(
'title' => $total['title'],
'text' => $this->currency->format($total['value'], $this->session->data['currency'])
);
}
if(!$this->cart->countProducts()){
$json['update'] = true;
}
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}
public function remove() {
$this->load->language('checkout/cart');
$json = array();
// Remove
if (isset($this->request->post['key'])) {
$this->cart->remove($this->request->post['key']);
unset($this->session->data['vouchers'][$this->request->post['key']]);
$json['success'] = $this->language->get('text_remove');
unset($this->session->data['shipping_method']);
unset($this->session->data['shipping_methods']);
unset($this->session->data['payment_method']);
unset($this->session->data['payment_methods']);
unset($this->session->data['reward']);
// Totals
$this->load->model('setting/extension');
$totals = array();
$taxes = $this->cart->getTaxes();
$total = 0;
// Because __call can not keep var references so we put them into an array.
$total_data = array(
'totals' => &$totals,
'taxes' => &$taxes,
'total' => &$total
);
// Display prices
if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
$sort_order = array();
$results = $this->model_setting_extension->getExtensions('total');
foreach ($results as $key => $value) {
$sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order');
}
array_multisort($sort_order, SORT_ASC, $results);
foreach ($results as $result) {
if ($this->config->get('total_' . $result['code'] . '_status')) {
$this->load->model('extension/total/' . $result['code']);
// We have to put the totals in an array so that they pass by reference.
$this->{'model_extension_total_' . $result['code']}->getTotal($total_data);
}
}
$sort_order = array();
foreach ($totals as $key => $value) {
$sort_order[$key] = $value['sort_order'];
}
array_multisort($sort_order, SORT_ASC, $totals);
}
$json['total'] = sprintf($this->language->get('text_items'), $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0), $this->currency->format($total, $this->session->data['currency']));
//更新订单小计
$json['totals'] = array();
foreach ($totals as $total) {
$json['totals'][] = array(
'title' => $total['title'],
'text' => $this->currency->format($total['value'], $this->session->data['currency'])
);
}
if(!$this->cart->countProducts()){
$json['update'] = true;
}
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}





直接在产品详情页面,点击“加入到购物车”就直接跳转到购物车付款页面,不用再次点击购物车,才跳转到购物车。
谢谢