JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<button class="button-add">add</button>
<button class="button-remove">remove</button>
<button class="button-undo">undo</button>
<button class="button-redo">redo</button>
<div id="selectable">
<div class="selectable-content">Item1</div>
<div class="selectable-content">Item2</div>
<div class="selectable-content">Item3</div>
<div class="selectable-content">Item4</div>
<div class="selectable-content">Item5</div>
</div>
CSS
#selectable .ui-selecting {background: #FECA40;}
#selectable .ui-selected {background: #F39814; color: white;}
#selectable {margin: 0; padding: 0; height: 300px; position: relative; padding:0; border:solid 1px #DDD;}
#selectable > div {position: absolute; margin: 0; padding:10px; border:solid 1px #CCC; width: 100px;}
.ui-selectable-helper {position: absolute; z-index: 100; border:1px dotted black;}
JavaScript
// this creates the selected variable
// we are going to store the selected objects in here
var offset = {top:0, left:0};
var elemId = 0;
// starting position of the divs
var i = 0;
$(".selectable-content").each( function() {
$(this).css({
top: i * 42
});
i++;
elemId++;
});
// buttons
$(".button-add").on("click", function(e) {
elemId++;
RecordCommand(
"Add",
{ id:"Item" + elemId, left: 0, top: 0 },
function () {
var el = $('<div class="selectable-content">' + this.Params.id + '</div>');
$(el).css("left", this.Params.left);
$(el).css("top", this.Params.top);
$("#selectable").append(el);
update();
},
function () {
$(".selectable-content:contains('" + this.Params.id + "')").remove();
}
);
/*
var el = $('<div class="selectable-content">Item ' + elemId + '</div>');
$("#selectable").append(el);
update();
*/
});
$(".button-remove").on("click", function(e) {
StartGroupRecording("GroupRemove");
$(".ui-selected").each(function() {
RecordCommand(
"Remove",
{ id: $(this).text(), left: $(this).css("left"), top: $(this).css("top") },
function () {
$(".selectable-content:contains('" + this.Params.id + "')").remove();
},
function () {
var el = $('<div class="selectable-content">' + this.Params.id + '</div>');
$(el).css("left", this.Params.left);
$(el).css("top", this.Params.top);
$("#selectable").append(el);
update();
}
);
});
FinishGroupRecording();
/*
$(".ui-selected").each(function() {
$(this).remove();
});
*/
});
function update() {
$(".selectable-content").draggable({
start: function(ev, ui) {
if (!$(this).hasClass("ui-selected")) {
$(".ui-selected").each(function() {
var el = $(this);
el.removeClass("ui-selected");
});
$(this).addClass("ui-selected");
}
...