Yii2: Membuat dropdown ala struktur data berupa Tree

Membuat dropdown pada Yii2 sangat mudah, akan tetapi bagaimana membuat dropdown yang berbentuk layaknya sebuah tree
Published di Yii2, 2 years ago

Kebetulan lagi pengen nulis blog artikel, gak tahu bakal berguna kedepannya atau tidak, minimal jadi dokumentasi saya.

Sebelumnya kita definisikan dulu database nya : DBFIDDLE

Setelah kita sudah membuat database nya, kita harus memanipulasi record tersebut menjadi struktur yang lebih enak di mata user.

Kita akan menggunakan Yii2:

```

<?= $form->field($model, 'article_category_id')

        ->dropDownList(ArticleCategory::find()->map(), [

                   'prompt' => '= Pilih Tipe ='

        ])

        ->label(false)

?>


```

Dan ini adalah, function map yang dimaksud:

```

    /**

     * @param bool $withTopRootNode |  munculkan record `root` atau tidak, 

     * @return array

     * @throws Exception

     */

    public function map(bool $withTopRootNode = false): array

    {

        $tree = Tree::buildTree($this->tree(), 1);

        $flattingTree =  Tree::flattingTree($tree);


        if($withTopRootNode){ // case jika ingin memunculkan node record `root`


            $topRoot = ArrayHelper::map(ArticleCategory::find()

                ->where([

                    'IS' , 'parent_id' , NULL

                ])

                ->all(), 'id', 'name')

            ;


            $flattingTree = ArrayHelper::merge($topRoot, $flattingTree);

        }


        return $flattingTree;

    }


    /**

     * @return array|DataReader

     * @throws Exception

     */

    public function tree($rootId = 1)

    {

        $sql =<<<SQL

WITH RECURSIVE article_category_tree(id, parent_id,  text, lvl) AS (


    SELECT id,

           COALESCE(parent_id, 0),

           name as text,

           0 lvl

    FROM article_category top_root

    WHERE top_root.id = :id


    UNION ALL


    SELECT at.id,

           at.parent_id,

           at.name as text,

           (trivial.lvl + 1) AS lvl

    FROM article_category_tree AS trivial

             JOIN article_category AS at

                  ON trivial.id = at.parent_id

)


SELECT * FROM article_category_tree ORDER BY parent_id, lvl;

SQL;

        return Yii::$app->db->createCommand($sql, ['id' => $rootId])

            ->queryAll();

    }


```


Dropdown berfungsi berbentuk key=>value, jadi kita perlu membuat tree menjadi flat, semua ada dalam class helper yang saya namakan Tree,

dimana penggunaanya seperti pada code sbelumnya :

```

class Tree

{

    /**

     * @param array $elements

     * @param int $parentId

     * @return array

     */


    public static function buildTree(array $elements, int $parentId = 0): array

    {

        $branch = [];

        foreach ($elements as $element) {

            if ($element['parent_id'] == $parentId) {

                $children = self::buildTree($elements, $element['id']);

                if ($children) {

                    $element['nodes'] = $children;

                }

                $element['href'] = Url::to(['/site/read-by-category', 'id' => $element['id']]);

                $branch[] = $element;

            }

        }

        return $branch;

    }


    /**

     * @param array $tree

     * @return array

     */

    public static function flattingTree(array $tree): array

    {

        $denormalizeTree = [];

        foreach ($tree as $key => $node) {

            $denormalizeTree[$node['id']] =

                str_repeat(html_entity_decode('&nbsp;&nbsp;&nbsp;'), $node['lvl']) . $node['text'];


            if ($node['nodes']) {

                $result = self::flattingTree($node['nodes']);

                $denormalizeTree += $result;

            }

        }

        return $denormalizeTree;

    }


}

```

Hasilnya akan terlihat di halaman index web pribadi ini :

Dukung Saya supaya tetap menulis artikel-artikel yang baik, membayar sewa domain, dan server untuk blog ini. Caranya dengan donasi cendol via Trakteer.id.


No image

Fadly Dzil Jalal

PHP, Yii2 Framework, Laravel, Java, Java Swing, Hibernate, Javascript, Angular, React, MySQL, MongoDB


Dapatkan USD 200 untuk develop aplikasimu di DigitalOcean DigitalOcean Referral Badge