How to drag and drop <li> elements into input fields

11.8k views Asked by At

I'm trying to develop a page that has the following functionality:

Page will have two columns: one being #origin(left column), containing a list of rectangles(which represent variables), and the second one will be #drop(right column),containing inputs where the rectangles can be dropped on.

enter image description here

In order to get the result I want , I'd thought of using two plugins: jquery ui draggable and jQuery Tokeninput

The question is , how can I make that once I drop a rectangle( <li> ) into an input field , it is displayed as a tag. It'd also be OK to use the same <li> element , so long I can enter more text into the input(to complete a formula) ,and if later the user changes its mind and decides that the variable (tag) was not the one he or she wanted, the page should allow them to delete the tag(by clicking the "X" in the top-right corner or returning the tag to its original location on the left column)

Has someone done something similar already and can give me some guidance?? Or has someone another idea for this?

Any help is greatly appreciated.

P.S. If you know of any other tagging plugin that lets combine text and tags in the same input please let me know.

4

There are 4 answers

1
Muhammad Umer On BEST ANSWER

Take a look: Preview

This is my first time ever dealing with drop and drag seriously. And i kept going.

Lot can be improved. And made more efficent however, i have already spent like 3 hours on it :D.

I did learn a LOOOT.

$('.menu li').on('mousedown', function (e) {
    $(this).draggable({
        helper: "clone"
    }).css({
        opacity: '.7'
    });

});
var li = {}, i = 0;

function enable(x) {
    x.droppable({
        hoverClass: "drop-hover",
        drop: function (e, ui) {
            $(ui.draggable).clone().prependTo(this).draggable().addClass('special').data('i', $(this).data('i'));
            $(this).droppable('destroy')
        }
    });
};
$('.i1').each(function (u, n) {
    $(this).data('i', i);
    li[i] = $(this);
    i++;
});
$('.i1').each(function (u, i) {
    enable($(this));
});
$('.m').droppable({
    accept: ".special",
    drop: function (e, ui) {
        var x = $(ui.draggable).data();
        $(ui.draggable).remove();
        enable(li[x.i]);
    }
});


$('input[type="text"]').keypress(function (e) {
    if (e.which !== 0 && e.charCode !== 0) { // only characters
        var c = String.fromCharCode(e.keyCode | e.charCode);
        $span = $(this).siblings('span').first();
        $span.text($(this).val() + c); // the hidden span takes 
        // the value of the input
        $inputSize = $span.width();
        $(this).css("width", $inputSize); // apply width of the span to the input
    }
});
0
R.Falque On

You can use an input with the propriety "hidden" and use another div for the usual drag and drop like that:

<input type="hidden" name="valDrop" value="" id="valDrop"></input>
<div id="divDrop" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

Then you set the value of the input in the javascript when the drop event occurs.

function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
var val=document.getElementById("valDrop");
val.value=data;
}
0
Yudho Ahmad Diponegoro On

I did something similar. Well, for the input boxes, I did not use <input></input> but with some div elements making use of contenteditable attribute.

I believe in jQuery-UI, there is an event registered for the droppable element. In that event listener, put a code to clone the dragged element and make it as a child of the container. Position it with relative positioning.

The layout more or less is like this

<div id="1">
 <span id="2">
  <div id="3" contenteditable="true">
     <!-- where user can type something like > 18 etc -->
  </div>
 </span>
</div>

If user drags a tag, then drop event on droppable will be fired. Make a code that clone the tag (or make a new one) and place it under id="2" by insertBefore($("#3")) method in jQuery.

Another tag comes, just do another insertBefore($("#3")). So, even when we have tags in the box, user still can type. What he/she types, we can get it as $("#3").text();

0
SarathSprakash On

Try this fiddle DEMO

$(function () {
  $(".ui-widget-content").draggable({
        revert : function(event, ui) {

            $(this).data("ui-draggable").originalPosition = {
                top : 0,
                left : 0
            };

            return !event;

        }
    });
    $("#droppable").droppable();
});

Hope this helps,Thank you