Zum Hauptinhalt springen

Adding a product to the basket

In this example, the product is added to the basket using the BasketItemAdd action. The corresponding form is located, for example, in the product box, which can be placed flexibly.
{{ var $basketAdd = $wsActions.create("BasketItemAdd", tag=$product.id)}}

{{ if $wsActions.current.success and $wsActions.current.name == "BasketItemAdd" }}
   <p>Product successfully added to the basket!</p>
{{ /if }}

{{ if $basketAdd.error }}
   Errors occurred:
   {{ foreach $error in $basketAdd.errors }}
      {{ if $error.text }}
         {{= $error.text }}
      {{ else }}
         {{= $error.code }}
      {{ /if }}
   {{ /foreach }}
{{ /if }}

<form method="post" action="{{= $wsViews.current.url() }}" itemscope itemtype="http://schema.org/Product" class="h-100">
   <input type="hidden" name="wsact" value="{{= $basketAdd.id }}">
   <input type="hidden" name="wscsrf" value="{{= $basketAdd.csrf }}">
   <input type="hidden" name="wstarget" value="{{= $view.url() }}">
   <input type="hidden" name="productId" value="{{= $product.id }}">

   <p>{{= $product.name }}</p>

   <input type="text" name="quantity" value="{{= $basketAdd.params.quantity|ifNull(1) }}">
   <button type="submit">Add to basket</button>
</form>

Removing a product from the basket

Using the BasketItemDelete action, products can be removed from the basket.
{{ if $wsBasket.items }}
  {{ foreach $cProduct in $wsBasket.items }}
    {{ var $cProductDelete = $wsActions.create("BasketItemDelete", tag = $cProduct.id) }}

    {{ if $basketItemDelete.error }}
      Errors occurred:
      {{ foreach $error in $basketItemDelete.errors }}
        {{ if $error.text }}
          {{= $error.text }}
        {{ else }}
          {{= $error.code }}
        {{ /if }}
      {{ /foreach }}
    {{ /if }}

    <p>{{= $cProduct.product.name }}</p>
    ...
    <form id="wsFormBasketDeleteProductOffcanvas-{{= $cProduct.id }}" action="{{= $wsViews.viewUrl('basket.htm') }}" method="post" ws-ajax-form>
      <input type="hidden" name="wsReplaceIds" value="wsBasketWrapper,wsBasketEntries,wsBasketOffcanvasContent">
      <input type="hidden" name="wscsrf" value="{{= $cProductDelete.csrf }}">
      <input type="hidden" name="wsact" value="{{= $cProductDelete.id }}">
      <input type="hidden" name="wstarget" value="{{= $wsViews.viewUrl('basket.htm') }}">
      <input type="hidden" name="productId" value="{{= $cProduct.product.id }}">
      <input type="hidden" name="basketItemId" value="{{= $cProduct.id }}">
      <button type="submit">Remove from basket</button>
    </form>
  {{ /foreach }}
{{ /if }}

Changing the quantity of individual items in the basket

Using the BasketItemUpdate action, the quantity of a product in the basket can be changed.
{{ if $wsBasket.items }}
  {{ foreach $cProduct in $wsBasket.items }}
    <p>{{= $cProduct.product.name }}</p>

    {{ var $basketItemUpdateAction = $wsActions.create("BasketItemUpdate", tag=$basketItem.id) }}
    
    <form method="post" action="{{ $wsViews.viewUrl('basket.htm') }}">
      <input type="hidden" name="wscsrf" value="{{= $basketItemUpdateAction.csrf }}">
      <input type="hidden" name="wsact" value="{{= $basketItemUpdateAction.id }}">
      <input type="hidden" name="wstarget" value="{{= $wsViews.viewUrl('basket.htm') }}">
      <input type="hidden" name="basketItemId" value="{{= $basketItem.id }}">

      <input type="text" name="quantity" value="{{= $basketItem.quantity | preparedFormat('amount') }}" class="quantityUpdate">
    </form>
    
    <script type="text/javascript">
      $("input.quantityUpdate").on("change", function() {
        $(this).closest("form").submit();
      });
    </script>

    {{ if $basketItemUpdateAction.success }}
      <p>Quantity successfully changed.</p>
    {{ /if }}

    {{ if $basketItemUpdateAction.error }}
      Errors occurred:
      {{ foreach $error in $basketItemUpdateAction.errors }}
        {{ if $error.text }}
          {{= $error.text }}
        {{ else }}
          {{= $error.code }}
        {{ /if }}
      {{ /foreach }}
    {{ /if }}
  {{ /foreach }}
{{ /if }}

