/*! * Select2-to-Tree 1.1.1 * https://github.com/clivezhg/select2-to-tree */ (function ($) { $.fn.select2ToTree = function (options) { var opts = $.extend({}, options); if (opts.treeData) { buildSelect(opts.treeData, this); } opts.closeOnSelect = false; opts.placeholder = 'Select'; opts._templateResult = opts.templateResult; opts.templateResult = function (data, container) { var label = data.text; if (typeof opts._templateResult === "function") { label = opts._templateResult(data, container); } var $iteme = $("").append(label); if (data.element) { var ele = data.element; container.setAttribute("data-val", ele.value); if (ele.className) container.className += " " + ele.className; if (ele.getAttribute("data-pup")) { container.setAttribute("data-pup", ele.getAttribute("data-pup")); } let isChecked = ''; if ($(data.element).parent().val().length) { const selectedValues = $(data.element).parent().val(); const valIndex = selectedValues.findIndex(x => x === data.id); valIndex != -1 ? isChecked = 'checked' : ''; } else { data.selected ? isChecked = 'checked' : ''; } //if ($(container).hasClass("non-leaf")) { return $.merge($(``), $iteme); //} } return $iteme; }; window.expColMouseupHandler = function (evt) { toggleSubOptions(evt.target || evt.srcElement); /* prevent Select2 from doing "select2:selecting","select2:unselecting","select2:closing" */ evt.stopPropagation ? evt.stopPropagation() : evt.cancelBubble = true; evt.preventDefault ? evt.preventDefault() : evt.returnValue = false; } var s2inst = this.select2(opts); s2inst.on("select2:open", function (evt) { var s2data = s2inst.data("select2"); s2data.$dropdown.addClass("s2-to-tree"); s2data.$dropdown.removeClass("searching-result"); var $allsch = s2data.$dropdown.find(".select2-search__field").add(s2data.$container.find(".select2-search__field") ); $allsch.off("input", inputHandler); $allsch.on("input", inputHandler); s2data.dropdown.$dropdown.off('click').click(function (e) { e.stopPropagation(); }); }); s2inst.on("select2:select select2:unselect", function (e) { const data = e.params.data; if (data.selected) { $(`#${data._resultId}`).find('.s2-to-tree-checkbox').prop('checked', true); } else { $(`#${data._resultId}`).find('.s2-to-tree-checkbox').prop('checked', false); } }); window.s2TreeChkHandler = function (evt) { const selectedValues = s2inst.val(); const selectedVal = s2inst.find(`option[value="${$(evt.target).parents('.select2-results__option').data('val')}"]`).val(); if ($(evt.target).is(':checked')) { selectedValues.push(selectedVal); } else { selectedValues.splice($.inArray(selectedVal, selectedValues), 1); } s2inst.val(selectedValues).trigger('change'); } /* Show search result options even if they are collapsed */ function inputHandler(evt) { var s2data = s2inst.data("select2"); if ($(this).val().trim().length > 0) { s2data.$dropdown.addClass("searching-result"); } else { s2data.$dropdown.removeClass("searching-result"); } } return s2inst; }; /* Build the Select Option elements */ function buildSelect(treeData, $el) { /* Support the object path (eg: `item.label`) for 'valFld' & 'labelFld' */ function readPath(object, path) { var currentPosition = object; for (var j = 0; j < path.length; j++) { var currentPath = path[j]; if (currentPosition[currentPath]) { currentPosition = currentPosition[currentPath]; continue; } return 'MISSING'; } return currentPosition; } function buildOptions(dataArr, curLevel, pup) { var labelPath; if (treeData.labelFld && treeData.labelFld.split('.').length> 1){ labelPath = treeData.labelFld.split('.'); } var idPath; if (treeData.valFld && treeData.valFld.split('.').length > 1) { idPath = treeData.valFld.split('.'); } for (var i = 0; i < dataArr.length; i++) { var data = dataArr[i] || {}; var $opt = $(""); if (labelPath) { $opt.text(readPath(data, labelPath)); } else { $opt.text(data[treeData.labelFld || "text"]); } if (idPath) { $opt.val(readPath(data, idPath)); } else { $opt.val(data[treeData.valFld || "id"]); } if (data[treeData.selFld || "selected"] && String(data[treeData.selFld || "selected"]) === "true") { $opt.prop("selected", data[treeData.selFld || "selected"]); } if($opt.val() === "") { $opt.prop("disabled", true); $opt.val(getUniqueValue()); } $opt.addClass("l" + curLevel); if (pup) $opt.attr("data-pup", pup); $el.append($opt); var inc = data[treeData.incFld || "inc"]; if (inc && inc.length > 0) { $opt.addClass("non-leaf"); buildOptions(inc, curLevel+1, $opt.val()); } } // end 'for' } // end 'buildOptions' buildOptions(treeData.dataArr, 1, ""); if (treeData.dftVal) $el.val(treeData.dftVal); } var uniqueIdx = 1; function getUniqueValue() { return "autoUniqueVal_" + uniqueIdx++; } function toggleSubOptions(target) { $(target.parentNode).toggleClass("opened"); showHideSub(target.parentNode); } function showHideSub(ele) { var curEle = ele; var $options = $(ele).parent(".select2-results__options"); var shouldShow = true; do { var pup = ($(curEle).attr("data-pup") || "").replace(/'/g, "\\'"); curEle = null; if (pup) { var pupEle = $options.find(".select2-results__option[data-val='" + pup + "']"); if (pupEle.length > 0) { if (!pupEle.eq(0).hasClass("opened")) { // hide current node if any parent node is collapsed $(ele).removeClass("showme"); shouldShow = false; break; } curEle = pupEle[0]; } } } while (curEle); if (shouldShow) $(ele).addClass("showme"); var val = ($(ele).attr("data-val") || "").replace(/'/g, "\\'"); $options.find(".select2-results__option[data-pup='" + val + "']").each(function () { showHideSub(this); }); } })(jQuery);