0

Trying to create a drag n drop implementation from an Rxjs course example, but its not working correctly. Some time the box is dragged back to original position some times it just get stuck. Here is the plunkr https://plnkr.co/edit/9Nqx5qiLVwsOV7zU6Diw?p=preview

the js code:

var $drag = $('#drag');
var $document = $(document);
var $dropAreas = $('.drop-area');

var beginDrag$ = Rx.Observable.fromEvent($drag, 'mousedown');
var endDrag$ = Rx.Observable.fromEvent($document, 'mouseup');
var mouseMove$ = Rx.Observable.fromEvent($document, 'mousemove');

var currentOverArea$ = Rx.Observable.merge(
  Rx.Observable.fromEvent($dropAreas, 'mouseover').map(e => $(e.target)),
  Rx.Observable.fromEvent($dropAreas, 'mouseout').map(e => null)
);

var drops$ = beginDrag$
  .do(e => {
    e.preventDefault();
    $drag.addClass('dragging');
  })
  .mergeMap(startEvent => {
    return mouseMove$
      .takeUntil(endDrag$)
      .do(moveEvent => moveDrag(startEvent, moveEvent))
      .last()
      .withLatestFrom(currentOverArea$, (_, $area) => $area);
  })
  .do(() => {
    $drag.removeClass('dragging')
      .animate({top: 0, left: 0}, 250);
  })
  .subscribe( $dropArea => {
    $dropAreas.removeClass('dropped');

    if($dropArea) $dropArea.addClass('dropped');
  });

  function moveDrag(startEvent, moveEvent) {
    $drag.css(
      {left: moveEvent.clientX - startEvent.offsetX,
       top: moveEvent.clientY - startEvent.offsetY}
    );
  }

If I remove the withLatestFrom operator, then dragging of div always work fine, but without this I cannot get the drop feature implemented.

coure2011
  • 40,286
  • 83
  • 216
  • 349

1 Answers1

0

Problem one: Some time the box is dragged back to original position some times it just get stuck. Answer: you should replace order of chain, ".do" before ".withLatestFrom" like this:

const drops$ = beginDrag$
.do( e => {
  e.preventDefault();
  $drag.addClass('dragging');
})
.mergeMap(startEvent => {
  return mouseMove$
  .takeUntil(endDrag$)
  .do(mouseEvent => {
    moveDrag(startEvent, mouseEvent);
  })
  .last()
  .do((x) => {
    console.log("hey from last event",x);
    $drag.removeClass('dragging')
    .stop()
    .animate({ top:0, left: 0}, 250);
  }
  )
  .withLatestFrom(currentOverArea$, (_, $area) => {
    console.log('area',$area);
    return $area;
  });

Problem two: drop and drag outside not working correctly. Answer: because of mouse event causing by "pointer-events" is not clearly. In Css File, at:

    .dragable .dragging {
            background: #555;
            pointer-events: none;
        }

This is not Enough, the "mouseout" (or "mouseleave") still working, so when you drag box and drop. it happening the same time event "mouseover" and "mouseout". So the drag area never change color. What to do ?: make it better by clear every mouse event from the target element. In this case, it is div#drag.dragable.dragging. Add only this to CSS and problem is solve.

    div#drag.dragable.dragging {
            pointer-events: none;
        }

(Holly shit, it take me 8 hours to resolve this. Readmore or see Repo at: Repository )

Hiep Tran
  • 3,735
  • 1
  • 21
  • 29