问题
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">×</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?
回答1:
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);
回答2:
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">×</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;
}
回答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);
来源:https://stackoverflow.com/questions/65463427/ajax-the-old-value-appears-first-and-then-the-new-one