Cambiar el texto del un label con jquery con text() o html() no funciona

publicado por: Anonymous

se que para cambiar el valor de un label vale con html() o text() pero el problema es que no funciona. Me explico:

La funcion del programa es que al hacer doble click en un elemento con la clase “.item” se clone ese elemento y lo añada a un div, que el stock se reste en uno y que el precio y el numero de items se incremente.

Defino $stockLblInicial y $cantStockInicial al cargar la página para comprobar si hay stock y si hay hacer el doble click, si no lo hay pues nada.

Carga de la página:

    $(function(){

    $("#citem").val(0); //Ponemos el contador de items a cero cada vez que se refresque la pagina
    $("#cprice").val(0 + " €"); //Ponemos el valor del precio total a cero cada ves que se refresque la pagina 

    var $stockLblInicial = $(".stock", $(this)).text(); //Pillamos la etiqueta del stock 
    var $cantStockInicial = parseInt($stockLblInicial.slice(6)); //Cogemos solo el numero y lo pasamos a int 
    //Hago un slice ya que el label es tal que "Stock 10" y solo quiero el numero 

    //Si hay items en stock 
    if($cantStockInicial > 0){
        $(".item").on("dblclick", dobleClickItems);
    }else{
        return false;
    }
}); 

Dentro de la funcion del dobleClick se define $stockLbl y $cantStock porque mas adelante el valor de esas variables se pisará. En la funcion en si coge esos valores para que en compra() se reste en uno el stock y se le asigne al texto del item clickado. El texto no cambia entonces pilla siempre como que hay 10 items. El problema no está en el contador ya que resta como toca. El problema es directamente no cambia el texto. He probado con text() y con html() y no funciona.

    function dobleClickItems(){
    //Variable necesarias para clonar
    const $divCarrito = $("#cart_items"); //Pillamos el contenedor del carrito
    let $idItem = $(this).attr("id"); //Pillamos la id del item seleccionado (devuelve un string)
    let $clonedItem = $(this).clone(); //Clonamos el item 

    var $stockLbl = $(".stock", $(this)).text(); //Pillamos la etiqueta del stock 
    var $cantStock = parseInt($stockLbl.slice(6)); //Cogemos solo el numero y lo pasamos a int 

    let $precioLabel = $(".price", $(this)).text(); //Pillamos el precio del producto clickado
    let $precio = parseInt($precioLabel.slice(0, 4)); //Cogemos el numero y lo pasamos a int

    let $numItems = $("#citem").val(); //Pillamos el valor del input de la cantidad de elementos 
    parseInt($numItems); //Pasamos el valor a int para poder hacer operaciones

    //Pillamos el valor del input del precio total y lo pasamos a int tambien 
    let $precioTotal = parseInt($("#cprice").val().slice(0, 4));

    compra($cantStock, $numItems, $precioTotal, $precio);
    cloneItem($idItem, $clonedItem, $divCarrito);

    if($cantStock == 0){ //Si no quedan items le añadimos la clase "agotado" al item 
        $(".stock", $(this)).addClass("agotado");
    }
}

Aquí la funcion compra:

    function compra($cantStock, $numItems, $precioTotal, $precio){
    $cantStock--; //Contador para decrementar el valor del stock  
    $(".stock", $(this)).html("Stock " + $cantStock); //Reducimos en uno el numero de stock

    console.log("Cantidad en stock " + $cantStock);

    $numItems++; //Incrementamos el numero de items comprados
    $("#citem").val($numItems); //Aumentamos el numero de compras

    console.log($numItems);

    $precioTotal += $precio; //Al precio del input le vamos sumando el precio de todas la compras 
    $("#cprice").val($precioTotal + " €");
}

La consola no lanza ningún problema, es solo que el label no lo cambia y no sé por qué puede ser. Si alguien me pudiese ayudar estaria muy agradecido.

El html:

_x000D_

_x000D_

<!DOCTYPE html>_x000D_
<html>_x000D_
<head>_x000D_
	<title>Carro de la compra con jQuery</title>_x000D_
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />_x000D_
	<link rel="stylesheet" title="normal" href="css/carro.css" type="text/css" media="screen" />_x000D_
	<!-- CDN JQuery de Google -->_x000D_
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>_x000D_
    <script src="http://code.jquery.com/jquery-1.9.0.min.js" _x000D_
			type="text/javascript"></script>_x000D_
	<script src="scripts/carro.js" type="text/javascript"></script>_x000D_
