简体   繁体   English

将产品添加到购物车 jQuery/Ajax/Symfony/Twig

[英]Add products to the cart jQuery/Ajax/Symfony/Twig

I am using session array as a cart in my store.我在商店中使用 session 阵列作为购物车。 So everytime I add new product to the cart I also update my total value of the cart that looks like: <a class="navbar-brand px-3" href="{{path('checkout')}}" id="cart">Cart{{total}}€</a>所以每次我将新产品添加到购物车时,我也会更新购物车的总价值,如下所示: <a class="navbar-brand px-3" href="{{path('checkout')}}" id="cart">Cart{{total}}€</a>

The problem is that the pages is reloaded every time i add a new product, because of return $this->redirectToRoute('eshop');问题是每次我添加新产品时都会重新加载页面,因为return $this->redirectToRoute('eshop'); in my add_product function.在我的 add_product function 中。

I want to add products and update the total value, without reloading the whole page.我想添加产品并更新总值,而不重新加载整个页面。 How can I implement jQuery and AJAX in this situation?在这种情况下如何实现 jQuery 和 AJAX ? And what changes should be done in add_product function? add_product function应该做哪些改变?

I tried this but the product is not declared variable.我试过这个,但产品没有声明为变量。

<script>
  $(document).ready(function() {
     $('#btnAddProduct').click(function() {
        var pos = $('{{product.id}}').val();
       
       
        $.ajax({
           url: "{{path('add_product', {'id' : 'id'}) }}",
           type: "POST",
           data: },
           success: function() {
            
           }
        });
     });
  });

My products looks like this.我的产品看起来像这样。

{% for product in products %}    

              <div class="col-lg-2">
                 <div class="card mb-3">
                    <img src="{{asset(product.image)}}" class="img-fluid" alt="{{product.name}}">
                    <h5 class="text-center" >{{product.name}}</h5>
                    <p class="text-center" >€{{product.price}}</p>
                    <form action="{{path('add_product', {'id' : product.id}) }}" method="post">
                       <button id="btnAddProduct" class="btn btn-primary btn-block" type="submit" >Add product</button>
                    </form>
                 </div>
              </div>
             
{% endfor %}

And also my add_product method in Symfony:还有我在 Symfony 中的 add_product 方法:

 /**
 * @Route("/eshop/add_product/{id}", name="add_product")
 */
public function add_product($id,Request $request){
    
    $product = $this->eshop_model->get_product($id);
    $total= $this->session->get('total');

    $basket = $this->session->get('basket');
    $check = 0;
    foreach($basket as $k => $v){
            if($v['id'] == $product['id']){
                $basket[$k]['quantity']++;
                $basket[$k]['subtotal'] += $product['price'];
                $check = 1;
                break;          
            }    
    }
        
        if($check == 0){
            $a = array('id' => $product['id'], 'quantity' => 1, 'subtotal' => $product['price'], 'price' => $product['price'], 'name' => $product['name']);
            array_push($basket,$a);
        }
                 
        $total= $total+ $product['price'];
        $this->session->set('total',$total);
        
        $this->session->set('basket',$basket);

    return $this->redirectToRoute('eshop');
}

A small example with your codebase.你的代码库的一个小例子。

First remove the Html Form and add a data field for your product id to the button.首先删除 Html 表单,并为您的产品 ID 添加一个数据字段到按钮。

{% for product in products %}
    <div class="col-lg-2">
        <div class="card mb-3">
            <img src="{{asset(product.image)}}" class="img-fluid" alt="{{product.name}}">
            <h5 class="text-center" >{{product.name}}</h5>
            <p class="text-center" >€{{product.price}}</p>
            <button id="btnAddProduct" class="btn btn-primary btn-block" type="button" data-id="{{ product.id }}">Add product</button>
        </div>
    </div>
{% endfor %}

Then change your controller class to get the right datatype to work with javascript and add a default value for id.然后更改您的 controller class 以获取正确的数据类型以使用 javascript 并为 id 添加默认值。

// Set id default value to get the route without id
/**
 * @Route("/eshop/add_product/{id}", name="add_product")
 */
public function add_product(Request $request, $id = null): Response
{

    // ..... your stuff

    // remove 
    return $this->redirectToRoute('eshop');

    // and add 
    return $this->json(['total' => $total]);
}

Add a span tag around your total value to set it with javascript.在您的总值周围添加一个跨度标签以将其设置为 javascript。

<a class="navbar-brand px-3" href="{{path('checkout')}}" id="cart">Cart <span id="total">{{ total }}</span>€</a>

Bind the button to the ajax call and change the total field on success.将按钮绑定到 ajax 调用并在成功时更改总字段。

    $(document).ready(function() {
        $('#btnAddProduct').click(function() {
            $.ajax({
                url: "{{ path('add_product') }}/" + $(this).data('id'),
                type: "GET",
                success: function(response) {
                    // Change #total text
                    $('#total').text(response.total);
                }
            });
        });
    });

thats all;)就这样;)

If you need both behaviours (default url with an redirect response and a json response for ajax calls), you can check if the request ist an ajax request. If you need both behaviours (default url with an redirect response and a json response for ajax calls), you can check if the request ist an ajax request.

public function add_product(Request $request, $id = null): Response
{

    // ..... your stuff


    if ($request->isXmlHttpRequest()) {
        return $this->json(['total' => $total]);
    }
    
    return $this->redirectToRoute('eshop');
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM