JQuery手风琴+可排序。禁用父组可拖动

时间:2014-11-13 22:13:35

标签: jquery-ui-accordion jquery-ui-sortable

我有一个按部分分组的搜索选项列表,并使用accordion折叠。用户展开一个部分并将其选择拖动到"保存列表"。这些字段将保存并用于我站点中表的自定义列。除了一些小事之外,一切都很顺利。

  1. 我想锁定父母(个人,教育,主题)并且只有内部的li元素可以拖动。现在,用户可以将整个组拖到顶部,这是不可取的,因为我有可以搜索的字段限制。拖动整个部分可能会超出该限制并打破我的表格。

  2. 在IE中,在折叠父级之后,li元素" blip"在隐藏之前可见一秒钟。 不是很大,但可能很烦人,特别是对我的一些挑剔的用户:)

  3. 代码如下。有关样式,请参阅我的设置的Fiddle

    我已经到了无法看到森林树木的地步,所以如果我可以指向正确的方向,那将非常感激!

    HTML:

    <div class="demo">
        <div id="swaplist" style="height: 0;"></div>
        <ul id="sortable2" class='saved'>
            <div class="container" style="overflow:auto;">
                <div align='center'>
                     <h2>Saved List</h2>
    
                </div>
                <div class="group"></div>
            </div>
        </ul>
        <br />
        <ul id="sortable1" class='available'>
            <div align='center'>
                 <h2>Available Fields</h2>
    
            </div>
            <br />
            <div id="accordion" style="width:950px;">
                <div class="group">
                     <h2><span class="text"><a href="#">Personal</a></span></h2>
    
                    <div class="container">
                        <ul id="sortable1" class='available' style="width:850px;">
                            <li class='ui-state-default'><b>First Name</b>
    
                                <br />Section: A</li>
                            <li class='ui-state-default'><b>Last Name</b>
    
                                <br />Section: A</li>
                            <li class='ui-state-default'><b>Date of Birth</b>   
                                <br />Section: A</li>
                        </ul>
                    </div>
                </div>
                <br />
                <div class="group">
                     <h2><span class="text"><a href="#">Education</a></span></h2>
    
                    <div class="container">
                        <ul id="sortable1" class='available' style="width:850px;">
                            <li class='ui-state-default'><b>Associate's</b>
    
                                <br />Section: B</li>
                            <li class='ui-state-default'><b>Bachelor's</b>
    
                                <br />Section: B</li>
                            <li class='ui-state-default'><b>Master's</b>
    
                                <br />Section: B</li>
                            <li class='ui-state-default'><b>Doctorate</b>
    
                                <br />Section: B</li>
                            <li class='ui-state-default'><b>Other</b>
    
                                <br />Section: B</li>
                        </ul>
                    </div>
                </div>
                <br />
                <div class="group">
                     <h2><span class="text"><a href="#">Subject</a></span></h2>
    
                    <div class="container">
                        <ul id="sortable1" class='available' style="width:850px;">
                            <li class='ui-state-default'><b>Science</b>
    
                                <br />Section: C</li>
                            <li class='ui-state-default'><b>Business</b>
    
                                <br />Section: C</li>
                            <li class='ui-state-default'><b>Liberal Arts</b>
    
                                <br />Section: C</li>
                        </ul>
                    </div>
                </div>
                <br />
            </div>
            <!-- End accordion -->
        </ul>
        <br clear="both" />
    </div>
    

    的javascript:

    $(function () {
    
        $("#accordion")
            .accordion({
            active: false,
            collapsible: true,
            animate: false,
            heightStyle: "content",
            autoHeight: false,
            header: "> div > h2"
        })
            .sortable({
            axis: "y",
            handle: "h2",
            stop: function (event, ui) {
                // IE doesn't register the blur when sorting
                // so trigger focusout handlers to remove .ui-state-focus
                ui.item.children("h2").triggerHandler("focusout");
            }
        });
    
    
        $("ul.available").sortable({
            connectWith: "ul",
            scroll: true,
            helper: 'clone', //keeps children visible when pulling out of container
            appendTo: '#swaplist' //temporarily stores children in hidden div
        });
    
        $("ul.saved").sortable({
            connectWith: "ul",
            receive: function (event, ui) {
    
                if ($(this).children().length > 9) {
                    //ui.sender: will cancel the change.
                    //Useful in the 'receive' callback.
                    $(ui.sender).sortable('cancel');
                }
            },
            items: "li[id!=nomove]",
            update: function () {
                var order = $(this).sortable("serialize") + '&action=update';
                $.post("ajax_file", order, function (theResponse) {
                    $("#info").html(theResponse);
                });
            },
            helper: 'clone', //keeps children visible when pulling out of container
            appendTo: '#swaplist' //temporarily stores children in hidden div
        });
    
        $("#sortable1, #sortable2").disableSelection();
        $("#sortable1, #sortable2").disableSelection();
    });
    

    更新:

    我发现了我需要解决的第三件事。我需要确保用户不会选择重复的选项。请参阅下面的答案。

1 个答案:

答案 0 :(得分:1)

我找到了一种锁定父母的方法!它可能不是最理想的方式,但它的工作原理。查看完整的小提琴here

对于#1 ,我在How to implement a button on a jQuery Sortable accordion header处应用了答案来锁定父母。我做了一个名为&#34; DontMove&#34;并将它们放在<h2>上,然后在每个可排序的cancel: ".DontMove"中将其设置为取消选项。以下是实现它的片段。



    $("#accordion")
        .accordion({
        active: false,
        collapsible: true,
        animate: false,
        heightStyle: "content",
        autoHeight: false,
        header: "> div > h2"
    })
        .sortable({
        axis: "y",
        handle: "h2",
        cancel: ".DontMove",
        stop: function (event, ui) {
            ui.item.children("h2").triggerHandler("focusout");
        }
    });

对于#3 ,感谢prevent duplicated item in jQueryUI sortable提供了解决方案。

这个片段是诀窍。我把它放在接收部分。



    var id = ui.item.attr('id');
    var ele = $('#sortable2').find('li[id="'+id+'"]');
    if (ele.length != 1) {
        $(ui.sender).sortable('cancel');
    }

最初的问题是,在可排序的接收函数触发并添加新元素之前,我无法获取已保存列表中的当前元素列表。所以每当我检查添加的元素是否已经存在时,它总是会被取消,因为它已经被添加,因此符合条件。

我没有打架,而是让所有的线元素具有相同的ID。如果有超过1则长度> 1所以取消掉落。我知道拥有重复ID是不好的做法,但由于列表是数据库驱动的,因此有可能发生这种情况,我想覆盖所有基础。

问题#2 而言,我不会在Firefox或Chrome中看到它发生,所以我会不理睬它,因为我最担心的是 #1 #3