Saturday, April 14, 2012

ZK Tree with mix-state checkbox


This post is about implement the mix-state of the checkbox in the tree,
tested with ZK 5.0.8.

How it works

A Treeitem store the selected child in an array,
and it will be set to mix-state if it has selected child and not self selected.

The Program


<zk xmlns:w="client">
        tested with ZK 5.0.8
        <!-- The mix-state style,
             remove the margin then add blue border -->
        .mixed-state {
            margin: 0px;
            border: 2px solid #3E48AE;
    <!-- Override the Treeitem#doSelect_ -->
    <script type="text/javascript"><![CDATA[
    zk.afterLoad("zul.sel", function () {
        var oldSelect = zul.sel.Treeitem.prototype.doSelect_;
        zul.sel.Treeitem.prototype.doSelect_ = function (evt) {
            // do original doSelect_
            oldSelect.apply(this, arguments);

            var $dom = jq(evt.domTarget), // the dom within the target row
                row = $dom.hasClass('z-treerow')? $dom[0] : $dom.parents('.z-treerow')[0], // the root dom of target row
                isSelected = jq(row).hasClass('z-treerow-seld'), // the selected status of target row
                isSelfSelected = jq(this.treerow.$n()).hasClass('z-treerow-seld'), // the selected status of self
                _selectedChild = this._selectedChild, // the array that store the dom of the selected children
                index, isRecord;

            // create _selectedChild array if not exists.
            if (!_selectedChild)
                _selectedChild = this._selectedChild = [];

            // find the position of target row
            index = _selectedChild.indexOf(row);
            // whether the target row is already stored
            isRecord = index > -1;
            // push the root dom of target row into array if
            // it is selected but not stored
            if (isSelected && !isRecord)
            // remove the root dom of target row from array if
            // it is not selected but stored
            else if (!isSelected && isRecord)
                _selectedChild.splice(index, 1);

            // set self style to mix-state if self is not selected
            // and some children is selected
            if (_selectedChild.length > 0 && !isSelfSelected)
    <div style="margin: 30px;">
        <tree id="tree" rows="5" multiple="true" checkmark="true" width="500px" vflex="200px">
                <treecol label="Name"/>
                <treecol label="Description"/>
                        <treecell label="Item 1"/>
                        <treecell label="Item 1 description"/>
                        <treecell label="Item 2"/>
                        <treecell label="Item 2 description"/>
                                <treecell label="Item 2.1"/>
                                        <treecell label="Item 2.1.1"/>
                                        <treecell label="Item 2.1.2"/>
                                <treecell label="Item 2.2"/>
                                <treecell label="Item 2.2 is something who cares"/>
                <treeitem label="Item 3"/>

The Result

See the demo flash at

Thie files are available at github:

full project
demo movie (click View Raw to download)

No comments:

Post a Comment