JSFiddle - React, Tailwind, and code Playground

by stevea

HTML

<div id='box1' class='box'></div>
<div id='box2' class='box'></div>
<div id='box3' class='box'></div>
<div id='box4' class='box'></div>
<div id='group'></div>

CSS

.box {
    position: absolute;
/*    float: left;  */
    width: 100px;
    height: 100px;
    background: black;
    z-index: 100 ;  /* keep boxes above div#group so we can select them */
}
#box1 {
    left:10px;
    top: 15px;
}
#box2 {
    left:150px;
    top:25px;
}
#box3 {
    left:300px;
    top:35px;
}
#box4 {
    left:450px;
    top:45px;
}


#group {
    width: 100%;
    height: 100%;
//*   z-index: -1;  */
    position: absolute;
}

JavaScript

$('.box').draggable();

$('.box').click(function(){
//    debugger;
    var top;
    var left;
    var data = $(this).data('clicked'); // undefined if not clicked. true if clicked
    var group$ = $('#group');        // short hand
    if(data == undefined || data == false){
        $(this).data('clicked', true);        //  wasn't clicked. mark it clicked
        this.style.opacity = '0.3';            // dim it to show box is now in group
        $(this).draggable('disable');        // disable box's own draggable
        if(group$.children().length <= 0){   // if group empty,  this is first member
            group$.draggable().css({        // make group draggable
                top: '0px',                // position group at top left (size=100%)
                left: '0px',
                'z-index': 1               // keep group below boxes
            });
        }
         /*
           Add group offset to box offset
        */
        top = parseInt(group$.css('top').replace('px','')) +  // group's top +
                    parseInt($(this).css('top').replace('px',''));        // box's top
        left = parseInt(group$.css('left').replace('px','')) +        // group's left +
                    parseInt($(this).css('left').replace('px',''));        // box's left  
        
        $(this).css({
            top: top,
            left: left
        }) 
        
        group$.append($(this));  // move this box into group in DOM
    }
    else {        // clicking a clicked box. Move box out of group  back to body
        $(this).data('clicked', false);    // clear clicked flag
        this.style.opacity = '1.0';        // bring back full color
        $(this).draggable('enable');        // let box be draggable again on its own
        /*
           Add group offset to box offset
        */
        top = parseInt(group$.css('top').replace('px','')) +  // group's top +
                    parseInt($(this).css('top').replace('px',''));        // box's top
      ...