[js/dHTML] Items over tree verplaatsen

Pagina: 1
Acties:

  • r0bert
  • Registratie: September 2001
  • Laatst online: 11-08 16:19
All problems solved!!! DankU allen .. vooral Blues :P
-------------------------------------------------



Ik ben bezig met het maken van een tree, wat een menutree voor moet gaan stellen. Om de structuur van
het menu te kunnen beheren, ben ik bezig met een scriptje waarbij je de items kan verplaatsen door
de gehele tree dmv links(/knoppen)

code:
1
2
3
4
5
^ pijl omhoog: Item op zelfde niveau 1 plaats omhoog verplaatsen
<- pijl links: Item (en childs) 1 niveau naar beneden plaatsen
-> pijl rechts: Item 1 niveau dieper plaatsen/child maken van 
        voorgaande item op zelfde niveau (previousSibling)
\/ pijl omlaag: Item op zelfde niveau 1 plaats omlaag verplaatsen

Dit zijn dus niet de controls op je toetsenbord, maar gewone links in de pagina :)

Het is me nu al voor een aardig deel gelukt, maar er ontstaan nog steeds errors, alleen snap ik niet altijd
waardoor ..

Is er iemand bereidt om eventjes met mij mee te denken en mij verder te helpen :)

Code tot nu toe (zie online):
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<body onLoad="fnInit();">

<script language="JavaScript" type="text/javascript">
function objMenuItem( strRefId, strParentId, strText)
{
    this.refId = strRefId;
    this.parentId = strParentId;
    this.strText = strText;
    //this.bVerwerkt = false;

    this.element = new function()
    {
        this.elObj = document.createElement('<div>');
        this.elObj.setAttribute('id', 'elMenuItem[' + strRefId + ']');
        this.elObj.innerHTML =   
                      '<a href="javascript: void(0);" onClick="fnMoveItem(\'<-\');">&lt;- </a> '
                    + '<a href="javascript: void(0);" onClick="fnMoveItem(\'^^\');">^^ </a> '
                    + '<a href="javascript: void(0);" onClick="fnMoveItem(\'\/\');">\/ </a> '
                    + '<a href="javascript: void(0);" onClick="fnMoveItem(\'->\');">-> </a> '
                    + strText + ' - ' + strRefId + ' - ' + strParentId;
        this.elObj.style.setAttribute('paddingLeft', 25);
        this.elObj.strParentId = strParentId;
    }
}

var arrMainItems = new Array();
var arrMenuItems = new Array();

//arrMenuItem[intId] = new objMenuItem(intId, parentId, text)
arrMenuItems[1] = new objMenuItem(1, 0, 'Hoofditem 1');
arrMenuItems[2] = new objMenuItem(2, 0, 'Hoofditem 2');
arrMenuItems[3] = new objMenuItem(3, 1, 'Subitem 1.1');
arrMenuItems[4] = new objMenuItem(4, 2, 'Subitem 2.1');
arrMenuItems[5] = new objMenuItem(5, 2, 'Subitem 2.2');
arrMenuItems[6] = new objMenuItem(6, 2, 'Subitem 2.3');
arrMenuItems[7] = new objMenuItem(7, 6, 'Subitem 2.3.1');
arrMenuItems[10] = new objMenuItem(10, 6, 'Subitem 2.3.2');
arrMenuItems[11] = new objMenuItem(11, 6, 'Subitem 2.3.3');
arrMenuItems[8] = new objMenuItem(8, 2, 'Subitem 2.4');
arrMenuItems[12] = new objMenuItem(12, 2, 'Subitem 2.5');
arrMenuItems[13] = new objMenuItem(13, 7, 'Subitem 2.3.1.1');
arrMenuItems[14] = new objMenuItem(14, 7, 'Subitem 2.3.1.2');

function fnBuild()
{
    for (strId in arrMenuItems)
    {
        with (objItem = arrMenuItems[strId])
        {
            if (objItem.parentId)
                arrMenuItems[objItem.parentId].element.elObj.appendChild(objItem.element.elObj);
            
            else
                document.getElementById('elDefault').appendChild(objItem.element.elObj);
        }
    }
}

function fnMoveItem(strAction)
{
    switch (strAction)
    {
        case '<-':
         if(event.srcElement.parentNode.parentNode.parentNode)
           event.srcElement.parentNode.parentNode.parentNode.appendChild(event.srcElement.parentNode);
        break;
        
        case '->':
         if (event.srcElement.parentNode.previousSibling)
            event.srcElement.parentNode.previousSibling.appendChild(event.srcElement.parentNode);
                
        break;

        case '^^':
                var tempObj = event.srcElement.parentNode.previousSibling
                       || event.srcElement.parentNode;
                var thisObj = event.srcElement.parentNode;
        
                //event.srcElement.parentNode.previousSibling = thisObj;
        break;
        
        case '\/':
                var tempObj = event.srcElement.parentNode.nextSibling 
                       || event.srcElement.parentNode;
                var thisObj = event.srcElement.parentNode;
                
                event.srcElement.parentNode.nextSibling = thisObj;
        break;
        
        default:
                alert(strAction);
        break;
    }
}

function fnInit()
{
    fnBuild();
}

</script>
<div id="elDefault"></div>

Verwijderd

Mijn eerste opmerking zou zijn: maak geen gebruik van zo'n lelijke onduidelijke array.
Maak een object aan waarin je in een keer die menustructuur kan uitdrukken. Eenvoudig voorbeeld:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function treeObject( sID,aNodes ) {
    this.sID = sID
    this.aNodes = aNodes;
}

var myTree = new treeObject('root',[
    new treeObject('nivo 1.1',[]),
    new treeObject('nivo 1.2',[]),
    new treeObject('nivo 1.3',[
        new treeObject('nivo 2.1',[]),
        new treeObject('nivo 2.2',[
            new treeObject('nivo 3.1',[]),
            new treeObject('nivo 3.2',[])
        ])
    ]),
    new treeObject('nivo 1.4',[])
]);


Dat maakt het uiteindelijk een stuk makkelijker om je tree te parsen...

  • r0bert
  • Registratie: September 2001
  • Laatst online: 11-08 16:19
Euh. okey!

* r0bert volgt Blues advies natúúrlijk op :)

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
function objMenuItem(strRefId, strText, objChilds)
{
    this.refId = strRefId;
    this.strText = strText;
    //this.bVerwerkt = false;

    this.element = new function()
    {
        this.elObj = document.createElement('<div>');
        this.elObj.setAttribute('id', 'elMenuItem[' + strRefId + ']');
        this.elObj.innerHTML =   
                        '<a href="javascript: void(0);" 
                       onMouseOver="fnMoveItem(this.parentNode, \'<-\', 1);" 
                       onMouseOut="fnMoveItem(this.parentNode, \'<-\', 2);" 
                       onClick="fnMoveItem(this.parentNode, \'<-\', 0); 
                       fnMoveItem(this.parentNode, \'<-\', 2);">&lt;- </a> '

                    + '<a href="javascript: void(0);"
                       onMouseOver="fnMoveItem(this.parentNode, \'<-\', 1);" 
                       onMouseOut="fnMoveItem(this.parentNode, \'^^\', 2);" 
                       onClick="fnMoveItem(this.parentNode, \'^^\', 0); 
                       fnMoveItem(this.parentNode, \'^^\', 2);">^^ </a> '

                    + '<a href="javascript: void(0);" 
                       onMouseOver="fnMoveItem(this.parentNode, \'<-\', 1);" 
                       onMouseOut="fnMoveItem(this.parentNode, \'\/\', 2);" 
                       onClick="fnMoveItem(this.parentNode, \'\/\', 0); 
                       fnMoveItem(this.parentNode, \'\/\', 2);">\/ </a> '

                    + '<a href="javascript: void(0);" 
                       onMouseOver="fnMoveItem(this.parentNode, \'<-\', 1);" 
                       onMouseOut="fnMoveItem(this.parentNode, \'->\', 2);" 
                       onClick="fnMoveItem(this.parentNode, \'->\', 0); 
                       fnMoveItem(this.parentNode, \'->\', 2);">-> </a> '

                    + '<span>' + strText + ' - ' + strRefId + '</span>';
        this.elObj.style.setAttribute('paddingLeft', 25);
    }
    this.ch = objChilds;
}

var objItems = new objMenuItem(1, 'root',[
    new objMenuItem(2, 'nivo 1.1',[]),
    new objMenuItem(3, 'nivo 1.2',[]),
    new objMenuItem(4, 'nivo 1.3',[
        new objMenuItem(5, 'nivo 2.1',[]),
        new objMenuItem(6, 'nivo 2.2',[
            new objMenuItem(7, 'nivo 3.1',[]),
            new objMenuItem(8, 'nivo 3.2',[])
        ])
    ]),
    new objMenuItem(9, 'nivo 1.4',[])
]);

Hoe kan ik nu niveau 3.1 aanroepen dan ?
PHP:
1
alert( objItems.ch[2].ch[1].ch[0].strText );

wil niet :|
[edit] Dom dom dom!.. werkt wel.. ik had er een beetje een rotzooitje van gemaakt :P[ /edit]

de html is nog de oude html dus klopt niet..

En hoe kan ik de parent aanroepen vanuit een child ?
PHP:
1
2
objEl = objItems.ch[2].ch[1].ch[0];
alert(objEl.parentNode);

oid :S

Verwijderd

r0bert schreef op 22 oktober 2002 @ 15:49:
En hoe kan ik de parent aanroepen vanuit een child ?
PHP:
1
2
objEl = objItems.ch[2].ch[1].ch[0];
alert(objEl.parentNode);
Daarvoor zal je eerst de tree moeten parsen, denk ik.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function objMenuItem(strRefId, strText, objChilds)
{
    this.refId = strRefId;
    this.strText = strText;
    this.ch = objChilds;
    this.parentNode = null;
} 

function parseTree( oTree ) {
    var iLength = oTree.ch.length;
    for(var i=0; i<iLength; i++) {
        oTree.ch[i].parentNode = oTree;
        parseTree(oTree.ch[i]);
    }
}
parseTree(objItems);

  • r0bert
  • Registratie: September 2001
  • Laatst online: 11-08 16:19
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//   ...
this.element = new function()
{
    this.elObj = document.createElement('div');
    this.elObj.setAttribute('id', 'elMenuItem[' + strRefId + ']');
    this.elObj.innerHTML =    '<a onClick="this.parentNode.moveLeft();">&lt;- </a> '
                + '<a onClick="this.parentNode.moveUp();">^^ </a> '
                + '<a onClick="">\\/ </a> '
                + '<a onClick="">-&gt; </a> '
                + '<span>' + strText + ' - ' + strRefId + '</span>';
    this.elObj.style.setAttribute('paddingLeft', 25);
    this.elObj.moveUp = function()
    {
        if (this.parentNode.previousSibling)
        {
            oldChild = this.parentNode.previousSibling;
            this.parentNode.replaceChild(this, oldChild);
        }
    }
    this.elObj.moveDown = function()
    {
/* ### HIER GAAT HET OM  ### */
        if (this.parentNode.parentNode.nodeName == 'DIV')
            this.parentNode.parentNode.appendChild(this);
/* ###                                 ### */
    }
    this.elObj.moveLeft = function()
    {
        if (this.parentNode.parentNode.nodeName == 'DIV')
            this.parentNode.parentNode.appendChild(this);
    }
    this.elObj.moveRight = function()
    {
        /*if (this.parentNode.parentNode.nodeName == 'DIV')
            this.parentNode.parentNode.appendChild(this);*/
    }
}
// ...

this.element is onderdeel van een obj, maar dat is verder denk ik niet van belang.. Het gaat me even om de (previousSibling.)replaceChild! Want dat wil maar niet werken :|

Syntax is volgens mij/msdn obj.replaceChild(newNode, oldChildNode)

http://msdn.microsoft.com.../methods/replacechild.asp

Maar het werkt niet :S wat doe ik fout ?

  • r0bert
  • Registratie: September 2001
  • Laatst online: 11-08 16:19
Bedankt voor alle reacties ;)

Ik ben er intussen zelf al uitgekomen.. het lag aan de aanroep (wat ik hierboven dus niet genoemt heb). Hierdoor werd er 1 niveau te diep gekeken en klopte er niets meer van..

  • r0bert
  • Registratie: September 2001
  • Laatst online: 11-08 16:19
edit: Probleem opgelost (als je de oplossing wilt weten, moet je maar even mailen)

Ok, het meeste werkt nu wel, alleen moet de data nog uit de XML komen. De xmlfile ziet er als volgt uit:
PHP:
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0"?>

<root id="0" text="root">
    <item id="1" text="Menu item 1">
        <item id="11" text="Sub item 1.1" />
        <item id="12" text="Sub item 1.2">
            <item id="121" text="Sub item 1.2.1" />
        </item>
    </item>
    <item id="2" text="Menu item 2"/>
</root>

De functie om objecten aan te maken:
PHP:
1
2
3
4
5
6
7
8
9
10
11
function objMenuItem(strRefId, strText, objChilds)
{
    this.refId = strRefId;
    this.strText = strText;
    this.parentNode = null
    //this.bVerwerkt = false;

    this.element = new function()
    {}
    this.ch = objChilds;
}
Functie om de XMLdata om te zetten in een tree van objMenuItem objecten...
PHP:
1
2
3
4
5
6
7
8
9
function fnShowXml(objEl)
{
    var arrTemp = new Array();
    
    for (var int = 0; int < objEl.childNodes.length; int++)
        arrTemp[arrTemp.length] = fnShowXml(objEl.childNodes(int));

    return  new objMenuItem(objEl.getAttribute('id'), objEl.getAttribute('text'), arrTemp);
}

de functie parsetree om de parent te setten e.d.
PHP:
1
2
3
4
5
6
function fnParseTree(objTreeItem) { 
    for(var int = 0; int < objTreeItem.ch.length;  int++) { 
        objTreeItem.ch[int].parentNode = objTreeItem; 
        fnParseTree(objTreeItem.ch[int]); 
    } 
}

en natuurlijk nog de aanroepen onderaan:
PHP:
1
2
3
4
5
6
objRoot = 
  new objMenuItem(objXmlDoc.documentElement.getAttribute('id'),
     objXmlDoc.documentElement.getAttribute('text'),
     fnShowXml(objXmlDoc.documentElement));
fnParseTree(objRoot);
fnBuild(objRoot);

Ik heb de laadfunctie voor de XMLpagina even weggelaten, want daar ligt het niet aan.. maar het xmldocument is dus 'objXmlDoc'.


Als ik nu na dit alles aan het einde Sub item 1 wil uitlezen, zou ik volgens mij het volgende moeten doen:
PHP:
1
alert(objRoot.ch[0].ch[0]);

Maar dan krijg ik een foutmelding of bij objRoot.ch[0] een undefined :S

Ik heb het al helemaal nagepuzzelt, maar kom er EGT niet uit..

ps. ik zal het hele zooitje zo even onlijn zetten.. @ deze pagina

edit: Probleem opgelost (als je de oplossing wilt weten, moet je maar even mailen)
Pagina: 1