Offcanvas mini basket

The required CSS and JavaScript files are already included in the delivery shop. However, additional scripts are required if the functions to change the quantity and remove a product from the basket are needed. Button to open the mini basket
<button type="button" title="Basket" data-bs-toggle="offcanvas" data-bs-target="#wsBasketOffcanvas">
   <svg role="img" xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="currentColor" viewBox="0 0 16 16"><path d="M8 1a2.5 2.5 0 0 1 2.5 2.5V4h-5v-.5A2.5 2.5 0 0 1 8 1zm3.5 3v-.5a3.5 3.5 0 1 0-7 0V4H1v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4h-3.5zM2 5h12v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5z"/></svg>
   <span id="wsBasketEntries">
      {{ if $wsBasket.items }}
         {{= $wsBasket.items | len }}
      {{ /if }}
   </span>
</button>
Display area of the mini basket
<div class="offcanvas offcanvas-end" tabindex="-1" id="wsBasketOffcanvas">
   <div class="offcanvas-header">
      <p>Basket</p>
      <button type="button" data-bs-dismiss="offcanvas" title="Close"></button>
   </div>
   <div class="offcanvas-body">
      <div id="wsBasketOffcanvasContent">
         {{ if $wsBasket.items }}
            <table class="table">
               {{ foreach $cProduct in $wsBasket.items }}
                  <tr>
                     <td class="wsTableCellMin">
                        <a href="{{= $wsViews.url('Product', {productId: $cProduct.product.id}) }}">
                        <img src="{{= $cProduct.product.custom.image.normal}}" alt="Product image for '{{= $cProduct.product.name }}'" width="100" height="110">
                        </a>
                     </td>
                     <td>
                        {{= $cProduct.product.name }} 
                        {{ if $cProduct.product.variantSelection }}
                           <table>
                              <tbody>
                                 {{ foreach $cVarAttr in $cProduct.product.variantSelection | keys }}
                                    <tr>
                                       <td>{{= $cVarAttr}}:</td>
                                       <td>{{= $cProduct.product.variantSelection[$cVarAttr] }}</td>
                                    </tr>
                                 {{ /foreach }}
                              </tbody>
                           </table>
                        {{ /if }}
                        Quantity: {{= int($cProduct.quantity) }} 
                        Unit price: {{= $cProduct.price | currency }} 
                        {{= $cProduct.total | currency }} 
                     </td>
                  </tr>
               {{ /foreach }}
            </table>
            <div class="container-fluid">
               <div class="row">
                  <div class="col">Shipping costs:</div>
                  <div class="col">{{= $wsCheckout.sum.shippingCost | currency }}</div>
               </div>
               <div class="row">
                  <div class="col">Total:</div>
                  <div class="col">{{= $wsBasket.total | currency }}</div>
               </div>
            </div>
            <a href="{{= $wsViews.viewUrl('basket.htm')}}">View basket</a>

            {{ if $wsAccount.isLoggedIn or $wsCheckout.guestMail }}
               <a href="{{= $wsViews.viewUrl('checkout.htm', {step: 1}) }}">Checkout<svg role="img" xmlns="http://www.w3.org/2000/svg" width="20" height="23" fill="currentColor" class="ms-2 align-text-bottom" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8z"/></svg></a>
            {{ else }}
               <a href="{{= $wsViews.viewUrl('account/login.htm', {checkout: true}) }}">Checkout<svg role="img" xmlns="http://www.w3.org/2000/svg" width="20" height="23" fill="currentColor" class="ms-2 align-text-bottom" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8z"/></svg></a>
            {{ /if }}
         {{ else }}
            <p>You have no products in the basket!</p>
         {{ /if }}
      </div>
   </div>
</div>  

Changing quantity and removing products

This requires additional scripts for the corresponding Ajax functions.
<div class="offcanvas offcanvas-end" tabindex="-1" id="wsBasketOffcanvas">
   <div class="offcanvas-header">
      <p>Basket</p>
      <button type="button" data-bs-dismiss="offcanvas" title="Close"></button>
   </div>
   <div class="offcanvas-body">
      <div id="wsBasketOffcanvasContent">
         {{ if $wsBasket.items }}
            <table class="table">
               {{ foreach $cProduct in $wsBasket.items }}
                  {{ var $cProductDelete = $wsActions.create("BasketItemDelete", tag = $cProduct.id) }}
                  {{ var $cProductUpdateAction = $wsActions.create("BasketItemUpdate", tag = $cProduct.id) }}
                  <tr>
                     <td class="wsTableCellMin">
                        <a href="{{= $wsViews.url('Product', {productId: $cProduct.product.id}) }}">
                        <img src="{{= $cProduct.product.custom.image.normal}}" alt="Product image for '{{= $cProduct.product.name }}'" width="100" height="110">
                        </a>
                     </td>
                     <td>
                        {{= $cProduct.product.name }} 
                        {{ if $cProduct.product.variantSelection }}
                           <table>
                              <tbody>
                                 {{ foreach $cVarAttr in $cProduct.product.variantSelection | keys }}
                                    <tr>
                                       <td>{{= $cVarAttr}}:</td>
                                       <td>{{= $cProduct.product.variantSelection[$cVarAttr] }}</td>
                                    </tr>
                                 {{ /foreach }}
                              </tbody>
                           </table>
                        {{ /if }}
                        Quantity: {{= int($cProduct.quantity) }} 
                        Unit price: {{= $cProduct.price | currency }} 
                        {{= $cProduct.total | currency }} 
                        <form id="wsFormBasketQuantityChangeOffcanvas-{{= $cProduct.id }}" action="{{= $wsViews.current.url() }}" method="post" ws-ajax-form>
                           <input type="hidden" name="wsReplaceIds" value="wsBasketWrapper,wsBasketEntries,wsBasketOffcanvasContent">
                           <input type="hidden" name="wscsrf" value="{{= $cProductUpdateAction.csrf }}">
                           <input type="hidden" name="wsact" value="{{= $cProductUpdateAction.id }}">
                           <input type="hidden" name="wstarget" value="{{= $wsViews.current.url() }}">
                           <input type="hidden" name="basketItemId" value="{{= $cProduct.id }}">
                           <div class="wsBasketQuantityChange" role="group">
                              <button type="button" title="Decrease quantity by 1" ws-operator="minus"><svg role="img" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="mb-1" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M2 8a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11A.5.5 0 0 1 2 8Z"/></svg></button>
                              <input type="text" name="quantity" value="{{= $cProduct.quantity | preparedFormat('amount') }}" class="wsBasketQuantityChangeInput form-control text-center rounded-0 border-0 mx-1" aria-label="Quantity">
                              <button type="button" title="Increase quantity by 1" ws-operator="plus"><svg role="img" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="mb-1" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2Z"/></svg></button>
                           </div>
                        </form>
                        <form id="wsFormBasketDeleteProductOffcanvas-{{= $cProduct.id }}" action="{{= $wsViews.viewUrl('basket.htm') }}" method="post" ws-ajax-form>
                           <input type="hidden" name="wsReplaceIds" value="wsBasketWrapper,wsBasketEntries,wsBasketOffcanvasContent">
                           <input type="hidden" name="wscsrf" value="{{= $cProductDelete.csrf }}">
                           <input type="hidden" name="wsact" value="{{= $cProductDelete.id }}">
                           <input type="hidden" name="wstarget" value="{{= $wsViews.viewUrl('basket.htm') }}">
                           <input type="hidden" name="productId" value="{{= $cProduct.product.id }}">
                           <input type="hidden" name="basketItemId" value="{{= $cProduct.id }}">
                           <button type="submit">
                              <svg role="img" xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
                                 <path d="M6.5 1h3a.5.5 0 0 1 .5.5v1H6v-1a.5.5 0 0 1 .5-.5ZM11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3A1.5 1.5 0 0 0 5 1.5v1H2.506a.58.58 0 0 0-.01 0H1.5a.5.5 0 0 0 0 1h.538l.853 10.66A2 2 0 0 0 4.885 16h6.23a2 2 0 0 0 1.994-1.84l.853-10.66h.538a.5.5 0 0 0 0-1h-.995a.59.59 0 0 0-.01 0H11Zm1.958 1-.846 10.58a1 1 0 0 1-.997.92h-6.23a1 1 0 0 1-.997-.92L3.042 3.5h9.916Zm-7.487 1a.5.5 0 0 1 .528.47l.5 8.5a.5.5 0 0 1-.998.06L5 5.03a.5.5 0 0 1 .47-.53Zm5.058 0a.5.5 0 0 1 .47.53l-.5 8.5a.5.5 0 1 1-.998-.06l.5-8.5a.5.5 0 0 1 .528-.47ZM8 4.5a.5.5 0 0 1 .5.5v8.5a.5.5 0 0 1-1 0V5a.5.5 0 0 1 .5-.5Z"/>
                              </svg>
                              Delete
                           </button>
                        </form>
                     </td>
                  </tr>
               {{ /foreach }}
            </table>
            <div class="container-fluid">
               <div class="row">
                  <div class="col">Shipping costs:</div>
                  <div class="col">{{= $wsCheckout.sum.shippingCost | currency }}</div>
               </div>
               <div class="row">
                  <div class="col">Total:</div>
                  <div class="col">{{= $wsBasket.total | currency }}</div>
               </div>
            </div>
            <a href="{{= $wsViews.viewUrl('basket.htm')}}">View basket</a>

            {{ if $wsAccount.isLoggedIn or $wsCheckout.guestMail }}
               <a href="{{= $wsViews.viewUrl('checkout.htm', {step: 1}) }}">Checkout<svg role="img" xmlns="http://www.w3.org/2000/svg" width="20" height="23" fill="currentColor" class="ms-2 align-text-bottom" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8z"/></svg></a>
            {{ else }}
               <a href="{{= $wsViews.viewUrl('account/login.htm', {checkout: true}) }}">Checkout<svg role="img" xmlns="http://www.w3.org/2000/svg" width="20" height="23" fill="currentColor" class="ms-2 align-text-bottom" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8z"/></svg></a>
            {{ /if }}

            {{# crosslinks #}}
            {{ foreach $cProduct in $wsBasket.items }}
               {{ if $cProduct.product.custom.crosslinks }}
                  <p>Goes well with this</p>
                  <div class="row">
                     {{ var $cCrosslinks = $cProduct.product.custom.crosslinks | split(",") | take(2) }}
                     {{ foreach $cCrosslinkProduct in $cCrosslinks }}
                        {{ var $cCrosslinkProductInfo = $wsProducts.load($cCrosslinkProduct) }}
                        <div class="col-6">
                           {{ include "components/product/productBox.htm" with $cProduct = $cCrosslinkProductInfo }}
                        </div>
                     {{ /foreach }}
                  </div>
               {{ /if }}
            {{ /foreach }}
         {{ else }}
            <p>You have no products in the basket!</p>
         {{ /if }}
      </div>
   </div>
</div>