Foros del Web » Programando para Internet » Javascript »

Cambiar color de una celda mediante un boton

Estas en el tema de Cambiar color de una celda mediante un boton en el foro de Javascript en Foros del Web. Hola a todos, siguiendo con otros dos temas que tengo en este foro: http://www.forosdelweb.com/f13/cambiar-color-td-con-dom-1114860/ http://www.forosdelweb.com/f13/crear-tabla-con-javascript-1114397/ En los que para resumir un poco tenía que crear ...
  #1 (permalink)  
Antiguo 30/11/2014, 04:56
 
Fecha de Ingreso: noviembre-2014
Mensajes: 27
Antigüedad: 9 años, 5 meses
Puntos: 0
Cambiar color de una celda mediante un boton

Hola a todos, siguiendo con otros dos temas que tengo en este foro:
http://www.forosdelweb.com/f13/cambiar-color-td-con-dom-1114860/
http://www.forosdelweb.com/f13/crear-tabla-con-javascript-1114397/

En los que para resumir un poco tenía que crear una tabla con JavaScript y cambiar el color de una celda al pulsarla. Ahora bien lo que quiero hacer es que cuando pulse un botón las celdas que haya pulsado cambien de color y me aparezca un contador de cuantas de estas casillas hay pulsadas. Bien hasta ahora mi código HTML es el siguiente que de momento no me esta dando ningún problema:

Código HTML:
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title></title>
	<script type="text/javascript" src="js/funciones.js"></script>
</head>
<body onload="crearTabla()">
	<header></header>
	<article>
		<section id="butaca">
			<p id="numsala"></p>
			<p id="titulo"></p>
			<table id="tabla"></table>
                         <div id="reservar">
				<p>Cuantos con precio reducido</p>
				<input type="text"><br>
				<button id="comprar">Comprar</button>
			</div>
		</section>
	</article>
</body>
</html> 
Y este es mi JavaScript al que le he añadido un evento para que me cambie de color al pulsar el botón:

Código Javascript:
Ver original
  1. var columna=new Array();
  2. columna[0]=1;
  3. columna[1]=2;
  4. columna[2]=3;
  5. columna[3]=4;
  6. columna[4]=5;
  7. columna[5]=6;
  8. var filas=new Array();
  9. filas[0]=1;
  10. filas[1]=2;
  11. filas[2]=3;
  12. filas[3]=4;
  13. filas[4]=5;
  14. var tabla=new Array();
  15. tabla[0]=columna;
  16. tabla[1]=filas;
  17.          
  18. function crearTabla(){
  19.     var tbl = document.getElementById("tabla");
  20.     var tblBody = document.createElement("tbody");
  21.     for (var i = 0; i < columna.length; i++) {
  22.         var fila = document.createElement("tr");
  23.         for (var j = 0; j < filas.length; j++) {
  24.             var celda = document.createElement("td");
  25.  
  26.             celda.onclick=function(){
  27.                 var div=document.getElementById("reservar");
  28.                 div.style.display='block';
  29.                 var compra=document.getElementById("comprar");
  30.                 compra.onclick=function(){
  31.                     if(celda.style.background=='orange'){
  32.                         celda.style.background='red';
  33.                     }
  34.                 }
  35.                 if(this.style.background=='green'){
  36.                     this.style.background='orange';
  37.                 }
  38.                 else{
  39.                     this.style.background='green';
  40.                 }
  41.             }
  42.  
  43.             var textoCelda = document.createTextNode(i+"-"+j);
  44.             celda.appendChild(textoCelda);
  45.             fila.appendChild(celda);
  46.         }
  47.         tblBody.appendChild(fila);
  48.     }
  49.     tbl.appendChild(tblBody);
  50.     tbl.setAttribute("border", "2");
  51. }

El caso es que lo he intentado hacer de esta otra forma y no me funciona tampoco:

Código Javascript:
Ver original
  1. var compra=document.getElementById("comprar");
  2.            
  3.             celda.onclick=function(){
  4.                 var div=document.getElementById("reservar");
  5.                 div.style.display='block';
  6.                 if(this.style.background=='green'){
  7.                     this.style.background='orange';
  8.                 }
  9.                 else{
  10.                     this.style.background='green';
  11.                 }
  12.             }
  13.  
  14.             compra.onclick=function(){
  15.                 if(celda.style.background=='orange'){
  16.                     celda.style.background='red';
  17.                 }
  18.             }

¿Que solución puede tener este problema?
  #2 (permalink)  
Antiguo 30/11/2014, 11:34
Avatar de marlanga  
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 3 meses
Puntos: 206
Respuesta: Cambiar color de una celda mediante un boton

Los estilos, a la hoja de estilos. Hacerlo con javascript es siempre mala idea.
Código CSS:
Ver original
  1. td.elegible { cursor:pointer; }
  2. td.elegido { background-color: green; }
  3. td.procesado { background-color: red; cursor: not-allowed; }

Para el javascript he usado varias ideas:

Encapsular todo el código en un espacio de nombre llamado PRG, así no habrá conflictos con otros códigos que use la página, y personalmente lo veo mas bonito. Cuando no uso orientación a objetos, como en éste caso, suelo partir el código en tres bloques: datos, elementos HTML y funciones que usan esos datos y elementos para hacer cosas.

Como norma general, intenta que una función haga una única cosa, así el código es mas sencillo de entender, de modificar, de detectar errores, y de reusar en otros códigos. Todo ventajas, y ni una sola desventaja.

Es por ello que las declaraciones de eventos las he sacado a otra función, y ahí he usado una técnica llamada "delegación de eventos", que básicamente consiste en crear un evento en un único elemento contenedor que luego se ejecutará cuando salte ese mismo evento en sus hijos. ësto funciona porque los eventos en javascritp se disparan en cadena, primero el hijo, luego el padre, despues el abuelo, etc, hasta llegar al "<body>". Así en memoria sólo hay declarado un único evento sobre la tabla, pero en la práctica es como si en todos los TD's de tu tabla tuvieran ese evento declarado. Otra ventaja que tiene esta técnica es que si insertas futuros TD's en esa tabla, automáticamente también tendrán ese evento asociado.

Y por último he aprovechado el classList que tienen todos los elementos html de JAVASCRIPT para manejar su listado de clases. Con él tienes add, remove, toggle y contains. El primero añade clases, mirando de no meterla otra vez si ya la tiene. El segundo, elimina. El tercero mete la clase si no la tiene, o la elimina si la tiene. El cuarto te dice si una clase existe en un elemento.

Así que la lógica javascript sólo se encarga de meter clases a los elementos TD's, y el CSS les da color.

Como curiosidad, todos los GetElement[s]By(Id | ClassName | TagName) devuelven lista dinámicas. Es decir, si hago un getElementByClassName, y luego con un bucle lo recorro, y borro la clase que usé en la función de antes, el listado se actualizará (se borrará esa posición que usas en el bucle) y probablemente ocurran errores en tu código del bucle. Lo he solucionado simplemente recorriendo el blucle alrevés y haciendo el borrado de la clase en último lugar. Otra posible solución es clonar el array de elementos obtenido, y así éste no se modificará dinámicamente dentro del bucle.

Por último, y haciendo referencia a lo que dije en primer lugar: Los estilos a la hoja de estilos. No escribas estilos dentro de elementos <HTML> ni se los metas con javascript. Es un coñazo de mantener, y muy pesado de entender. Por la misma razón, no metas javascript a los elementos HTML. El onload del body se reescribe fácilmente a javascript con un simple window.onload, por ejemplo. O con un window.addEventListener('load') por si alguno de los otros códigos también necesitara usar el evento load.

Código Javascript:
Ver original
  1. var PRG = {
  2.     datos : {
  3.         columnas : 6,
  4.         filas : 5,
  5.         clase_elegible : 'elegible',
  6.         clase_elegido : 'elegido',
  7.         clase_procesado : 'procesado'
  8.     },
  9.     elementos : {
  10.         div_reservar : null,
  11.         tabla : null,
  12.         btn_comprar : null
  13.     },
  14.     funciones : {
  15.         cargar : function() {
  16.             PRG.elementos.div_reservar = document.getElementById("reservar");
  17.             PRG.elementos.tabla = document.getElementById("tabla");
  18.             PRG.elementos.btn_comprar = document.getElementById("comprar");
  19.             PRG.funciones.crearTabla();
  20.             PRG.funciones.crearEvento();
  21.         },
  22.         crearTabla : function() {
  23.             var tblBody = document.createElement("tbody");
  24.             for (var i = 0; i < PRG.datos.columnas; i++) {
  25.                 var fila = document.createElement("tr");
  26.                 for (var j = 0; j < PRG.datos.filas; j++) {
  27.                     var celda = document.createElement("td");
  28.                     var textoCelda = document.createTextNode(i+"-"+j);
  29.                     celda.classList.add(PRG.datos.clase_elegible);
  30.                     celda.appendChild(textoCelda);
  31.                     fila.appendChild(celda);
  32.                 }
  33.                 tblBody.appendChild(fila);
  34.             }
  35.             PRG.elementos.tabla.appendChild(tblBody);
  36.             PRG.elementos.tabla.setAttribute("border", "2");
  37.         },
  38.         accionClickTd : function (td) {
  39.             if (!td.classList.contains(PRG.datos.clase_procesado)) {
  40.                 td.classList.toggle(PRG.datos.clase_elegido);
  41.             }
  42.         },
  43.         accionClickComprar : function () {
  44.             var elegidas = PRG.elementos.tabla.getElementsByClassName(PRG.datos.clase_elegido);
  45.             var n_ini = elegidas.length, n = n_ini;
  46.             console.log(elegidas);
  47.             while (n--) {
  48.                 elegidas[n].classList.add(PRG.datos.clase_procesado);
  49.                 elegidas[n].classList.remove(PRG.datos.clase_elegido);
  50.             }
  51.             alert('Ha comprado ' + n_ini + ' asientos');
  52.         },
  53.         crearEvento : function() {
  54.             PRG.elementos.tabla.addEventListener("click", function(e) {
  55.                 if(e.target) {
  56.                     if (e.target.classList.contains(PRG.datos.clase_elegible)) {
  57.                         PRG.funciones.accionClickTd(e.target);
  58.                     }
  59.                 }
  60.             });
  61.             PRG.elementos.btn_comprar.addEventListener("click", function() {
  62.                 PRG.funciones.accionClickComprar();
  63.             });
  64.         }
  65.     }
  66. };
  67.  
  68. window.onload = function () {
  69.     PRG.funciones.cargar();
  70. }

PD. Me he molestado en soltar este rollazo porque te veo maneras aunque no demasiada experiencia, por lo menos con JS; y porque has usado correctamente las herramientas del foro para escribir HTML por un lado y JAVASCRIPT por otro, haciendo que no me sangren los ojos al leer.

Última edición por marlanga; 30/11/2014 a las 11:44
  #3 (permalink)  
Antiguo 30/11/2014, 12:03
 
Fecha de Ingreso: noviembre-2014
Mensajes: 27
Antigüedad: 9 años, 5 meses
Puntos: 0
Respuesta: Cambiar color de una celda mediante un boton

La verdad es que tu código se ve bastante bien aunque si que es un poco complicado de entender. Lo que yo necesito es un código más sencillo y a ser posible que utilice algo de la estructura DOM o DHTML
  #4 (permalink)  
Antiguo 01/12/2014, 09:49
 
Fecha de Ingreso: noviembre-2014
Mensajes: 27
Antigüedad: 9 años, 5 meses
Puntos: 0
Respuesta: Cambiar color de una celda mediante un boton

¿Alguien me puede ayudar por favor? Necesito un código mas sencillo que el que ha puesto marlanga. Yo he estado investigando si hay alguna otra forma de hacerlo pero no he encontrado nada. He añadido también otro código pero sigue sin funcionarme. Este es el código que he añadido:

Código Javascript:
Ver original
  1. var compra=document.getElementById("comprar");
  2. compra.addEventListener('click',cambiaColor,false);
  3.  
  4. function cambiaColor(){
  5.     var tbl = document.getElementById("tabla");
  6.     var tblBody = document.createElement("tbody");
  7.    
  8.     for (var i = 0; i < columna.length; i++) {
  9.         var fila = document.createElement("tr");
  10.         for (var j = 0; j < filas.length; j++) {
  11.             var celda = document.createElement("td");
  12.             celda.style.background='orange';
  13.             if(celda.style.background=='orange'){
  14.                 celda.style.background='red';
  15.             }
  16.             else{
  17.                 celda.style.background='green';
  18.             }
  19.             fila.appendChild(celda);
  20.         }
  21.     }
  22. }
  #5 (permalink)  
Antiguo 01/12/2014, 11:32
Avatar de marlanga  
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 3 meses
Puntos: 206
Respuesta: Cambiar color de una celda mediante un boton

Perdone usted, caballero. Pensé que el código que posteaba era suyo, pero ya veo que no es así. Cuánto tiempo perdido, no volverá a suceder.
  #6 (permalink)  
Antiguo 01/12/2014, 13:10
 
Fecha de Ingreso: octubre-2014
Mensajes: 29
Antigüedad: 9 años, 5 meses
Puntos: 0
Respuesta: Cambiar color de una celda mediante un boton

En realidad el código que ha utilizado marlanga esta bastante bien. Lo único que quizá que para una persona que no haya visto el suficiente código JavaScript pues este código resulte complicado aunque si se mira detenidamente y linea por linea se puede llegar a entender (Te lo dice una persona que lleva 2 meses dando JavaScript). A mi la única solución que se me ocurre a tu problema y que ademas utiliza estructura DOM como tu pedías es la siguiente:


Código Javascript:
Ver original
  1. var compra=document.getElementById("comprar");
  2. compra.addEventListener('click',cambiaColor,false);
  3.  
  4. function cambiaColor(){
  5.     var tbl = document.getElementById("tabla");
  6.     var tblBody = tbl.firstChild;
  7.    
  8.     for (var i = 0; i < columna.length; i++) {
  9.         var fila = tblBody.childNodes[i];
  10.         for (var j = 0; j < filas.length; j++) {
  11.             var celda = fila.childNodes[j];
  12.             celda.style.background='orange';
  13.             if(celda.style.background=='orange'){
  14.                 celda.style.background='red';
  15.             }
  16.             else{
  17.                 celda.style.background='green';
  18.             }
  19.             fila.appendChild(celda);
  20.         }
  21.     }
  22. }

Lo que tenias que hacer es acceder a cada uno de los hijos de la etiqueta <table> en este caso. Lo de contar la cantidad de celdas pulsadas lo puedes hacer creando un contador y que cada vez que pulses una que aumente en una unidad o no se como quieres que lo haga, eso es ya a tu elección.

PD: Si alguien que sepa más JavaScript del que yo se y ve algún error en mi código que se lo comunique a dglypho, yo he intentado ayudar con lo que se. Si esta bien el código que lo comunique también para que sepa que por lo menos tengo algo de idea en estos 2 meses que llevo con JavaScript jejejejeje

Etiquetas: boton, celda, color, funcion, html, input, js, mediante
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 09:45.