skip to Main Content

I have Session::flash notifications(bootstrap toasts), which is used to notify about adding a product to the cart:

@if(Session::has('add-product'))
<div aria-live="polite" aria-atomic="true" class="d-flex justify-content-center align-items-center">
 <div class="toast fixed-top" role="alert" aria-live="assertive" aria-atomic="true" data-delay="3000">
  <div class="toast-header bg-success">
   <span class="mr-auto notif_text"></span>
   <button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
    <span aria-hidden="true">&times;</span>
   </button>
  </div>
 </div>
</div>
@endif

CartController with Session:flash:

public function addCart(Request $request, $id){
    $product = Product::find($id);
    $oldCart = Session::has('cart') ? Session::get('cart') : NULL;
    $cart = new Cart($oldCart);
    $cart->add($product, $product->id);

    $request = Session::put('cart', $cart);

    Session::flash('add-product', $product->name);

    return response()->json([
         'total_quantity' => Session::has('cart') ? Session::get('cart')->totalQty : '0',
         'notif_text' => 'Product' . Session::get('add-product', $product->name) . 'added to cart'
     ]);
  }

And Ajax request:

$(document).ready(function() {
  $('.product-icon-container').find('.ajaxcartadd').click(function(event) {
    event.preventDefault();
    $('.toast').toast('show');
    $.ajax({
      url: $(this).attr('href'),
      dataType: 'JSON',
      success: function(response) {
        $('.prodcount').html(response.total_quantity);
        $('.notif_text').html(response.notif_text); //!!!Here I load the notification text!!
      }
    });
    return false;
  });
});

My question is how to make sure that the old value does not appear, but a new one appears immediately.

Now it works like this:
img_1

Then after about 1 second a new notification appears:
img_2

How can this be fixed?

3

Answers


  1. Chosen as BEST ANSWER

    Solution for my case, maybe someone will find it useful:

    The reason is that the product is added when the ajax status is success (this is where the handler for clicking on the "Add to cart" button is).

    I am using bootstrap toasts, they are included with:

    $('.toast').toast('show');
    

    And since the inclusion of notifications was not inside the ajax request, it turned out that first an empty or old value was loaded, and then only a new one.

    The solution was to move the inclusion "bootstrap toasts" inside ajax:

    $(document).ready(function() {
      $('.product-icon-container').find('.ajaxcartadd').click(function(event) {
        event.preventDefault();
        $.ajax({
          url: $(this).attr('href'),
          dataType: 'JSON',
          success: function(response) {
            $('.prodcount').html(response.total_quantity);
            $('.notif_text').html(response.notif_text); //!!!Here I load the notification text!!
            $('.toast').toast('show');//!!!I moved it here!!!
          }
        });
        return false;
      });
    });
    

    But there is one nuance that I understood just now. Flash messages are not always loaded asynchronously, since they depend on the session (if I understood correctly), and if your user visits the site for the first time, flash will not work. Therefore, it is worth displaying messages without flash:

    Bootstrap toasts:

    <div aria-live="polite" aria-atomic="true" class="d-flex justify-content-center align-items-center">
     <div class="toast fixed-top" role="alert" aria-live="assertive" aria-atomic="true" data-delay="3000">
      <div class="toast-header bg-success">
       <span class="mr-auto notif_text"></span>
       <button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
        <span aria-hidden="true">&times;</span>
       </button>
      </div>
     </div>
    </div>
    

    CartController:

    public function addCart(Request $request, $id){
        $product = Product::find($id);
        $oldCart = Session::has('cart') ? Session::get('cart') : NULL;
        $cart = new Cart($oldCart);
        $cart->add($product, $product->id);
    
        $request = Session::put('cart', $cart);
    
        return response()->json([
             'total_quantity' => Session::has('cart') ? Session::get('cart')->totalQty : '0',
             'notif_text' => 'Product' . $product->name . 'added to cart'
         ]);
      }
    

    P.S. If you want bootstrap toasts with the same styles as mine, add this to your css:

    .toast{
      max-width: none;
    }
    .toast.fixed-top{
      margin-top: 30px;
      left: auto;
      right: auto;
    }
    .toast-header{
      border: 0;
      padding: 0.75rem 1.25rem;
      color: #fff;
      border-radius: 0.25rem;
    }
    .close{
      opacity: 1;
      color: #fff;
      text-shadow: 0 1px 0 #000;
    }
    .close:hover{
      color: #fff;
      opacity: 0.5;
    }
    

  2. first remove already assigned value like this then assign value to that class element.

    document.getElementsByClassName("prodcount").innerHTML = ""; // or $('.prodcount').innerHTML = "";
    document.getElementsByClassName("notif_text").innerHTML = ""; // or $('.notif_text').innerHTML = "";
    $('.prodcount').html(response.total_quantity);
    $('.notif_text').html(response.notif_text);
    
    Login or Signup to reply.
  3. You can try the easiest way in your ajax call as. You can use this instead of toast also just as:

          $('.prodcount').empty().show().html(response.total_quantity).delay(3000).fadeOut(300);
    
          $('.notif_text').empty().show().html(response.notif_text).delay(3000).fadeOut(300);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search