javascript - treeview JS 中的限制 - 仅选中一个复选框

标签 javascript html jquery treeview

我在 JS 中完成的“ TreeView ”有一个小问题 TreeView 工作正常,但现在我需要应用一些限制。

TreeView 具有以下结构: 父>节点>节点

限制是我不能在“父”中选择一个以上的“节点”,反过来,在它的“节点”中,我也不能选择一个以上的“子节点”。也就是说,我只能在每个父节点之间标记一个复选框。

如果我在“子节点”中设置了另一个复选框,您必须取消选中已有的复选框并标记新的复选框(如单选按钮)。

和“节点”一样,每个“父节点”内只能标记一个节点

<div id="treeview-container">
        <ul>
            <li>Parent 1</li>
            <li>Parent 2
                <ul>
                    <li>node 2.1</li>
                    <li>node 2.2
                        <ul>
                            <li data-value="2.2.1">subnode 2.2.1</li>
                            <li data-value="2.2.2">subnode 2.2.2</li>
                            <li data-value="2.2.3">subnode 2.2.3</li>
                        </ul>
                    </li>
                    <li>node 2.3</li>
                </ul>
            </li>
            <li>parent 3
                <ul>
                    <li data-value="3.1">node 3.1</li>
                    <li data-value="3.2">node 3.2</li>
                </ul>
            </li>
        </ul>
    </div>

这里是 JS:

    (function( $ ){
    var plugin = {
        name: 'TreeView',
        version: '1.0.0'
    }
    var defaults = {
        debug : false,
        autoExpand : false,
        css : {
            list : 'fa-ul',
            listItem : 'fa-li fa',
            collapsed : 'fa-caret-right',
            expanded : 'fa-caret-down'
        }
    }
    
    var settings;
    var debug, me = null;
    
    function __changeHandler( e ) {
        var currentTarget = $(this);
        var isChecked = currentTarget.is(':checked');
        
        debug.log(currentTarget);
        debug.log("Checked ", isChecked)
        
        if (!isChecked) {
            debug.log('Uncheck all childs');
            
            currentTarget.parent()
                         .find('input.tw-control')
                         .prop('checked', false);
        }
        
        if (isChecked) {
            debug.log('Check my parents tree');
            
            currentTarget.parents('li')
                         .find('>input.tw-control')
                         .prop('checked', true);
        }
        
        _toggleCollapse( currentTarget );
        
        me.trigger('treeview.change', currentTarget, me);
    }
    
    function _toggleCollapse ( element ) {
        debug.log("Toggle collapse");
        
        var chk = $('input[type="checkbox"]:checked');
        
        if (chk.is(':checked')) {
            debug.log('Open checked branchs');
            chk.parent()
               .find('>ul.collapse')
               .collapse('show')
               .parent()
               .find('>i.fa-li')
               .removeClass(settings.css.collapsed)
               .addClass(settings.css.expanded);
        }
        
        if (!element.is(':checked')) {
            debug.log('Hide branch');
            
            element.parent()
                   .find('ul.collapse')
                   .collapse('hide')
                   .parent()
                   .find('i.fa-li')
                   .removeClass(settings.css.expanded)
                   .addClass(settings.css.collapsed);
        }
    }
    
    function _init() {
        debug.log( "Initializing plugin" );
        
        me.on('change', 'input.tw-control', __changeHandler);
        
        debug.log("Collapsing tree");
        
        
        me.find('>ul')
          .addClass(settings.css.list)
          .find('ul')
          .addClass('collapse ' +  settings.css.list)
          .parent()
          .prepend(
              $('<i></i>').addClass(settings.css.listItem + ' ' +
                                    settings.css.collapsed)
          );
          
        if (settings.autoExpand) {
            me.find('ul.collapse').collapse('show');
        }
        
        debug.log("Adding checkbox");
            
        me.find('li').each(function( index, element ) {
            var elmt = $(element);
            
            var chk = $('<input/>').prop('type', 'checkbox')
                                   .prop('class', 'tw-control')
                                   .prop('value', elmt.attr('data-value'));
            
            debug.log("Checking if the element is selected");
            
            var isChecked = elmt.attr('data-checked');
            
            elmt.prepend(chk);
            
            if ( isChecked ) {
                debug.log('Toggle checkbox');
                
                chk.prop('checked', true);
                
                chk.trigger('change');
            }
        });
    }
    
    function _fill( data ) {
        $( data ).each(function (index, element) {
            me.find('input[value="' + element + '"]')
              .prop('checked', true)
              .trigger('change');
        });
    }
    
    var publicMethods = {
        init : function( options ) {
            me = this;
            
            settings = $.extend( defaults, options );
            
            debug = $.Logger(settings.debug, plugin);
            
            _init();
            
            debug.log('Ready');
            
            _fill ( options.data );
            
            return this;
        },
        selectedValues: function() {
            debug.log("Getting selected values");
            
            var chk = me.find('input[type="checkbox"]:checked');
            var output = [];
            
            chk.each(function(index, item) {
                var item = $(item);
                
                if(typeof item.parent().attr('data-value') !== typeof undefined) {
                    output.push(item.attr('value'));
                }
            })
            
            return output;
        }
    }
    
    $.fn.treeview = function (options) {
        if ( publicMethods[options] ) {
            return publicMethods[ options ].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof options === 'object' || ! options ) {
            // Default to "init"
            return publicMethods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' +  options  + ' does not exist on jQuery.treeview' );
        }
    }
    
}( jQuery ));

$('#treeview-container').treeview({
            debug : true,
            data : ['3.2', '2.2.3']
        });

http://codepen.io/vilacactus/pen/BpMjOp?editors=1010#0

最佳答案

您可以监听 treeview.change 事件并为所有 sibling 设置 checked 为 false:

$('#treeview-container').treeview({
  debug : false,
  data : ['3.2', '2.2.3']
});
$('#treeview-container').on("treeview.change", function (e, ele) {
  if ($(ele).parents('ul').length > 1) {  // not on root elements
    $(ele).closest('li').siblings().find(':checkbox').prop('checked', false);
  }
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="http://www.jqueryscript.net/demo/Checkable-Collapsible-jQuery-Tree-View-Plugin-Treeview/dev/logger.js"></script>
<script src="http://www.jqueryscript.net/demo/Checkable-Collapsible-jQuery-Tree-View-Plugin-Treeview/dev/treeview.js"></script>


<div id="treeview-container">
    <ul>
        <li>Parent 1</li>
        <li>Parent 2
            <ul>
                <li>node 2.1</li>
                <li>node 2.2
                    <ul>
                        <li data-value="2.2.1">subnode 2.2.1</li>
                        <li data-value="2.2.2">subnode 2.2.2</li>
                        <li data-value="2.2.3">subnode 2.2.3</li>
                    </ul>
                </li>
                <li>node 2.3</li>
            </ul>
        </li>
        <li>Parent 3
            <ul>
                <li data-value="3.1">node 3.1</li>
                <li data-value="3.2">node 3.2</li>
            </ul>
        </li>
    </ul>
</div>

关于javascript - treeview JS 中的限制 - 仅选中一个复选框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42213451/

相关文章:

javascript - 单击当前页面上的链接后保持菜单项处于事件状态

javascript - 修改 onHeadersReceived 上的 header

javascript - JS : Callback function is not executing

javascript - MVC 3 使用 dropdownlist 和 ajax 获得新模型

javascript - 如何在 jQuery 验证器中为一条规则添加一条自定义消息并为所有其他规则添加默认消息

javascript - 如何将页面的特定部分居中,使其完美地平滑滚动?

javascript - 使用空格键播放和暂停声音

javascript - 使用 Javascript 获取每种模式的总金额

CSS扩展DIV并压低其他

html - 有定位和 div 问题