Alright, I'm trying to make some progress:
This is the issue at hand:
Take a look at 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>
<!-- 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 -->
My goal here is:
- By CLICKING and DRAGGING the outer wrapper, everything inside including the avatar should move. (this part is functioning without issue)
- Just a "CLICK" on the image within the PARENT OUTER WRAPPER should trigger a modal to open. (working fine as well)
- Simply CLICKING on the MIC or SPEAKER icons should toggle them between enabled/disabled states. (also working smoothly)
- MAKE ALL OF THESE FUNCTIONS WORK SMOOTHLY WITHOUT INTERFERING WITH EACH OTHER!
The Challenge:
I need to maintain separation between the CLICK, DRAGSTART, DRAGDROP, DRAGEND events so that when clicking and dragging, the MODAL does NOT open... this is where I'm encountering difficulty.
Here's an overview of my .ts code:
NOTE: Utilizing the cool features of ngDraggable.
...
Definition of variables:
public avatarBUBBLE: HTMLElement; //OUTER MOST PARENT DIV
public debugCONSOLE: HTMLElement; //DEBUG CONSOLE
public micICON: HTMLElement; //MICROPHONE ICON
public spkrICON: HTMLElement; //SPEAKER ICON
...
Locating 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;
}
...
The event handlers:
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) Initially posed question: How to keep two divs close together if you move one or the other which seems close to being resolved through: http://jsfiddle.net/2EqA3/3/
b) Derived from elements in this query: D3 Differentiate between click and drag for an element which has a drag behavior