Bueno, pues ya he modificado mi script para tablas anidadas. Si antes era complicado de entender, ahora no te imaginas...
El script es corto, pero rebuscado, como me suelen gustar últimamente
Código:
/******************
FUNCION PARA COLOREAR CELDAS, FILAS O TABLAS (según tagPadre)
******************/
function colorea(obj,tagPadre,niveles) {
var col= obj.checked ? "#aaf" : "transparent";
// encontrar con parentNode un obj con tag tagPadre tantas veces como niveles se nos pasen por argumento
for(var nivelActual=0; nivelActual<niveles; nivelActual++) {
obj=obj.parentNode;
while( obj.nodeType==1 && obj.tagName.toUpperCase()!=tagPadre.toUpperCase() )
obj=obj.parentNode;
}
obj.style.backgroundColor=col;
}
/******************
FUNCION PARA MARCAR TODOS LOS CHECKBOXES CONTENIDOS EN UNA TABLA QUE SEAN PARA COLOREAR
******************/
function todosChkDeTabla(obj,check) {
while( obj.nodeType==1 && obj.tagName.toUpperCase()!="TABLE" )
obj=obj.parentNode;
//obj ahra es la TABLE sobre la que trabajamos
function recorrerHijos(elem) {
if( elem.nodeType==1 && elem.tagName.toUpperCase()=="INPUT" && elem.type=="checkbox" && elem.onclick && /colorea\(/.test(elem.onclick) ) { // tipo ELEMENT_NODE y encima es checkbox y sirve para colorear
elem.checked=check;
// extraemos la funcion que salta al onclick para forzar a ejecutarla (siempre que no sea todosChkDeTabla, entraríamos en recursión)
var saltaEnOnclick=elem.onclick.toString().match(/^[^\{]+\{([^\}]+)}$/)[1].replace(/this/g,"elem");
eval(saltaEnOnclick);
}
else if (elem.nodeType==1 && elem.hasChildNodes() ) { //ELEMENT_NODE y encima con hijos
for(var hijo=0; hijo<elem.childNodes.length; hijo++) //recorremos cada hijo con la función, recursivamente
recorrerHijos( elem.childNodes[hijo] );
}
}
recorrerHijos(obj); //recorremos sus hijos y encontramos checkboxes para marcarlos
}
La estructura HTML es todo lo complicada que se quiera (he anidado varios tipos de tabla). Además he incluído el soporte para checkboxes que no tienen nada que ver con colorear, que antes no tenía esa capacidad la función
todosChkDeTabla:
Código PHP:
<table border="1">
<tr>
<td colspan="3"><input type="checkbox" onclick="todosChkDeTabla(this,this.checked);" /></td>
</tr>
<tr>
<td>
<table border="1">
<tr>
<td>
<input type="checkbox" onclick="colorea(this,'TR',1);" />
<input type="checkbox" onclick="colorea(this,'TR',2);" />
</td>
<td>AA</td>
<td>BB</td>
</tr>
</table>
</td>
<td>loren</td>
<td>ipsum</td>
</tr>
<tr>
<td><input type="checkbox" onclick="colorea(this,'TR',1);" /></td>
<td>dolor</td>
<td>sit</td>
</tr>
<tr>
<td><input type="checkbox" onclick="colorea(this,'TR',1);" /></td>
<td>amet</td>
<td>loren</td>
</tr>
<tr>
<td><input type="checkbox" onclick="colorea(this,'TR',1);" /></td>
<td>
<table border="1">
<tr>
<td>¿Tienes coche? <input type="checkbox" /></td>
</tr>
<tr>
<td>¿Moto? <input type="checkbox" /></td>
</tr>
<tr>
<td>¿Camión? <input type="checkbox" /></td>
</tr>
</table>
</td>
<td>dolor</td>
</tr>
<tr>
<td colspan="3">
<table border="1">
<tr>
<td>Minifila A</td>
<td><input type="checkbox" onclick="colorea(this,'TR',1);" /></td>
</tr>
<tr>
<td>Minifila B</td>
<td><input type="checkbox" onclick="colorea(this,'TR',1);" /></td>
</tr>
<tr>
<td>Minifila C</td>
<td><input type="checkbox" onclick="colorea(this,'TR',1);" /></td>
</tr>
</table>
</td>
</tr>
</table>
Lo he intentado identar todo muy bien para que no haya confusiones y pueda ser lo más legible posible. He tenido que utilizar los bbcode [ code ] en vez de [ php ] porque utilizo expresiones regulares y las contrabarras se me eliminan si no, lo siento.
La función
colorea ahora selecciona el color ella misma, no hace falta pasárselo por argumento (me parece más cómodo). Además busca un padre con la etiqueta
tagPadre, pero lo busca tantas veces como
niveles. Así si tienemos dos tablas anidadas y desde la de dentro le decimos que coloree "TR" con
nivel=2, coloreará el segundo TR que se encuentre haciendo parentNode, es decir, el de la tabla padre. Para "TR" con
nivel=1 coloreara la fila de la misma tabla hija.
Para la función
todosChkDeTabla lo que he hecho es restringir que se
checken todos los checkboxes que en su onclick esté la función
colorea; para ello necesito todo el condicional bestia este
Código:
elem.nodeType==1 && elem.tagName.toUpperCase()=="INPUT" && elem.type=="checkbox" && elem.onclick && /colorea\(/.test(elem.onclick)
Aquí ojo que he pensado que si se llama en un onclick a
colorea y a
todosChkDeTabla a la vez, habría que meter un condicional así para ejecutar el eval:
Código:
if( !/todosChkDeTabla/.test(saltaEnOnclick) )
Pero bueno... son detalles.
Al final me ha gustado mucho cómo me ha quedado el script, pequeño pero matón jeje. Además sirve tanto como para colorear TD como TR como TBODY y TABLE y BODY entero..., lo que se quiera mientras ese elemento sea padre del checkbox
Bueno, ya está bien de parrafada