It's a lot more efficient to set $div = $('#shoppingCart');; in the global scope and use that var instead. This way your JS won't search through your entire DOM every time the function is called.
Your stuff doesn't work because your vars are very odd. I believe what you want to achieve is this:
HTML
<a class="waves-effect waves-teal btn-flat no-margin white-text right" th:inline="text">
<i class="material-icons right">shopping_cart</i>
<span>[[@{${total}+' руб'}]]</span>
</a>
JS:
function updateShoppingCart(newTotal) {
var $div = $("#shoppingCart");
var $a = $("a", $div); //select the <a> within the shoppingcart div
var $i = $("i", $div); //select the <i> within the shoppingcart div
var $span = $("span", $div); //select the newly added span
var newPrice = formatDecimal(newTotal,',','.') + " руб";
$span.text(newPrice);
}
I kept the $a and $i in as examples, but I don't see a need for you to use them or completely replace them, since you only want to change the text. By using a span, you can target the price without replacing all the html.
On a sidenote, the $ is generally used to state a var is a jquery object. string is not a jquery object in this scenario, so the $ there is a bit odd.
On a sidenote, if you want to replace html within an element, you should try doing it like so:
function updateShoppingCart(newTotal) {
var $div = $("#shoppingCart");
var newPrice = formatDecimal(newTotal,',','.') + " руб";
//Create the new HTML as a string, not as an element
var newHtml= '<a href="#" class="somethingClass"><i>Shopping_cart</i>'+newPrice+'</a>';
//empties div beforehand current html, no seperate removal needed.
//Then places the html string within the element
$div .html(newHtml);
}
See working JSFiddle here