Reputation: 319
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.
I've posted 5 images to understand better.
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>');
}
}
}
}
});
Upvotes: 0
Views: 2047
Reputation: 30252
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);
}
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);
}
Upvotes: 2