</head>_x000D_
<body>_x000D_
	<div id="item_container">_x000D_
		<div class="item" id="i1">_x000D_
			<img src="img/camiseta1.jpg" alt="descripción i1"/>_x000D_
			<label class="title">Camiseta 1</label>_x000D_
			<label class="price">20 €</label>_x000D_
			<label class="stock">Stock 10</label>_x000D_
		</div>_x000D_
		<div class="item" id="i2">_x000D_
			<img src="img/reloj2.jpg" alt="descripción i2"/>_x000D_
			<label class="title">Reloj 2</label>_x000D_
			<label class="price">24 €</label>_x000D_
			<label class="stock">Stock 10</label>_x000D_
		</div>_x000D_
		<div class="clear"></div>_x000D_
	</div>_x000D_
	<div id="cart_container">_x000D_
		<div id="cart_title">_x000D_
			<span>Carrito</span>_x000D_
			<div class="clear"></div>_x000D_
		</div>_x000D_
		<div id="cart_toolbar">_x000D_
			<div id="cart_items" class="back"></div>_x000D_
		</div>_x000D_
		<div id="navigate">_x000D_
			<div id="nav_left">_x000D_
				<button id="btn_comprar" title="Confirma la compra de los artículos">Comprar</button>_x000D_
				<button id="btn_prev" title="Desplaza el carrito hacia la izquierda">&lt;</button>_x000D_
				<button id="btn_next" title="Desplaza el carrito hacia la derecha">&gt;</button>_x000D_
				<button id="btn_clear" title="Vacia el carrito">Vaciar</button>_x000D_
			</div>_x000D_
			<div id="nav_right">_x000D_
				<span class="sptext">_x000D_
					<label>Compras </label><input id="citem" value="0" readonly title="Número de productos comprados"/>_x000D_
				</span>_x000D_
				<span class="sptext">_x000D_
					<label>Precio </label><input id="cprice" value="0 €" readonly  title="Precio total de los productos comprados"/>_x000D_
				</span>_x000D_
			</div>_x000D_
			<div class="clear"></div>_x000D_
		</div>_x000D_
	</div>_x000D_
</body>_x000D_
</html>

_x000D_

_x000D_

_x000D_

PD: Si hiciese falta el html edito la pregunta y lo añado también.

EDIT: El error concretamente es que intento editar el label con clase “stock” dentro del div con clase “item” pero no lo hace. Esto concretamente lo hago aquí: $(".stock", $(this)).html("Stock " + $cantStock);
Es la segunda linea de la funcion compra().
Espero que esto lo aclare un poco más.

EDIT 2: Quiero modificar el label del elemento al que clicko dos veces es por eso por lo que está la variable $this cuando defino $stockLbl. Lo que quiero es cambiar el contenido de ese label y accedo a el mediante su clase “.stock”. Concretamente quiero que al hacer doble click el numero del label se reduzca en uno. Por eso tengo una variable $cantStock que uso como contador y que está inicializada al hacer un split del contenido del label hasta quedarme solo con el numero.

Igual viendo el layout como es se entiende un poco mejor:
Layout de la app

Cuando haces doble click en uno de los contenedores donde está el producto el numero del stock se debería reducir en 1.

solución

Te propongo una solución basada en el uso de los atributos data-*. No me parece correcto un código en el que almacenes valores que son necesarios para cálculos junto con palabras, como es el caso de Stock. Con los atributos data-* puedes almacenar en cada div elementos como la cantidad en stock o el precio como números y usar esos valores para cálculos futuros. Y cosas más profesionales serían más fáciles de implementar, como el hecho de deshabilitar los elementos cuando el stock llegue a 0.

En este fragmento, se escuchan los doble clicks del div y en cada doble click se reduce en uno el stock.

Ten en cuenta que este código te será muy útil también si quieres trabajar con el precio por ejemplo. O si quieres pasar el elemento clickeado a otra parte, como a un carrito de compras o algo parecido. Y te evitará tener que estar limpiando el contenido del label para obtener solamente el valor numérico.

Yo he usado código Javascript puro. Puedes usar jQuery si quieres, pero se recomienda evitar el uso de librerías externas cuando puedes hacerlo con JS puro (el código es más rápido).

Espero te sea de utilidad. Puedes probar su funcionamiento…

_x000D_

_x000D_

/*Asignamos un listener a todos los elementos de la clase item*/_x000D_
var elementsArray = document.querySelectorAll('.item');_x000D_
elementsArray.forEach(function(elem) {_x000D_
  elem.addEventListener("dblclick", dobleClick, false);_x000D_
});_x000D_
/*Esta es la función definida en el listener*/_x000D_
function dobleClick() {_x000D_
  /*Con dataset.[nombre] obtenemos el valor que hay en ese atributo*/_x000D_
  var stockReduced = this.dataset.stock - 1;_x000D_
  /*Actualizamos el atributo a [valor-1]*/ _x000D_
  this.dataset.stock= stockReduced;_x000D_
  /*Referencia al label stock*/_x000D_
  var lblStock = this.getElementsByTagName('label')[2];_x000D_
  /*Actualizamos el valor numérico de forma dinámica*/_x000D_
  lblStock.textContent = `Stock ${stockReduced}`;_x000D_
}

_x000D_

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<div id="item_container">_x000D_
  <div class="item" id="i1" data-stock="10" data-price="20">_x000D_
    <img src="img/camiseta1.jpg" alt="descripción i1" />_x000D_
    <label class="title">Camiseta 1</label>_x000D_
    <label class="price">20 €</label>_x000D_
    <label class="stock">Stock 10</label>_x000D_
  </div>_x000D_
  <div class="item" id="i2" data-stock="10" data-price="24">_x000D_
_x000D_
    <img src="img/reloj2.jpg" alt="descripción i2" />_x000D_
    <label class="title">Reloj 2</label>_x000D_
    <label class="price">24 €</label>_x000D_
    <label class="stock">Stock 10</label>_x000D_
  </div>_x000D_
  <div class="clear"></div>_x000D_
</div>

_x000D_

_x000D_

_x000D_

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *