Empfehlungen: Erweiterte Suche

[Helper] Explorer-Tree

Anleitungen und Quellcode-Auszüge die den Start vereinfachen sollen.

[Helper] Explorer-Tree

Beitragvon getit » Do 15. Jan 2009, 16:13

Hallo,

ich habe für meine Diplomarbeit einen neuen Helper 'explorer_tree' geschrieben.

Dieser Helper erlaubt es Dokumente in einer beliebig tiefen Verschachtelung darzustellen.
explorer_tree.gif
Der explorer_tree-Helper in Action
explorer_tree.gif (12.75 KiB) 424-mal betrachtet



Den Helper würde ich gerne der gesammten cake-Gemeinde zur Verfügung stellen.
Aber da ich nicht weis, wie ich mich an die cake-Entwickler melde poste ich den Helper hier.

Dabei möchte ich mich mal bei der hervorragenden Community bedanken :!:

Code: Alles auswählen

<?php
/*
 * Den Helper nach /app/views/helpers kopieren
 *
 * Den Helper im Controller aktivieren (var $helpers = array('explorer-tree');)
 *
 *
 * 2 Tabellen müssen existieren:
 *
 *  create table types (
 *      id int(4) auto_increment,
 *      typ varchar(128) not null,
 *      parent int(4) null,
 *      primary key(id)
 *  );
 *
 *  create table documents (
 *      id int(8) auto_increment,
 *      type_id int(4) not null,
 *      name varchar(128) not null,
 *      primary key(id)
 *  );
 *
 *
 * 2 Models:
 *
 *  class Type extends AppModel {
 *      var $hasMany = array('Document');
 *  }
 *
 *  class Document extends AppModel {
 *      var $belongsTo = array('Type');
 *  }
 *  
 *  
 * 1 Controller:
 *
 *  class DocumentsController extends AppController {
 *      var $helpers = array('explorerTree', 'javascript');
 *
 *      function index() {
 *          $this->set('types', $this->Document->Type->find('all'));
 *      }
 *  }
 *
 *
 * 1 View:
 *
 * Muss mind. das Javascript laden ($javascript->link('explorer_tree', false);)
 * und natürlich die Methoden des Helpers aufrufen
 * ($newArray = $explorerTree->init($types);echo $explorerTree->createTree($newArray);
 */

class explorerTreeHelper extends AppHelper {
   
    /*
     * Initialisiert das Array
     */

    function init($types) {    
        return $this->__createArray($types);
    }
   
    function __createArray($types) {
        $newArray;
        foreach ($types as $type) {        
            // Dokumenten-Array leeren
            foreach ($type['Document'] as $document) {
                array_splice($document, 0, 2);
            }
           
            // Werte auslesen und speichern
            $id = $type['Type']['id'];
            $name = $type['Type']['typ'];
            $parent = $type['Type']['parent'];
            $docs = $type['Document'];
           
            // Types-Array leeren
            array_splice($type, 0);

            // Array neu formatieren
            $newArray[] = $this->__reArrangeArray($id, $name, $parent, $docs);
        }
        foreach ($newArray as $array) {
            if ($array['parent'] != null) {
                $newArray = $this->__connect($newArray);
            }  
        }
   
        return $newArray;
    }
   
    // function __reArrangeArray
    //  $id (int)           ID des Types
    //  $name (String)      Name des Types
    //  $parent (int)       Vorfahre des Types
    //  $docs (Array)       Dokumenten des Typess
    function __reArrangeArray($id, $name, $parent, $docs) {
        $tmpArray['id'] = $id;
        $tmpArray['name'] = $name;
        $tmpArray['parent'] = $parent;
        $tmpArray['docs'] = $docs;
        $tmpArray['descendants'] = array();
        return $tmpArray;
    }
   
