jQuery可拖动+可排序与自定义HTML的放置事件?

7

当元素拖放到可拖放区域时,更改html。

类似于这样:http://the-stickman.com/files/jquery/draggable-sortable.html

但是当我放置元素时,会更改已放置的html。

其他示例:我有2个列表,第一个是可拖动列表,第二个是可放置列表,当我从第一个列表中拖动元素并将其放入第二个列表中时,该元素将被克隆到第二个列表中。

拖动:

<a href="#">test</a>

放置:

<a href="#">test</a>

我想将这个 HTML 更改为:

拖动:

<a href="#">test</a>

删除:

<div class="toggle"><a href="#">test</a></div>

1
请编辑您的问题。很抱歉,我不明白您想做什么和您的期望是什么。您想要改变什么? - JMax
4个回答

11

请查看这个演示 http://jsfiddle.net/yeyene/7fEQs/8/

您可以按照自己的意愿自定义下拉元素。

$(function() {
    $( "#draggable li" ).draggable({
        connectToSortable: "#sortable",
        helper: "clone",
        revert: "invalid"
    });

    $( "#sortable" ).sortable({
        revert: true,
        receive: function(event, ui) {
            var html = [];
            $(this).find('li').each(function() {
                html.push('<div class="toggle">'+$(this).html()+'</div>');
            });
            $(this).find('li').replaceWith(html.join(''));
        }
    });
});

5
这是一个非常基础的例子,但适用于几种不同的情况。我使用了jQuery UI Draggable + Sortable作为示例,并在<ul id="sortable">元素上绑定了.droppable()小部件,除了.sortable()小部件之外。 尽管不是最明智的方式,在可放置的小部件的drop事件中,我检查一个变量的值来确定移动元素的来源。(它是来自可排序列表还是我的拖动元素之一?) 如果它确实来自拖动元素之一,我就将其HTML更改为所需内容。否则它保持不变(因为你只是重新排列可排序的顺序)。
<ul>
    <li id="draggable" class="ui-state-highlight">Drag me down</li>
</ul>
<br />
<br />
<br />
<ul id="sortable">
    <li class="ui-state-default">Item 1</li>
    <li class="ui-state-default">Item 2</li>
    <li class="ui-state-default">Item 3</li>
    <li class="ui-state-default">Item 4</li>
    <li class="ui-state-default">Item 5</li>
</ul>

JS

$(function () {
     var origin = 'sortable';
     $("#sortable").droppable({
         drop: function (event, ui) {
             if (origin === 'draggable') {
                 ui.draggable.html('<span>Look at this new fancy HTML!</span>');
                 console.log(ui.draggable);
                 origin = 'sortable';
             }
         }
     }).sortable({
         revert: true
     });
     $("#draggable").draggable({
         connectToSortable: "#sortable",
         helper: "clone",
         revert: "invalid",
         start: function () {
             origin = 'draggable';
         }
     });

 });

演示用的 jsfiddle

这个例子相当无聊,因为新的 HTML 是静态的。但是假设你有一个自定义助手程序来实现每个可拖动元素,这应该成为你的新 HTML。 因此,你可以将一些 HTML 片段存储在数组中,并选择与索引或其他适配项匹配的条目。 它可能会像这样:

var helpersArr = ['<input type="text" />', '<input type="file" />', '<input type="submit" value="Save" />'];
var helper;
//draggable
helper: function () {
    helper = helpersArr[$(this).index()];
    return helper;
}
//dropppable drop function
ui.draggable.html(helper);

第二个例子的jsfiddle

我相信你也可以通过避免使用helper变量并改用ui.helper来实现相同的结果,但我无法弄清如何获取其中的HTML部分。如果这不能满足你的需求,请告诉我。总的来说,我认为你可以将我的示例用作更改拖放元素的HTML的不同目标的起点。


你好,能否分享一下如何从服务器 / ajax 加载填充项来实现动态加载,而不是使用以下这种方式 var helpersArr = ['<input type="text" />', '<input type="file" />', '<input type="submit" value="Save" />']; - user3390927

2
我曾遇到过一个类似的问题,需要更加复杂的结果。我的系统从左侧的一个包含其他带有表单元素名称和id的div中拖动,它们会落入右侧的可排序的div中,成为一个Web表单。因为我需要右侧的div紧密地类似于一个没有额外标记的表单内容,所以使用无序列表是不可行的,除非我想在输入数据库之前进行一些“清洗”。我的例子中,当我从左侧的列表中拖动时,我必须使用拖动元素的id通过ajax查找许多东西,然后根据ajax的结果将标签、表单元素和验证放入左侧的列表中。出于明确起见,我从我的例子中删除了ajax。

因此,本质上,您正在采取两个并排的div,使用可拖拽和可排序的列表连接。关键是,在Sortable中有回调函数,你必须利用它们。 "接收"回调函数仅在向可排序列表添加新元素时才会触发。这很重要,因为您必须区分变化,以免在排序时产生影响。但是你不能仅仅使用"receive",因为如果你试图在该回调函数中操作html,你将影响你从中拖动的列表而不是你拖动到的列表。为了跟踪它是列表添加还是拖动,我在$.data中设置了一个名为"newlement"的变量为1,如果它是列表添加,则在更新回调函数中检查它,以查看是否应该影响拖动的html。在我的情况下,我不想对被拖动的元素进行任何操作。

因此,HTML:

<div class='master_list'>
  <div id="2">First Name</div>
  <div id="3">Last Name</div>
</div>

<div id="webform_container">
</div>

以及jQuery:

$( ".master_list div" ).draggable({
    connectToSortable: "#webform_container",
    helper: "clone",
    revert: "invalid"
});


$( "#webform_container" ).sortable({
    revert: true,
    cursor: 'pointer',
    placeholder: "placeholderdiv",
    connectWith: '.master_list',
    start: function() {
            /* Clear the value of newelement at start */
        $(this).data('newelement', 0);
    },
    receive: function(event, ui) {
            /* Get id from function and pass to the update to do stuff with */
        $(this).data('id', ui.item[0].id);
            /* Set value of newelement to 1 only when new element is added to list */
        $(this).data('newelement', 1);
    },
    update: function(event, ui) {
        /* If newelement ==1, this is a new element to the list, transform it */
        if ($(this).data('newelement') == 1) {
            var fieldname = ui.item.text();
            ui.item.html('your new html here');         
        }
    }

});


这正是我所需要的,不过我想从服务器/数据库加载HTML。您能否分享一下Ajax,以及如何避免清理和附加的方法。 - user3390927

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接