sexta-feira, 7 de novembro de 2014

Como adicionar Checkboxes de 3 estados em uma arvore em JavaScript

O segredo está no conceito de nó e arvores:

 

 
  1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
  2 <html lang="pt"><head>
  3 
  4   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5   <title>Exemplo de abrir/fechar elemento usando Javascript e CSS</title>
  6 
  7   <style type="text/css" >
  8 
  9    .link {
 10     color: #809823;
 11     text-decoration: none;
 12     display:inline;
 13     font-weight: bold;
 14    }
 15    .link :hover {
 16     background: #000000;
 17     cursor: pointer;
 18     color:#000;
 19     text-decoration: none;
 20     font-weight: bold;
 21    }
 22 
 23    body {
 24     background: #f6f9ea ;
 25     color: #000;
 26     margin: 20px;
 27     text-align: left;
 28     padding: 0;
 29     font-size: 80%;
 30     line-height: 1.6em;
 31     font-family: "Lucida Grande", Helvetica, Arial, sans-serif;
 32    }
 33 
 34    a, a:link, a:visited {color: #809823;}
 35    a:hover {
 36     background: #ccea8d;
 37     color: #000;
 38     text-decoration: none;
 39    }
 40    a:active {
 41     background: #c3e933;
 42     color: #fff;
 43     text-decoration: none;
 44    }
 45 
 46    code {color: #c63;}
 47    code strong {color: #930;}
 48 
 49    em {font-style: italic;}
 50    strong {font-weight: bold;}
 51 
 52    .highlight {
 53     background: #fffddd;
 54    }
 55 
 56    h1 {
 57     font-family: "Trebuchet MS", Helvetica, Arial, sans-serif;
 58     letter-spacing: -1px;
 59     font-weight: normal;
 60     font-size: 1.5em;
 61     color: #525252;
 62    }    
 63 
 64    .erro {
 65     padding: 3px 0 3px 25px;
 66     font-weight: bold;
 67     color: #444;
 68    }    
 69 
 70    # ['a','b','c','d'] {
 71     margin-top:100px;
 72     border-top:1px solid #ccc;
 73     font-size:0.9em;
 74     height:3em;
 75    }
 76 
 77    #footer p {
 78     margin:0;
 79     line-height: 3em;
 80     padding-left:120px;
 81    }
 82   </style>
 83 
 84   <script type="text/javascript">
 85 
 86 
 87 
 88 
 89 
 90 // *******************************************************************************
 91 // *******************************************************************************
 92 // *******************************************************************************
 93 // nos
 94        function Sofia_Nos(contrutor)
 95        {
 96         this.IdNome="";
 97         this.NoPai=null;
 98         this.NosFilhos=[];
 99 
100         this.typeof=null;
101         this.text="";
102         this.value=null;
103 
104         this.isShowing=null;
105 
106 
107         this.Add=function(nos)
108         {
109          if(!this.IdNome)
110           throw new Error("this.IdNome is null");
111          if(nos&&nos.length)
112          {
113           for(var i=0;i<nos.length;i++)
114           {
115            nos[i].NoPai=this
116            this.NosFilhos.push(nos[i])
117           }
118          }
119          else
120          {
121           nos.NoPai=this
122           this.NosFilhos.push(nos)
123          }
124         }
125 
126 
127 
128         this.Find=function(IdNome)
129         {
130          var retorno=null
131          for(i=0;i<this.NosFilhos.length;i++)
132          {
133           if(this.NosFilhos[i].IdNome==IdNome)
134           {
135            retorno=this.NosFilhos[i]
136            break
137           }
138          }
139          if(retorno==null)
140           for(i=0;i<this.NosFilhos.length;i++)
141           {
142            if(this.NosFilhos[i].NosFilhos.length>0)
143            {
144             retorno=this.NosFilhos[i].Find(IdNome)
145             break
146            }
147           }
148          return retorno;
149 
150         }
151         this.Remove=function(IdNome)
152         {
153          var excluir=this.Find(IdNome)
154          this.Find(excluir.NoPai).
155          splice(excluir)
156         }
157 
158 
159         // ======================================================================================
160         // metodos para pegar valores 
161         // ======================================================================================
162         // formatos: this.IdNome:this.valor, this.IdNome, this.arraysCompareds(), MyChoice
163         this.formaresposta=function(){
164          return this.IdNome;
165         }
166         // ao chamar getValues(valido) na raiz deste nó informa ao metodo se pode ou nao pegar o valor deste no.
167         this.allowToGetAnswer=true;
168 
169         this.functionToValidate=true;
170 
171         this.getIdsTrues=function(pegardequalquerforma)
172         {
173          if(this.allowToGetAnswer||pegardequalquerforma)
174          {
175           var retorno=[]
176           var qt=this.NosFilhos.length;
177           if(qt>0)
178           {
179            for(var i=0;i<qt;i++)
180            {
181             var res=this.NosFilhos[i].getIdsTrues(pegardequalquerforma)
182             for(var v=0;v<res.length;v++)
183              retorno.push(res[v])
184            }
185            return retorno;
186           }
187           else
188           {
189            if(this.value==true)
190             retorno.push(this.formaresposta())
191            return retorno;
192           }
193          }
194         }
195         this.getIdsFalses=function(pegardequalquerforma)
196         {
197          if(this.allowToGetAnswer||pegardequalquerforma)
198          {
199           var retorno=[]
200           var qt=this.NosFilhos.length;
201           if(qt>0)
202           {
203            for(var i=0;i<qt;i++)
204            {
205             var res=this.NosFilhos[i].getIdsFalses(pegardequalquerforma)
206             for(var v=0;v<res.length;v++)
207              retorno.push(res[v])
208            }
209            return retorno;
210           }
211           else
212           {
213            if(this.value!=true)
214             retorno.push(this.formaresposta())
215            return retorno;
216           }
217          }
218         }
219         this.getValues=function(pegardequalquerforma)
220         {
221          if(functionToValidate()&&this.allowToGetAnswer||pegardequalquerforma&&this.allowToGetAnswer)
222          {
223           var retorno=[]
224           var qt=this.NosFilhos.length;
225           if(qt>0)
226           {
227            for(var i=0;i<qt;i++)
228            {
229             var res=this.NosFilhos[i].getValues(pegardequalquerforma)
230             for(var v=0;v<res.length;v++)
231              retorno.push(res[v])
232            }
233            return retorno;
234           }
235           else
236           {
237            retorno.push(this.formaresposta())
238            return retorno;
239           }
240          }
241         }
242 
243 
244 
245         // ======================================================================================
246         // construir codigo html deste no 
247         // ======================================================================================
248         this.Builder=contrutor;
249 
250         this.getElement=function()
251         {
252          if(this.Element==null&&this.Builder!=null)
253          {
254           this.Element=new this.Builder(this).getElement();
255          }
256          return this.Element;
257         }
258        }
259 
260 
261 
262 
263 
264 // *******************************************************************************
265 // *******************************************************************************
266 // *******************************************************************************
267 // tabela
268        function Sofia_Tree(nos)
269        {
270         this.table=document.createElement("table");
271         this.table.id="table_"+nos.IdNome
272         //if(nos.NoPai!=null) this.table.style.display = 'none';
273         this.table.cellpadding=0;
274         this.table.cellspacing=0;
275         this.table.border=0;
276         //this.table.no = nos
277         this.tablebody=document.createElement("TBODY");
278 
279         for(var linhas=0;linhas<nos.NosFilhos.length;linhas++)
280         {
281          var tr=document.createElement("TR");
282          var td=document.createElement("TD");
283          td.vAlign='top';
284          nos.NosFilhos[linhas].Builder=Sofia_CheckBox
285          var btn=nos.NosFilhos[linhas].getElement();
286          td.appendChild(btn);
287          tr.appendChild(td);
288          var td2=document.createElement("TD");
289          td2.vAlign='top';
290          if(nos.NosFilhos[linhas].text)
291          {
292           td2.appendChild(document.createTextNode(nos.NosFilhos[linhas].text));
293          }
294          if(nos.NosFilhos[linhas].NosFilhos.length>0)
295          {
296           var noi=(new Sofia_Tree(nos.NosFilhos[linhas])).getElement()
297           td2.appendChild(noi);
298          }
299          tr.appendChild(td2);
300          this.tablebody.appendChild(tr);
301          btn.changeTriState()
302         }
303         this.table.appendChild(this.tablebody);
304         this.getElement=function()
305         {
306          return this.table;
307         }
308        }
309 
310 
311 
312 
313 
314        function Sofia_Div(no)
315        {
316         this.div=document.createElement("div");
317         this.div.appendChild(document.createTextNode(no.text))
318         this.div.style.background="#00ffff"
319         this.div.cellpadding=0;
320         this.div.cellspacing=0;
321         this.div.no=no;
322         this.div.onclick=function()
323         {
324          alert(this.no.IdNome)
325         }
326         this.getElement=function()
327         {
328          return this.div;
329         }
330        }
331 
332 
333 
334 
335        function Sofia_CheckBox(no)
336        {
337         this.div=document.createElement("div");
338         //this.div.appendChild( document.createTextNode(no.text) )
339         this.div.style.background="#00ffff"
340         this.div.cellpadding=0;
341         this.div.cellspacing=0;
342         this.div.border=0;
343         this.div.style.width="13px";
344         this.div.style.height="13px";
345         this.div.style.backgroundImage="url('b0.png')";
346         this.div.no=no;
347         if(no.NosFilhos.length)
348         {
349          this.div.onclick=function()
350          {
351           this.caixa=document.getElementById("table_"+this.no.IdNome)
352           if(this.caixa.style.display!="none")
353           {
354            this.caixa.style.display='none';
355           }
356           else
357           {
358            this.caixa.style.display='';
359           }
360          }
361         }
362         else
363         {
364          this.div.onclick=function()
365          {
366           if(this.no.disabled!=true)
367           {
368            if(this.no.value==false)
369            {
370             this.no.value=true
371             this.style.backgroundImage="url('b2.png')";
372             if(this.no.NoPai.getElement().changeTriStates!=null)
373              this.no.NoPai.getElement().
374              changeTriStates()
375            }
376            else
377            {
378             this.no.value=false
379             this.style.backgroundImage="url('b0.png')";
380             if(this.no.NoPai.getElement().changeTriStates!=null)
381              this.no.NoPai.getElement().
382              changeTriStates()
383            }
384           }
385          }
386         }
387         this.div.changeTriState=function()
388         {
389          if(this.no.getIdsFalses(true).length==0)
390          {
391           this.no.value=true
392           this.style.backgroundImage="url('b2.png')";
393 
394          }
395          else if(this.no.getIdsTrues(true).length==0)
396          {
397           this.no.value=false
398           this.style.backgroundImage="url('b0.png')";
399          }
400          else
401          {
402           this.no.value=null
403           this.style.backgroundImage="url('b1.png')";
404          }
405         }
406         this.div.changeTriStates=function()
407         {
408          this.changeTriState()
409          if(this.no.NoPai.getElement().changeTriStates!=null)
410           this.no.NoPai.getElement().
411           changeTriStates()
412         }
413         this.getElement=function()
414         {
415          return this.div;
416         }
417        }
418 
419 
420 
421 
422        var n0=new Sofia_Nos(Sofia_Tree)
423        function load()
424        {
425         n0.IdNome="raiz"
426         for(i=0;i<2;i++)
427         {
428          var n1=new Sofia_Nos()
429          n1.NoPai=n0;
430          n1.IdNome="IdNome"+i
431          n1.text="titulo "+i;
432          for(a=0;a<2;a++)
433          {
434           var n2=new Sofia_Nos()
435           n2.NoPai=n1;
436           n2.IdNome="IdNome"+i+a
437           n2.text="titulo "+i+a;
438           for(b=0;b<3;b++)
439           {
440            var n3=new Sofia_Nos()
441            n3.NoPai=n2;
442            n3.IdNome="IdNome "+i+a+b
443            n3.text="titulo "+i+a+b;
444            n3.value=true
445            n2.Add(n3);
446           }
447           n1.Add(n2);
448          }
449          n0.Add(n1)
450         }
451         //alert( JSON.stringify(JSON.decycle(noPai)) )
452         //n0.builderElement()
453         var tb=n0.getElement()
454         document.getElementById('ggg').
455         appendChild(tb)
456         n0.Remove('IdNome00')
457        }
458 
459 
460 
461        function teste()
462        {
463         //var yyy = n0.Find("cabeca 0")
464         var yyy=n0.getIdsTrues(true)
465         alert(yyy)
466        }
467 
468 
469 
470   </script>
471  </head>
472  <body id="aqui" onload="load()" >
473   <div id="ggg" > </div>
474  <input type="button" onclick="teste()" value="teste"/>
475 </body></html>
476 
477 
478 
imagens:

Nenhum comentário: