简体   繁体   中英

Remove a specific span in an element if have child - jquery

I'm using nestedsortable jQuery ( http://mjsarfatti.com/sandbox/nestedSortable/ ). In the list, the user can drag and drop the items until level 3. Basically, the item can have father and grandfather.

If the item don't have child, it's going to append the span element, that include the input file. And if the item is the father or grandfather, cannot show the input file element. So, when I drag and drop an item within another item (father), this is works. But when I drag and drop an item within the item dropped previously, the input file don't desappears.

JSFiddle

I've posted 5 images to understand better.

For example: 我有这个清单

我将项目5和项目7改为项目6。项目6是项目5和7的父项。文件按钮出现在这些项目中,因为它们没有孩子。

当我从项目6中拖放项目5时,按钮文件消失在项目5中。

当我将第5项拖放到第7项时,在第5项中会出现按钮文件(是正确的!但是在第7项中,按钮文件不会消失。实际上,该按钮会消失!

而且,如果我将项目7拖放到raiz,该按钮不会消失。

The code:

<ol class="sortable">
        <li id="list_1"><div><span class="disclose"><span></span></span>Item 1<span title="Click to delete item." data-id="1" class="deleteMenu ui-icon ui-icon-closethick">X</span></div>
            <ol>
                <li id="list_2"><div><span class="disclose"><span></span></span>Sub Item 1.1<span title="Click to delete item." data-id="2" class="deleteMenu ui-icon ui-icon-closethick">X</span></div>
                    <ol>
                        <li id="list_3"><div><span class="disclose"><span></span></span>Sub Item 1.2<span title="Click to delete item." data-id="3" class="deleteMenu ui-icon ui-icon-closethick">X</span></div>
                    </ol>
            </ol>
        <li id="list_4"><div><span class="disclose"><span></span></span>Item 2<span title="Click to delete item." data-id="4" class="deleteMenu ui-icon ui-icon-closethick">X</span></div>
        <li id="list_5"><div><span class="disclose"><span></span></span>Item 3<span title="Click to delete item." data-id="5" class="deleteMenu ui-icon ui-icon-closethick">X</span></div>
            <ol>
                <li id="list_6" class="mjs-nestedSortable-no-nesting"><div><span class="disclose"><span></span></span>Sub Item 3.1 (no nesting)<span title="Click to delete item." data-id="6" class="deleteMenu ui-icon ui-icon-closethick">X</span></div>
                <li id="list_7"><div><span class="disclose"><span></span></span>Sub Item 3.2<span title="Click to delete item." data-id="7" class="deleteMenu ui-icon ui-icon-closethick">X</span></div>
                    <ol>
                        <li id="list_8"><div><span class="disclose"><span></span></span>Sub Item 3.2.1<span title="Click to delete item." data-id="8" class="deleteMenu ui-icon ui-icon-closethick">X</span></div>
                    </ol>
            </ol>
        <li id="list_9"><div><span class="disclose"><span></span></span>Item 4<span title="Click to delete item." data-id="9" class="deleteMenu ui-icon ui-icon-closethick">X</span></div>
        <li id="list_10"><div><span class="disclose"><span></span></span>Item 5<span title="Click to delete item." data-id="10" class="deleteMenu ui-icon ui-icon-closethick">X</span></div>
    </ol>

Javascript:

$('ol.sortable').nestedSortable({
        forcePlaceholderSize: true,
        handle: 'div',
        helper: 'clone',
        items: 'li',
        opacity: .6,
        placeholder: 'placeholder',
        revert: 250,
        tabSize: 25,
        tolerance: 'pointer',
        toleranceElement: '> div',
        maxLevels: 3,
        isTree: true,
        expandOnHover: 700,
        startCollapsed: true,
        stop: function(event, ui) {
            //get item id
            var id = $(ui.item).attr('id');
            var res = id.substr(5);

            //check the item have child
            if($('#list_'+res).find('ol').length != 0) {
                //The item have child!
                $(this).parent('span.file_upload').remove();
            } else {
                //The item don't have child!
                //check the item have father
                if ($('#list_'+res).parent().is('ol.sortable')) {
                    //The item don't have father
                    $('#list_'+res).find('span.file_upload').remove();
                } else {
                    //The item have father!
                    //avoid multiple button file (only one!)
                    if ($('#list_'+res).find('span.file_upload').length == 0) {
                        //insert the file button
                        $('#list_'+res).append(
                            '<span class="file_upload" title="Click to upload a file." id="res" class="deleteMenu">'
                            + '<input name="upload_file" type="file" class="new_file" />'
                            + '</span>');
                    }
                }
            }
        }

    });

I propose an alternative approach. Instead of adding/removing single file uploads, each time remove all file upload spans and add spans where needed. I am not sure I fully understand the logic governing when we should or shouldn't have upload spans. So you'll need to change that in the sample below:

HTML

<div class="template" style="display:none">
    <span class="file_upload" class="deleteMenu">
        <input name="upload_file" type="file" class="new_file" />
    </span>
</div>

JS

var $fu_span;

$(document).ready(function(){    
    $fu_span = $("div.template").html();
    $("div.template").remove();
    $('ol.sortable').nestedSortable({
        ...
        stop: mount_file_uploads
    });
});

function mount_file_uploads() {
    var $root = $("body > ol.sortable");
    $root.find("span.file_upload").remove();
    $("li li.mjs-nestedSortable-leaf").append($fu_span);
}

JSFiddle

Update The OP described a case where we expect to have a file upload input to be added but it is not. Inspecting the code I realized that if you move an only-child item elsewhere, its former parent does not get a class of mjs-nestedSortable-leaf and an empty <ol> still remains there.

The plugin does not expose any method to discover leaf nodes, so we are using its internal state to find them.

I reported this issue but, as there is no api method, the maintainer may not consider this to be a bug .

Anyway, I have added a few lines as a workaround. Here is the updates mount_file_uploads function:

function mount_file_uploads() {
    var $root = $("body > ol.sortable");
    var $ol;
    $root.find("span.file_upload").remove();
    $root.find("ol").each(function(){
        $ol = $(this);
        if($ol.children().length === 0) {
            $ol.addClass("empty-ol");
            $ol.parent().addClass("mjs-nestedSortable-leaf");
        }
    });
    $("ol.empty-ol").remove();
    $("li li.mjs-nestedSortable-leaf").append($fu_span);
}

Updated JSFiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM