erhanfirat / combo-tree

ComboTree is a jQuery Plugin which is a combobox item with tree structured data list and multi/single selection options and more.
MIT License
79 stars 67 forks source link

Filter On Multi Selection #3

Closed jqueryscript closed 5 years ago

jqueryscript commented 6 years ago

Seems like the Filter functionality CANNOT work with Multi Selection mode. Any chance to fix it?

erhanfirat commented 6 years ago

I will check as soon as possible, unfortunately, for the 2 weeks I will be so busy.

There may be need of extra input field to filter for multi selection...

carlituxman commented 5 years ago

how is it?

DaveInTO commented 5 years ago

Anyone get anywhere with this?

harishksoft commented 5 years ago

/*!

;(function ( $, window, document, undefined ) {

// Create the defaults once
var comboTreePlugin = 'comboTree',
    defaults = {
        source: [], 
        isMultiple: false
    };

// The actual plugin constructor
function ComboTree( element, options ) {
    this.elemInput = element;
    this._elemInput = $(element);

    this.options = $.extend( {}, defaults, options) ;

    this._defaults = defaults;
    this._name = comboTreePlugin;

    this.init();
}

ComboTree.prototype.init = function () {
    // Setting Doms
    this.comboTreeId = 'comboTree' + Math.floor(Math.random() * 999999);

    this._elemInput.addClass('comboTreeInputBox');

    if(this._elemInput.attr('id') === undefined)
        this._elemInput.attr('id', this.comboTreeId + 'Input');
    this.elemInputId = this._elemInput.attr('id');

    this._elemInput.wrap('<div id="'+ this.comboTreeId + 'Wrapper" class="comboTreeWrapper"></div>');
    this._elemInput.wrap('<div id="'+ this.comboTreeId + 'InputWrapper" class="comboTreeInputWrapper"></div>');
    this._elemWrapper = $('#' + this.comboTreeId + 'Wrapper');

    this._elemArrowBtn = $('<button id="' + this.comboTreeId + 'ArrowBtn" class="comboTreeArrowBtn"><span class="comboTreeArrowBtnImg">▼</span></button>');
    this._elemInput.after(this._elemArrowBtn);
    this._elemWrapper.append('<div id="' + this.comboTreeId + 'DropDownContainer" class="comboTreeDropDownContainer"><div class="comboTreeDropDownContent"></div>');

    // DORP DOWN AREA
    this._elemDropDownContainer = $('#' + this.comboTreeId + 'DropDownContainer');
    this._elemDropDownContainer.html(this.createSourceHTML());

    this._elemItems = this._elemDropDownContainer.find('li');
    this._elemItemsTitle = this._elemDropDownContainer.find('span.comboTreeItemTitle');

    // VARIABLES
    this._selectedItem = {};
    this._selectedItems = [];

    this.bindings();
};

// *********************************
// SOURCES CODES
// *********************************

ComboTree.prototype.removeSourceHTML = function () {
    this._elemDropDownContainer.html('');
};

ComboTree.prototype.createSourceHTML = function () {
    var htmlText = this.createSourceSubItemsHTML(this.options.source);
    return htmlText;
};

ComboTree.prototype.createSourceSubItemsHTML = function (subItems) {
    var subItemsHtml = '<UL>';
    for (var i=0; i<subItems.length; i++){
        subItemsHtml += this.createSourceItemHTML(subItems[i]);
    }
    subItemsHtml += '</UL>'
    return subItemsHtml;
}

ComboTree.prototype.createSourceItemHTML = function (sourceItem) {
    var itemHtml = "",
        isThereSubs = sourceItem.hasOwnProperty("subs");

    itemHtml = '<LI class="ComboTreeItem' + (isThereSubs?'Parent':'Chlid') + '"> ';

    if (isThereSubs)
        itemHtml += '<span class="comboTreeParentPlus">&minus;</span>';

    if (this.options.isMultiple)
        itemHtml += '<span data-id="' + sourceItem.id + '" class="comboTreeItemTitle"><input type="checkbox">' + sourceItem.title + '</span>';
    else
        itemHtml += '<span data-id="' + sourceItem.id + '" class="comboTreeItemTitle">' + sourceItem.title + '</span>';

    if (isThereSubs)
        itemHtml += this.createSourceSubItemsHTML(sourceItem.subs);

    itemHtml += '</LI>';
    return itemHtml;
};

// BINDINGS
// *****************************
ComboTree.prototype.bindings = function () {
    var _this = this;

    this._elemArrowBtn.on('click', function(e){
        e.stopPropagation();
        _this.toggleDropDown();
    });
    this._elemInput.on('click', function(e){
        e.stopPropagation();
        if (!_this._elemDropDownContainer.is(':visible'))
            _this.toggleDropDown();
    });
    this._elemItems.on('click', function(e){
        e.stopPropagation();
        if ($(this).hasClass('ComboTreeItemParent')){
            _this.toggleSelectionTree(this);
        }
    });        
    this._elemItemsTitle.on('click', function(e){
        e.stopPropagation();
        if (_this.options.isMultiple)
            _this.multiItemClick(this);
        else
            _this.singleItemClick(this);
    });
    this._elemItemsTitle.on("mousemove", function (e) {
        e.stopPropagation();
        _this.dropDownMenuHover(this);
    });

    // KEY BINDINGS
    this._elemInput.on('keyup', function(e) {
        e.stopPropagation();

        switch (e.keyCode) {
            case 27:
                _this.closeDropDownMenu(); break;
            case 13:                  
            case 39: case 37: case 40: case 38:
                e.preventDefault(); 
                break;
            default: 
                //if (_this.options.isMultiple)
                    _this.filterDropDownMenu(); 
                break;
        }
    });
    this._elemInput.on('keydown', function(e) {
        e.stopPropagation();

        switch (e.keyCode) {
        case 9:
            _this.closeDropDownMenu(); break;
        case 40: case 38:
            e.preventDefault(); 
            _this.dropDownInputKeyControl(e.keyCode - 39); break;
        case 37: case 39:
            e.preventDefault(); 
            _this.dropDownInputKeyToggleTreeControl(e.keyCode - 38);
            break;
        case 13:
            if (_this.options.isMultiple)
                _this.multiItemClick(_this._elemHoveredItem);
            else
                _this.singleItemClick(_this._elemHoveredItem);
            e.preventDefault(); 
            break;
        default: 
            //if (!_this.options.isMultiple)
            //e.preventDefault();
    }
    });
    // ON FOCUS OUT CLOSE DROPDOWN
    $(document).on('mouseup.' + _this.comboTreeId, function (e){
        if (!_this._elemWrapper.is(e.target) && _this._elemWrapper.has(e.target).length === 0 && _this._elemDropDownContainer.is(':visible'))
            _this.closeDropDownMenu();
    });
};

// EVENTS HERE 
// ****************************

// DropDown Menu Open/Close
ComboTree.prototype.toggleDropDown = function () {
    this._elemDropDownContainer.slideToggle(50);
    this._elemInput.focus();
};
ComboTree.prototype.closeDropDownMenu = function () {
    this._elemDropDownContainer.slideUp(50);
};
// Selection Tree Open/Close
ComboTree.prototype.toggleSelectionTree = function (item, direction) {
    var subMenu = $(item).children('ul')[0];
    if (direction === undefined){
        if ($(subMenu).is(':visible'))
            $(item).children('span.comboTreeParentPlus').html("+");
        else
            $(item).children('span.comboTreeParentPlus').html("&minus;");

        $(subMenu).slideToggle(50);
    }
    else if (direction == 1 && !$(subMenu).is(':visible')){
            $(item).children('span.comboTreeParentPlus').html("&minus;");
            $(subMenu).slideDown(50);
    }
    else if (direction == -1){
        if ($(subMenu).is(':visible')){
            $(item).children('span.comboTreeParentPlus').html("+");
            $(subMenu).slideUp(50);
        }
        else {
            this.dropDownMenuHoverToParentItem(item);
        }
    }

};

// SELECTION FUNCTIONS
// *****************************
ComboTree.prototype.singleItemClick = function (ctItem) {
    this._selectedItem = {
        id: $(ctItem).attr("data-id"),
        title: $(ctItem).text()
    };

    this.refreshInputVal();
    this.closeDropDownMenu();
};
ComboTree.prototype.multiItemClick = function (ctItem) {
    this._selectedItem = {
        id: $(ctItem).attr("data-id"),
        title: $(ctItem).text()
    };

    var index = this.isItemInArray(this._selectedItem, this._selectedItems);
    if (index){
        this._selectedItems.splice(parseInt(index), 1);
        $(ctItem).find("input").prop('checked', false);
    }
    else {
        this._selectedItems.push(this._selectedItem);
        $(ctItem).find("input").prop('checked', true);
    }

    this.refreshInputVal();
};

ComboTree.prototype.isItemInArray = function (item, arr) {

    for (var i=0; i<arr.length; i++)
        if (item.id == arr[i].id && item.title == arr[i].title)
            return i + "";

    return false;
}

ComboTree.prototype.refreshInputVal = function () {
    var tmpTitle = "";

    //if (this.options.isMultiple) {
    //    for (var i=0; i<this._selectedItems.length; i++){
    //        tmpTitle += this._selectedItems[i].title;
    //        if (i<this._selectedItems.length-1)
    //            tmpTitle += ", ";
    //    }
    //}
    //else {
    //    tmpTitle = this._selectedItem.title;
    //}
    if (!this.options.isMultiple) {
      tmpTitle = this._selectedItem.title;
    }
    this._elemInput.val(tmpTitle);
}

ComboTree.prototype.dropDownMenuHover = function (itemSpan, withScroll) {
    this._elemItems.find('span.comboTreeItemHover').removeClass('comboTreeItemHover');
    $(itemSpan).addClass('comboTreeItemHover');
    this._elemHoveredItem = $(itemSpan);
    if (withScroll)
        this.dropDownScrollToHoveredItem(this._elemHoveredItem);
}

ComboTree.prototype.dropDownScrollToHoveredItem = function (itemSpan) {
    var curScroll = this._elemDropDownContainer.scrollTop();
    this._elemDropDownContainer.scrollTop(curScroll + $(itemSpan).parent().position().top - 80);
}

ComboTree.prototype.dropDownMenuHoverToParentItem = function (item) {
    var parentSpanItem = $($(item).parents('li.ComboTreeItemParent')[0]).children("span.comboTreeItemTitle");
    if (parentSpanItem.length)
        this.dropDownMenuHover(parentSpanItem, true);
    else 
        this.dropDownMenuHover(this._elemItemsTitle[0], true);
}

ComboTree.prototype.dropDownInputKeyToggleTreeControl = function (direction) {
    var item = this._elemHoveredItem;
    if ($(item).parent('li').hasClass('ComboTreeItemParent'))
        this.toggleSelectionTree($(item).parent('li'), direction);
    else if (direction == -1)
        this.dropDownMenuHoverToParentItem(item);
}

ComboTree.prototype.dropDownInputKeyControl = function (step) {
    if (!this._elemDropDownContainer.is(":visible")) 
        this.toggleDropDown();

    var list = this._elemItems.find("span.comboTreeItemTitle:visible");
    i = this._elemHoveredItem?list.index(this._elemHoveredItem) + step:0;
    i = (list.length + i) % list.length;

    this.dropDownMenuHover(list[i], true);        
},

ComboTree.prototype.filterDropDownMenu = function () {
    var searchText = this._elemInput.val();
    if (searchText != ""){
        this._elemItemsTitle.hide();
        this._elemItemsTitle.siblings("span.comboTreeParentPlus").hide();
        list = this._elemItems.find("span:icontains('" + this._elemInput.val() + "')").each(function (i, elem) {
            $(this).show();
            $(this).siblings("span.comboTreeParentPlus").show();
        });    
    }
    else{
        this._elemItemsTitle.show();
        this._elemItemsTitle.siblings("span.comboTreeParentPlus").show();
    }
}

// Retuns Array (multiple), Integer (single), or False (No choice)
ComboTree.prototype.getSelectedItemsId = function () {
    if (this.options.isMultiple && this._selectedItems.length>0){
        var tmpArr = [];
        for (i=0; i<this._selectedItems.length; i++)
            tmpArr.push(this._selectedItems[i].id);

        return tmpArr;
    }
    else if (!this.options.isMultiple && this._selectedItem.hasOwnProperty('id')){
        return this._selectedItem.id;
    }
    return false;
}

// Retuns Array (multiple), Integer (single), or False (No choice)
ComboTree.prototype.getSelectedItemsTitle = function () {
    if (this.options.isMultiple && this._selectedItems.length>0){
        var tmpArr = [];
        for (i=0; i<this._selectedItems.length; i++)
            tmpArr.push(this._selectedItems[i].title);

        return tmpArr;
    }
    else if (!this.options.isMultiple && this._selectedItem.hasOwnProperty('id')){
        return this._selectedItem.title;
    }
    return false;
}

ComboTree.prototype.unbind = function () {
    this._elemArrowBtn.off('click');
    this._elemInput.off('click');
    this._elemItems.off('click');        
    this._elemItemsTitle.off('click');
    this._elemItemsTitle.off("mousemove");
    this._elemInput.off('keyup');
    this._elemInput.off('keydown');
    this._elemInput.off('mouseup.' + this.comboTreeId);
    $(document).off('mouseup.' + this.comboTreeId);
}

ComboTree.prototype.destroy = function () {
    this.unbind();
    this._elemWrapper.before(this._elemInput);
    this._elemWrapper.remove();
    this._elemInput.removeData('plugin_' + comboTreePlugin);
}

$.fn[comboTreePlugin] = function ( options) {
    var ctArr = [];
    this.each(function () {
        if (!$.data(this, 'plugin_' + comboTreePlugin)) {
           $.data(this, 'plugin_' + comboTreePlugin, new ComboTree( this, options));
           ctArr.push($(this).data()['plugin_' + comboTreePlugin]);
        }
    });

    if (this.length == 1)
        return ctArr[0];
    else
        return ctArr;
}

})( jQuery, window, document );

use this. filtration on multi dropdown is fixed

ARr0w commented 5 years ago

@kirlisakal i added the search filter, but i know its not good enough as you included in above comment, Can you include the search like this and make the search work like this with proper code.

changes in this does : checks all children if parent is checked selectedItems array stored with only children or sole elements. filter/searches the children and populates filtered nodes underneath parent.

`obj = {

id : 1

title: "someTitle"

subs: {

       subId : 4

      subTitle: "subTitle"

      subs: {

             subId : 2

             subTitle: "subTitle"

      }

}

and so on ... } `

` /*!

; (function ($, window, document, undefined) {

// Create the defaults once
var comboTreePlugin = 'comboTree',
    IsSearchAdded = false,
    defaults = {
        source: [],
        isMultiple: false,
        keys: [{ value: "id", display: "title" }, { value: "subId", display: "subTitle" }]
    };

// The actual plugin constructor
function ComboTree(element, options) {
    $(element).attr('autocomplete', 'off');
    this.elemInput = element;
    this._elemInput = $(element);

    this.options = $.extend({}, defaults, options);

    this._defaults = defaults;
    this._name = comboTreePlugin;

    this.init();
}

ComboTree.prototype.init = function () {
    // Setting Doms
    this.comboTreeId = 'comboTree' + Math.floor(Math.random() * 999999);

    this._elemInput.addClass('comboTreeInputBox');

    if (this._elemInput.attr('id') === undefined)
        this._elemInput.attr('id', this.comboTreeId + 'Input');
    this.elemInputId = this._elemInput.attr('id');

    this._elemInput.wrap('<div id="' + this.comboTreeId + 'Wrapper" class="comboTreeWrapper"></div>');
    this._elemInput.wrap('<div id="' + this.comboTreeId + 'InputWrapper" class="comboTreeInputWrapper"></div>');
    this._elemWrapper = $('#' + this.comboTreeId + 'Wrapper');

    this._elemArrowBtn = $('<button type="button" id="' + this.comboTreeId + 'ArrowBtn" class="comboTreeArrowBtn"><span class="comboTreeArrowBtnImg">▼</span></button>');
    this._elemInput.after(this._elemArrowBtn);
    this._elemWrapper.append('<div id="' + this.comboTreeId + 'DropDownContainer" class="comboTreeDropDownContainer"><div class="comboTreeDropDownContent"></div>');

    // DORP DOWN AREA
    this._elemDropDownContainer = $('#' + this.comboTreeId + 'DropDownContainer');
    this._elemDropDownContainer.html(this.createSourceHTML());

    this._elemItems = this._elemDropDownContainer.find('li');
    this._elemItemsTitle = this._elemDropDownContainer.find('span.comboTreeItemTitle');

    // VARIABLES
    this._selectedItem = {};
    this._selectedItems = [];

    this.bindings();
};

// *********************************
// SOURCES CODES
// *********************************

ComboTree.prototype.removeSourceHTML = function () {
    this._elemDropDownContainer.html('');
};

ComboTree.prototype.createSourceHTML = function () {
    var htmlText = this.createSourceSubItemsHTML(this.options.source, false, 0);
    return htmlText;
};

ComboTree.prototype.createSourceSubItemsHTML = function (subItems, isChildObject, level) {
    var subItemsHtml = '<UL>';
    if (this.options.isMultiple && !IsSearchAdded) {
        IsSearchAdded = true;
        subItemsHtml += '<LI class="ComboTreeItem searchBox">' +
            '<span class="">' +
            '<input type="text" placeholder="search here" id="searchInput_' + this.comboTreeId + '" autocomplete="off"/>' +
            '</span></LI>';
    }
    if (subItems) {
        for (var i = 0; i < subItems.length; i++) {
            subItemsHtml += this.createSourceItemHTML(subItems[i], isChildObject, level);
        }
    }
    subItemsHtml += '</UL>';
    return subItemsHtml;
};

ComboTree.prototype.createSourceItemHTML = function (sourceItem, isChildObject, level) {
    var itemHtml = "",
        isThereSubs = sourceItem.hasOwnProperty("subs");

    itemHtml = '<LI class="ComboTreeItem' + (isThereSubs ? 'Parent' : 'Child') + '"> ';

    if (isThereSubs) {
        itemHtml += '<span class="comboTreeParentPlus">&minus;</span>';
        level += 1;
    }

    if (this.options.isMultiple) {
        var _isParent = isThereSubs;
        var ChkIdentityClass = _isParent ? "Parent_" + level : "Child_" + level;
        if (isChildObject) {
            itemHtml += '<span data-id="' +
                sourceItem[this.options.keys[1].value] +
                '" class="comboTreeItemTitle"><input type="checkbox" class="' + ChkIdentityClass + '">' +
                sourceItem[this.options.keys[1].display] +
                '</span>';
        } else {
            itemHtml += '<span data-id="' +
                sourceItem[this.options.keys[0].value] +
                '" class="comboTreeItemTitle"><input type="checkbox" class="' + ChkIdentityClass + '">' +
                sourceItem[this.options.keys[0].display] +
                '</span>';
        }

    } else {

        itemHtml += '<span data-id="' + sourceItem[this.options.keys[0].value] + '" class="comboTreeItemTitle">' + sourceItem[this.options.keys[0].display] + '</span>';
    }

    if (isThereSubs)
        itemHtml += this.createSourceSubItemsHTML(sourceItem.subs, isThereSubs, level);

    itemHtml += '</LI>';
    return itemHtml;
};

// BINDINGS
// *****************************
ComboTree.prototype.bindings = function () {
    var _this = this;

    this._elemArrowBtn.on('click', function (e) {
        e.stopPropagation();
        _this.toggleDropDown();
    });
    this._elemInput.on('click', function (e) {
        e.stopPropagation();
        if (!_this._elemDropDownContainer.is(':visible'))
            _this.toggleDropDown();
    });
    this._elemItems.on('click', function (e) {
        e.stopPropagation();
        if ($(this).hasClass('ComboTreeItemParent')) {
            _this.toggleSelectionTree(this);
        }
    });
    this._elemItemsTitle.on('click', function (e) {
        e.stopPropagation();
        if (_this.options.isMultiple)
            _this.multiItemClick(this);
        else
            _this.singleItemClick(this);
    });
    this._elemItemsTitle.on("mousemove", function (e) {
        e.stopPropagation();
        _this.dropDownMenuHover(this);
    });

    // KEY BINDINGS
    this._elemInput.on('keyup', function (e) {
        e.stopPropagation();

        switch (e.keyCode) {
            case 27:
                _this.closeDropDownMenu(); break;
            case 13:
            case 39: case 37: case 40: case 38:
                e.preventDefault();
                break;
            default:
                _this.filterDropDownMenu();
                break;
        }
    });
    this._elemInput.on('keydown', function (e) {
        e.stopPropagation();

        switch (e.keyCode) {
            case 9:
                _this.closeDropDownMenu(); break;
            case 40: case 38:
                e.preventDefault();
                _this.dropDownInputKeyControl(e.keyCode - 39); break;
            case 37: case 39:
                e.preventDefault();
                _this.dropDownInputKeyToggleTreeControl(e.keyCode - 38);
                break;
            case 13:
                if (_this.options.isMultiple)
                    _this.multiItemClick(_this._elemHoveredItem);
                else
                    _this.singleItemClick(_this._elemHoveredItem);
                e.preventDefault();
                break;
            default:
            //if (!_this.options.isMultiple)
            //e.preventDefault();
        }
    });
    // ON FOCUS OUT CLOSE DROPDOWN
    $(document).on('mouseup.' + _this.comboTreeId, function (e) {
        if (!_this._elemWrapper.is(e.target) && _this._elemWrapper.has(e.target).length === 0 && _this._elemDropDownContainer.is(':visible'))
            _this.closeDropDownMenu();
    });

    $('#searchInput_' + this.comboTreeId).on('keyup',
        function (e) {
            var _comboTreeId = this.id.split('_')[1];
            var _ddlContainer = $('#' + _comboTreeId + 'DropDownContainer');
            var _ddlElemItemsTitle = _ddlContainer.find('span.comboTreeItemTitle');

            var searchText = this.value;
            if (searchText !== "") {
                _ddlElemItemsTitle.hide();
                _ddlElemItemsTitle.siblings("span.comboTreeParentPlus").hide();
                var ddlLi = _ddlContainer.find('li');
                list = ddlLi.find("span:icontains('" + this.value + "')").each(function (i, elem) {
                    $(this).show();
                    $(this).siblings("span.comboTreeParentPlus").show();
                    if ($(this).closest('li').hasClass('ComboTreeItemChild')) {
                        var parent = $(this).closest('li.ComboTreeItemParent');
                        parent.find('span.comboTreeParentPlus').show();
                        parent.find('span.comboTreeParentPlus').siblings('span.comboTreeItemTitle').show();
                    }

                });
            } else {
                _ddlElemItemsTitle.show();
                _ddlElemItemsTitle.siblings("span.comboTreeParentPlus").show();
            }
        });
};

// EVENTS HERE 
// ****************************

// DropDown Menu Open/Close
ComboTree.prototype.toggleDropDown = function () {
    this._elemDropDownContainer.slideToggle(50);
    this._elemInput.focus();
};
ComboTree.prototype.closeDropDownMenu = function () {
    this._elemDropDownContainer.slideUp(50);
};
// Selection Tree Open/Close
ComboTree.prototype.toggleSelectionTree = function (item, direction) {
    var subMenu = $(item).children('ul')[0];
    if (direction === undefined) {
        if ($(subMenu).is(':visible'))
            $(item).children('span.comboTreeParentPlus').html("+");
        else
            $(item).children('span.comboTreeParentPlus').html("&minus;");

        $(subMenu).slideToggle(50);
    }
    else if (direction === 1 && !$(subMenu).is(':visible')) {
        $(item).children('span.comboTreeParentPlus').html("&minus;");
        $(subMenu).slideDown(50);
    }
    else if (direction === -1) {
        if ($(subMenu).is(':visible')) {
            $(item).children('span.comboTreeParentPlus').html("+");
            $(subMenu).slideUp(50);
        }
        else {
            this.dropDownMenuHoverToParentItem(item);
        }
    }

};

// SELECTION FUNCTIONS
// *****************************
ComboTree.prototype.singleItemClick = function (ctItem) {
    this._selectedItem = {
        id: $(ctItem).attr("data-id"),
        title: $(ctItem).text()
    };

    this.refreshInputVal();
    this.closeDropDownMenu();
};
ComboTree.prototype.multiItemClick = function (ctItem) {

    var chkBx = $(ctItem).find('input');
    var chkBxClassArr = chkBx.attr('class').split('_');
    var level = chkBxClassArr[1];

    this._selectedItem = {
        id: $(ctItem).attr("data-id"),
        title: $(ctItem).text()
    };
    var tempObj = this;
    if (chkBxClassArr[0] === 'Parent') {
        $(ctItem).find("input").prop('checked', chkBx[0].checked ? false : true);

        $(this._elemItems).find('.Child_' + level).closest('span').each(function (e, i) {

            var selectedItem = {
                id: $(this).attr('data-id'),
                title: $(this).text()
            };

            var index;
            if (chkBx[0].checked) {
                index = ComboTree.prototype.isItemInArray(selectedItem, tempObj._selectedItems);
                if (!index) {
                    tempObj._selectedItems.push(selectedItem);
                }
                $(this).find("input").prop('checked', true);
            } else {
                index = ComboTree.prototype.isItemInArray(selectedItem, tempObj._selectedItems);
                tempObj._selectedItems.splice(parseInt(index), 1);
                $(this).find("input").prop('checked', false);
            }

        });
        this._selectedItems = tempObj._selectedItems;
    } else {

        var index = this.isItemInArray(this._selectedItem, this._selectedItems);
        if (index) {
            this._selectedItems.splice(parseInt(index), 1);
            $(ctItem).find("input").prop('checked', false);
        }
        else {
            this._selectedItems.push(this._selectedItem);
            $(ctItem).find("input").prop('checked', true);
        }
    }

    this.refreshInputVal();
};

ComboTree.prototype.isItemInArray = function (item, arr) {

    for (var i = 0; i < arr.length; i++)
        if (item.id === arr[i].id && item.title === arr[i].title)
            return i + "";

    return false;
};

ComboTree.prototype.refreshInputVal = function () {
    var tmpTitle = "";

    if (this.options.isMultiple) {
        for (var i = 0; i < this._selectedItems.length; i++) {
            tmpTitle += this._selectedItems[i].title;
            if (i < this._selectedItems.length - 1)
                tmpTitle += ", ";
        }
    } else {
        tmpTitle = this._selectedItem.title;
    }

    this._elemInput.val(tmpTitle);
};

ComboTree.prototype.dropDownMenuHover = function (itemSpan, withScroll) {
    this._elemItems.find('span.comboTreeItemHover').removeClass('comboTreeItemHover');
    $(itemSpan).addClass('comboTreeItemHover');
    this._elemHoveredItem = $(itemSpan);
    if (withScroll)
        this.dropDownScrollToHoveredItem(this._elemHoveredItem);
};

ComboTree.prototype.dropDownScrollToHoveredItem = function (itemSpan) {
    var curScroll = this._elemDropDownContainer.scrollTop();
    this._elemDropDownContainer.scrollTop(curScroll + $(itemSpan).parent().position().top - 80);
};

ComboTree.prototype.dropDownMenuHoverToParentItem = function (item) {
    var parentSpanItem = $($(item).parents('li.ComboTreeItemParent')[0]).children("span.comboTreeItemTitle");
    if (parentSpanItem.length)
        this.dropDownMenuHover(parentSpanItem, true);
    else
        this.dropDownMenuHover(this._elemItemsTitle[0], true);
};

ComboTree.prototype.dropDownInputKeyToggleTreeControl = function (direction) {
    var item = this._elemHoveredItem;
    if ($(item).parent('li').hasClass('ComboTreeItemParent'))
        this.toggleSelectionTree($(item).parent('li'), direction);
    else if (direction === -1)
        this.dropDownMenuHoverToParentItem(item);
};

ComboTree.prototype.dropDownInputKeyControl = function (step) {
    if (!this._elemDropDownContainer.is(":visible"))
        this.toggleDropDown();

    var list = this._elemItems.find("span.comboTreeItemTitle:visible");
    i = this._elemHoveredItem ? list.index(this._elemHoveredItem) + step : 0;
    i = (list.length + i) % list.length;

    this.dropDownMenuHover(list[i], true);
};

ComboTree.prototype.filterDropDownMenu = function () {
    var searchText = this._elemInput.val();
    if (searchText !== "") {
        this._elemItemsTitle.hide();
        this._elemItemsTitle.siblings("span.comboTreeParentPlus").hide();
        list = this._elemItems.find("span:icontains('" + this._elemInput.val() + "')").each(function (i, elem) {
            $(this).show();
            $(this).siblings("span.comboTreeParentPlus").show();
        });
    } else {
        this._elemItemsTitle.show();
        this._elemItemsTitle.siblings("span.comboTreeParentPlus").show();
    }
};

// Retuns Array (multiple), Integer (single), or False (No choice)
ComboTree.prototype.getSelectedItemsId = function () {
    if (this.options.isMultiple && this._selectedItems.length > 0) {
        var tmpArr = [];
        for (i = 0; i < this._selectedItems.length; i++)
            tmpArr.push(this._selectedItems[i].id);

        return tmpArr;
    } else if (!this.options.isMultiple && this._selectedItem.hasOwnProperty('id')) {
        return this._selectedItem.id;
    }
    return false;
};

// Retuns Array (multiple), Integer (single), or False (No choice)
ComboTree.prototype.getSelectedItemsTitle = function () {
    if (this.options.isMultiple && this._selectedItems.length > 0) {
        var tmpArr = [];
        for (i = 0; i < this._selectedItems.length; i++)
            tmpArr.push(this._selectedItems[i].title);

        return tmpArr;
    } else if (!this.options.isMultiple && this._selectedItem.hasOwnProperty('id')) {
        return this._selectedItem.title;
    }
    return false;
};

ComboTree.prototype.unbind = function () {
    this._elemArrowBtn.off('click');
    this._elemInput.off('click');
    this._elemItems.off('click');
    this._elemItemsTitle.off('click');
    this._elemItemsTitle.off("mousemove");
    this._elemInput.off('keyup');
    this._elemInput.off('keydown');
    this._elemInput.off('mouseup.' + this.comboTreeId);
    $(document).off('mouseup.' + this.comboTreeId);
};

ComboTree.prototype.destroy = function () {
    this.unbind();
    this._elemWrapper.before(this._elemInput);
    this._elemWrapper.remove();
    this._elemInput.removeData('plugin_' + comboTreePlugin);
};

$.fn[comboTreePlugin] = function (options) {
    var ctArr = [];
    this.each(function () {
        if (!$.data(this, 'plugin_' + comboTreePlugin)) {
            $.data(this, 'plugin_' + comboTreePlugin, new ComboTree(this, options));
            ctArr.push($(this).data()['plugin_' + comboTreePlugin]);
        }
    });

    if (this.length === 1)
        return ctArr[0];
    else
        return ctArr;
};

})(jQuery, window, document); `

harishksoft commented 5 years ago

@kirlisakal is there any option of selecting children when parent selected? and returning all selected ids>

ARr0w commented 5 years ago

@harishksoft try the code i pasted above. I managed to do that.

harishksoft commented 5 years ago

@ARr0w image

issues in your script:

  1. Check the above image. every option is shown as undefined.
  2. the parent category not selectable, so the option of selecting children when parent choose will not work
ARr0w commented 5 years ago

@harishksoft

i have changed the object property for children. Its like this `obj = {

   id : 1

   title: "someTitle"

   subs: {

           subId : 4

          subTitle: "subTitle"

          subs: {

                 subId : 2

                 subTitle: "subTitle"

          }

   } 

 and so on ...

} `

itemHtml += '<span data-id="' + sourceItem.subId + '" class="comboTreeItemTitle"><input type="checkbox">' + sourceItem.subTitle + '</span>'

I also did test the search and its working great and i hope it does for you too! :)

erhanfirat commented 5 years ago

Filter is added for Multiple selection mode. Thanks.

erhanfirat commented 5 years ago

@harishksoft, there is no select sub items when parent selected function yet. Could you please open new issue for this.

erhanfirat commented 5 years ago

@ARr0w, you can download lasr version to get working copy of filterin on multiselect.