    // function __connect
    //  $newArray           Neuformatiertes Array
    function __connect($newArray) {
        // Index zum Element mit der höchsten ParentId ermitteln
        $indexArr = $this->__getMaxParentIndex($newArray);
        $indexArr = explode(':' , $indexArr);
        $index = $indexArr[0];
        $maxId = $indexArr[1];
        $hookHere;
        foreach($newArray as $key => $value) {
            if ($value['id'] == $maxId) {
                $hookHere = $key;
                break;
            }
        }  
        $newArray[$hookHere]['descendants'][] = $newArray[$index];
        array_splice($newArray, $index, 1);
       
        return $newArray;
    }
   
    // function __getMaxParentId
    //  $newArray (Array)   neu formatiertes Array
    function __getMaxParentIndex($newArray) {
        $maxParent = 0;
        $index;
        for ($i = 0; $i < count($newArray); $i++) {
            if ($newArray[$i]['parent'] >= $maxParent) {
                $maxParent = $newArray[$i]['parent'];
                $index = $i;
            }
        }
       
        //$index (int)      Index zum Element mit der höchsten ParentId
        //$maxParent (int)  Enthält den höchsten ParentIndex
        return $index . ':' . $maxParent;
    }
    /*
     * Ende der Initialisierung des Arrays
     */

   
    /*
     * Erstellung des Baumes
     */

    var $helpers = array('html');
    var $tree;
   
    function createTree($newArray) {               
        $this->tree = $this->html->tag('div', null, array('id' => 'tree'));
        $this->__getFolder($newArray);
        $this->tree .= $this->html->tag('/div');
       
        return $this->tree;
    }
   
    // function __getFolder
    //  $position           Enthät die aktuelle Position im Array
    function __getFolder($position) {
        $this->tree .= $this->html->tag('ul', null, array('id' => 'folder'));
        foreach ($position as $element) {
            $this->tree .= $this->html->tag('li', null, array('onclick' => 'javascript&#058;toggle();'));
            $this->tree .= $this->html->image('opened.gif');
            $this->tree .= $element['name'];
            $this->tree .= $this->html->tag('/li');
            $this->__getDocuments($element['docs']);
            if ($element['descendants']) {
                $this->__getFolder($element['descendants']);
            }
        }
        $this->tree .= $this->html->tag('/ul');
    }
   
    // function __getDocuments
    //  $position           Enthält die aktuelle Position im Array
    function __getDocuments($position) {
        $this->tree .= $this->html->tag('ul', null, array('id' => 'document'));
        foreach ($position as $doc) {
            $this->tree .= $this->html->tag('li');
            $this->tree .= $this->html->image('doc.gif');
            $this->tree .= $this->html->link($doc['name'], '');
            $this->tree .= $this->html->tag('/li');
        }
        $this->tree .= $this->html->tag('/ul');
    }
    /*
     * Ende Erstellung des Baumes
     */

}
?>
 


Ich denke mit den Erklärungen im Quellcode sollte jeder klar kommen.
Ansonsten einfach fragen!

P.S: Vielleicht hat ja jemand Lust, den Helper noch zu erweitern.
Z.b. das man die Ordner schließen (der Inhalt soll dann natürlich verschwinden) und wieder öffnen (der Inhalt erscheint wieder) kann, oder das sich alle 10sek per Ajax das gesammte Dokument neu lädt und somit evtl. neue Dokumente erscheinen (der Status - welcher Ordner war offen/geschlossen - soll dabei natürlich erhalten bleiben).
Wenn das jemand macht würde ich mich natürlich über den Quellcode freuen :D
getit
 
Beiträge: 105
Registriert: Mo 22. Dez 2008, 13:06
CakePHP-Version: 1.2.1.8004
OS: Vista

Re: Keine Frage, sondern neuer Helper

Beitragvon Tobitobe » Fr 16. Jan 2009, 07:37

Nettes Teil, sieht respektabel aus. :D

Was die Community und den Code angeht, so versuche es mal hier:

http://bakery.cakephp.org/categories/view/8

Wenn Du dort einen Benutzeraccount hast, kannst Du über "Add article" meines Erachtens neuen Code posten. Wenn Verfahren dürfte dem Übersetzen des Handbuchs ähneln, vermute ich mal. Sprich, bevor der Inhalt gepostet wird, würde jemand vom Entwicklerteam drüberschauen.

Gruß
Tobi
Tobitobe
 
Beiträge: 45
Registriert: Mi 11. Jun 2008, 08:41
Wohnort: Neuss
CakePHP-Version: 1.2.0.7962 Final
OS: Mac OS X

Re: [Helper] Explorer-Tree: NEUE VERSION

Beitragvon getit » So 18. Jan 2009, 13:26

:D

Ich habe heute eine neue Version meines Helpers fertig bekommen.

Zusätzlich zur ersten Version, kann man jetzt auch
    toggeln (d.h. die Ordner auf-/zuklappen)
:P
    die Einstellungen der Ordner (offen/geschlossen) bleiben auch nach einem Reload der Seite erhalten
:P :P

Als Anhang mein app-Verzeichnis gezippt.
Also nur noch Datenbank einstellen (DB: caketest) und Tabellen anlegen und los gehts. :!:

Bugfix am: 18.1. um 19.58
Im Firefox gab es keine Probleme (arbeite hauptsächlich am Firefox, deshalb habe ich das Problem erst jetzt bemerkt - sorry) aber im IE ist der Event nach oben gebubbelt.
D.h. wollte man einen inneren Ordner schließen, hat dieser Event einen Event bei den Parentelementen ausgelöst. Jetzt gehts.
Anhang geändert!!!
:!: Für alle, die schon die alte Version geladen haben :!:
Die einzige Änderung in der explorer_tree.js, function toggle(id):
Nach dem Ende der if()-Abfrage noch folgende Zeile einfügen
Code: Alles auswählen
event.cancelBubble = true;


Bugfix am: 19.1. um 9.30:
Das event-Objekt ist im Firefox nicht bekannt (IE, evtl. Andere). Deshalb muss die Zeile
Code: Alles auswählen
event.cancelBubble = true;
in eine if-Bedingung.
Code: Alles auswählen

if (document.all) {
   event.cancelBubble = true;
}
 

Ich habe den Dateianhang nicht korrigiert. D.h. jeder der den Anhang downloaded muss die Änderung manuell in der explorer_tree.js vornehmen.
Dateianhänge
app.zip
(78.84 KiB) 10-mal heruntergeladen
getit
 
Beiträge: 105
Registriert: Mo 22. Dez 2008, 13:06
CakePHP-Version: 1.2.1.8004
OS: Vista

Re: [Helper] Explorer-Tree

Beitragvon getit » Di 20. Jan 2009, 12:37

:D NEUE VERSION :D

Ich hab das jetzt mit integriertem AJAX.

Wenn Interresse besteht, einfach melden dann poste ich das hier.
getit
 
Beiträge: 105
Registriert: Mo 22. Dez 2008, 13:06
CakePHP-Version: 1.2.1.8004
OS: Vista

Re: [Helper] Explorer-Tree

Beitragvon havanna » Mi 21. Jan 2009, 23:09

Hallo,
wäre auf jeden Fall interessant, das mit Ajax zu sehen.

Ciao Thomas
Benutzeravatar
havanna
 
Beiträge: 191
Registriert: Mi 15. Okt 2008, 23:12
Wohnort: Bodman-Ludwigshafen
CakePHP-Version: 1.2.x
OS: WIN

Re: [Helper] Explorer-Tree

Beitragvon getit » Do 22. Jan 2009, 10:57

Hallo,

ich lade die Ajax-Version hoch.
Wie gehabt ist das wieder das komplette app-Verzeichnis.

Nur noch DB und Tabellen anlegen und los gehts.

Viel Spaß damit.
Dateianhänge
app.zip
(84.12 KiB) 21-mal heruntergeladen
getit
 
Beiträge: 105
Registriert: Mo 22. Dez 2008, 13:06
CakePHP-Version: 1.2.1.8004
OS: Vista


Zurück zu Tutorials und Snippets

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron