Search code examples
typescriptonclickdrag-and-dropmousedownmouseup

How to use, dragstart, dragend, click, mouseup, mousedown with three divs together and keep them all separate but equal


OK, I'm spinning my wheels:

My quandary is this:

Here's my HTML:

<!-- PARENT OUTER WRAPPER -->
<div id="avatarmoveable" class="moveablecontainer avatarBubble"
     title="Click on an HOLD to drag avatar"
     (click)="avatarMoveClick($event,'moveavatar')"
     ngDraggable>
  <!-- OUTER WRAPPER -->
  <div class="avatarsays box-opener">
    <!-- DEBUG CONSOLE OUTER WRAPPER -->
    <div class="debugcontainer"
         title="Click to OPEN DEBUG Console or say, 'OPEN DEBUG CONSOLE'."
         *ngIf="isVisible"
         (click)="showHideCSMModal($event, 'debugconsole')">
      <img id="debugavatar" class="avatarimg avatar img-circle" src="../../../assets/images/avatar/avatar_l.svg">
    </div>
    <!-- END DEBUG OUTER WRAPPER -->

    <!-- ICONS OUTER WRAPPER -->
    <div id="iconscont" class="iconscontainer">
      <!-- MICROPHONE ICON -->
      <a class="avataricons talk" href="javascript:;"
         (click)="handleClick($event,'miconoff')"
         (condition)="micon" title="Click the Mic ON or OFF!">
        <i id="mic" [ngClass]="micon ? 'fa fa-microphone iconactive' : 'fa fa-microphone-slash iconactive'"></i>
      </a>
      &nbsp;
      <!-- SPEARKER ICON -->
      <a class="avataricons listen" href="javascript:;"
         (click)="handleClick($event,'spkronoff')"
         (condition)="spkron" title="Click the Speaker ON or OFF!">
        <i id="spkr" [ngClass]="spkron ? 'fa fa-volume-up iconactive' : 'fa fa-volume-off iconactive'"></i>
      </a>
    </div>
    <!-- END ICONS OUTER WRAPPER -->

  </div>
  <!-- END OUTER WRAPPER -->
</div>
<!-- END PARENT OUTER WRAPPER -->

Here's what I'm trying to accomplish:

  1. When you CLICK and DRAG the outer wrapper, the avater and everything inside will drag. (this is working and not an issue)
  2. When you just "CLICK", on the image (inside the PARENT OUTER WRAPPER), a modal pops open (this is working and not an issue)
  3. When you just "CLICK" on the MIC or SPEAKER icons, they disabled/enable (this, too, is working without issue)
  4. MAKE THEM ALL WORK WITHOUT INTERFERING WITH EACH OTHER!

PROBLEM:

I want to keep the CLICK, DRAGSTART, DRAGDROP, DRAGEND separate so when I click and drag, the MODAL will NOT OPEN... which is the problem I'm facing now.

Here's my abridged .ts code:

NOTE: I'm using ngDraggable which is really cool.

...

Variables defined:

public avatarBUBBLE: HTMLElement; //OUTER MOST PARENT DIV
public debugCONSOLE: HTMLElement; //DEBUG CONSOLE
public micICON: HTMLElement; //MICROPHONE ICON
public spkrICON: HTMLElement; //SPEAKER ICON

...

Now, the elements:

ngOnInit() {

    //TYPE ERROR CHECK
    this.**typeErrorCheck**();
    this.avatarBUBBLE = document.querySelector("#avatarmoveable") as HTMLElement;
    this.debugCONSOLE = document.querySelector("#debugavatar") as HTMLElement;
    this.micICON = document.querySelector(".talk") as HTMLElement;
    this.spkrICON = document.querySelector(".listen") as HTMLElement;

}

...

ngAfterViewInit() { 


    this.avatarBUBBLE = document.querySelector("#avatarmoveable") as HTMLElement;
    this.debugCONSOLE = document.querySelector("#debugavatar") as HTMLElement;
    this.micICON = document.querySelector(".talk") as HTMLElement;
    this.spkrICON = document.querySelector(".listen") as HTMLElement;

}

...

My events:

onClick(event: any) {
  event.preventDefault();
  console.log("ON CLICK: ", event);
  if (event) {
    console.log("CLICK: event.target.id: ", event.currentTarget.id);

    return true;
  } else {
    return false;
  }
}

onMouseDown(event: any) {
  event.preventDefault();

  console.log("ON MOUSE Down: ", event);
  if (event) {
    console.log("MOUSEDOWN: event.target.id: ", event.target.id);
    return true;
  } else {
    return false;
  }
}

onMouseUp(event: any) {
  event.preventDefault();

  console.log("ON MOUSE UP: ", event);
  if (event) {
    console.log("MOUSEUP: event.target.id: ", event.target.id);
    return true;
  } else {
    return false;
  }
}

onDragStart(event: any) {
  console.log("ON DRAG START: ", event);
  if (event) {
    console.log("DRAGSTART: event.target.id: ", event.currentTarget.id);
    this.avatarMoveClick(event, 'moveavatar');
    return true;
  } else {
    return false;
  }
}

onDragEnd(event: any) {
  console.log("ON DRAG END: ", event);
  if (event) {
    console.log("DRAGEND: event.target.id: ", event.currentTarget.id);
    this.avatarMoveClick(event, 'moveavatar');
    return true;
  } else {
    return false;
  }
}

onDragDrop(event: any) {
  console.log("ON DRAG END: ", event);
  if (event) {
    console.log("DRAGDROP: event.target.id: ", event.currentTarget.id);
    this.avatarMoveClick(event, 'moveavatar');
    return true;
  } else {
    return false;
  }
}

**typeErrorCheck**() {  //Called in ngOnInit

  this.timer = window.setTimeout(() => {

    this.avatarBUBBLE.addEventListener('dragstart', this.onDragStart.bind(this.avatarBUBBLE));
    this.avatarBUBBLE.addEventListener('dragend', this.onDragEnd.bind(this.avatarBUBBLE));
    this.avatarBUBBLE.addEventListener('dragdrop', this.onDragDrop.bind(this.avatarBUBBLE));

    this.debugCONSOLE.addEventListener('mouseup', this.onMouseUp.bind(this.debugCONSOLE));
    this.micICON.addEventListener('mousedown', this.onMouseDown.bind(this.micICON));
    this.spkrICON.addEventListener('mousedown', this.onMouseDown.bind(this.spkrICON));

  }, 8000);

}

REFERENCES:

a) My original question: How to keep two divs close together if you move one or the other which I believe I'm nearly answered with this: http://jsfiddle.net/2EqA3/3/

b) Using elements of this question: D3 Differentiate between click and drag for an element which has a drag behavior


Solution

  • I was able to use ngDraggable's features to get the info I wanted then change the translate(x,y) quite easily.

    1. Where I have placed ngDraggable, add this in the draggable element on the HTML

       (click)="draggable = !draggable"
       (started)="onStart($event)"
       (stopped)="onStop($event)"
       (movingOffset)="onMoving($event,'chatbot')"
       (endOffset)="onMoveEnd($event,'chatbot')"
       [preventDefaultEvent]="true"
       [style.transform]="!transformXY ? css.moveableWrapper.transform.org : css.moveableWrapper.transform.new"
      
    2. And here's the .ts file

      private calcChatBotPos(trans: string) {
      
      console.log("TRANSFORM: " + trans);
      
      let re = /[^0-9\-.,]/g;
      let matrix = trans.replace(re, '').split(',');
      let x = matrix[0];
      let y = matrix[1];
      
      console.log("xTrans: " + x + "px");
      console.log("yTrans: " + y + "px");
      
      //The xy distant is 15, 10 respectively
      
        if (this.xposEndAvatarOffset !== '' && this.yposEndAvatarOffset !== '') {
        //Set to FALSE
        this.transformXY = false;
        this.css.moveableWrapper.transform.newxy = "translate(" + x + "px" + ", " + y + "px)";
        console.log("Inside IF...." + "translate(" + x + "px" + ", " + y + "px)");
        //Set the CHATBOT to it's NEW position
        this.theMoveable1.style.transform = this.css.moveableWrapper.transform.newxy;
        } else {
        //reset to TRUE
        this.transformXY = true;
        this.css.moveableWrapper.transform.orgxy = "translate(0px, 0px)";
        console.log("Inside ELSE...." + this.css.moveableWrapper.transform.orgxy);
        //Set the CHATBOT to it's ORG position
        this.theMoveable1.style.transform = this.css.moveableWrapper.transform.orgxy;
      }
      

      }

    3. Here's the link to ngDraggable. Click on the HTML to see where I got the options: https://xieziyu.github.io/angular2-draggable/#/draggable/usage/options

    4. Here's the code for getting the events from ngDraggable

      //ngDraggable stuff
      onStart(event) {
        console.log('started output:', event);
      }
      
      onStop(event) {
        console.log('stopped output:', event);
      }
      
      onMoving(event, fromwhere) {
      
      if (fromwhere === "chatbot") {
        this.movingOffset.x = event.x;
        this.movingOffset.y = event.y;
        this.xposChatbot = this.movingOffset.x;
        this.yposChatbot = this.movingOffset.y;
      
        console.log("CHATBOT movingoffset x and y: " + this.xposChatbot + " : " + this.yposChatbot);
      }
      if (fromwhere === "avatar") {
        this.movingOffset.x = event.x;
        this.movingOffset.y = event.y;
        this.xposAvatar = this.movingOffset.x;
        this.yposAvatar = this.movingOffset.y;
      
        console.log("AVATAR movingoffset x and y: " + this.xposAvatar + " : " + this.xposAvatar);
        }
      
      }
      
      onMoveEnd(event, fromwhere) {
      
      if (fromwhere === "chatbot") {
      
        this.endOffset.x = event.x;
        this.endOffset.y = event.y;
        this.xposEndChatOffset = this.endOffset.x;
        this.yposEndChatOffset = this.endOffset.y;
      
        console.log("CHATBOT endoffset x and y: " + this.xposEndChatOffset + " : " + this.yposEndChatOffset);
      
        }
        if (fromwhere === "avatar") {
      
        this.endOffset.x = event.x;
        this.endOffset.y = event.y;
        this.xposEndAvatarOffset = this.endOffset.x;
        this.yposEndAvatarOffset = this.endOffset.y;
      
        console.log("AVATAR endoffset x and y: " + this.xposEndAvatarOffset + " : " + this.yposEndAvatarOffset);
        this.avatarMoveClick(event, fromwhere);
        }
      
      }
      
    5. I also solved my issues with moving the chat window when the avatar is moved but the code snippet above.

    It's simple, once I the light went off in my head.