Tips for effectively utilizing dragstart, dragend, click, mouseup, and mousedown events simultaneously with three separate div elements, ensuring each maintains its distinctiveness and equality

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>
      &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 -->

My goal here is:

  1. By CLICKING and DRAGGING the outer wrapper, everything inside including the avatar should move. (this part is functioning without issue)
  2. Just a "CLICK" on the image within the PARENT OUTER WRAPPER should trigger a modal to open. (working fine as well)
  3. Simply CLICKING on the MIC or SPEAKER icons should toggle them between enabled/disabled states. (also working smoothly)
  4. 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

Answer №1

Utilizing the features of ngDraggable allowed me to easily retrieve the desired information and manipulate the translate(x,y) function.

  1. To implement ngDraggable, insert the following code into the draggable element in 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. Also included is the .ts file section

    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 distance is 15, 10 respectively
    ...
    

    }

  3. Refer to ngDraggable documentation for more options and information:

  4. The necessary code for handling events from ngDraggable:

    //ngDraggable stuff
    onStart(event) {
      console.log('started output:', event);
    }
    ...
    
  5. By implementing the provided code snippet, I successfully addressed the challenge of moving the chat window when the avatar is moved.

Understanding struck like a lightbulb moment once I delved into the solution.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

TypeScript does not automatically deduce types

Here is a function I am working with: type DefaultEntity = { id: string; createdBy: string; [fieldName: string]: unknown; }; abstract find<T, Schema extends string | (new () => T)>( schema: Schema, id: string, ): Promise<(Schema ...

How do I verify if a boolean variable has been changed within an Angular service?

In my MatHorizontalStepper parent component, I utilize the subscribe function to monitor changes in an Observable within a service. The purpose is to automatically progress to the next step in the stepper when the observable switches from false to true. D ...

Access PDF document in a fresh tab

How can I open a PDF file in a new tab using Angular 6? I have tried the following implementation: Rest controller: @RestController @RequestMapping("/downloads") public class DownloadsController { private static final String EXTERNAL_FILE_PATH = "/U ...

Utilizing Azure Function Model v4: Establishing a Connection with Express.js

Using Model v4 in my Azure function index.ts import { app } from "@azure/functions"; import azureFunctionHandler from "azure-aws-serverless-express"; import expressApp from "../../app"; app.http("httpTrigger1", { methods: ["GET"], route: "api/{*segme ...

How can we use tsyringe (a dependency injection library) to resolve classes with dependencies?

I seem to be struggling with understanding how TSyringe handles classes with dependencies. To illustrate my issue, I have created a simple example. In my index.tsx file, following the documentation, I import reflect-metadata. When injecting a singleton cl ...

Angular: Updating image tag to display asynchronous data

Utilizing Angular to retrieve user profile pictures from the backend, specifically Node.js/Express, has been mostly successful. However, there is one issue that I have encountered. The HTML displaying the profile picture does not re-render when the user up ...

An issue was encountered in the node_modules folder while attempting to access the 'Exclude' name in the lodash collection file. The error message reads: (1783,24): error TS2304: Cannot

When attempting to execute the ng serve command, I encountered an error. See below for more details. ERROR in node_modules/@types/lodash/common/collection.d.ts(1783,24): error TS2304: Cannot find name 'Exclude'. ... (error list continued) .. ...

Trigger event when the useRef element's height surpasses zero

I have a large list of photo thumbnails, and I need to ensure that one of the thumbnails scrolls into view when the list is loaded. The photos are generated using the map function, and the container div of one of the thumbnails will be assigned a ref. I ...

Resolving Node.js Absolute Module Paths with TypeScript

Currently, I am facing an issue where the modules need to be resolved based on the baseUrl so that the output code is compatible with node.js. Here is my file path: src/server/index.ts import express = require('express'); import {port, database ...

Creation of Card Component with React Material-UI

I am facing difficulties in setting up the design for the card below. The media content is not loading and I cannot see any image on the card. Unfortunately, I am unable to share the original image due to company policies, so I have used a dummy image for ...

Tips on executing an asynchronous operation before exiting

I have been attempting to execute an asynchronous operation before my process ends. By 'ends', I mean in every instance of termination: ctrl+c Uncaught exception Crashes End of code Anything.. As far as I know, the exit event handles this for ...

registering a back button action in Ionic2 for multiple pages

Currently, I am in the process of developing my Ionic2 app and have encountered a dilemma regarding the functionality of registerBackButtonAction. On one page, let's call it pageA, I have implemented this function and everything is functioning as exp ...

Limiting querySelector to a specific React component: a step-by-step guide

Is there a way to target a specific DOM element within a React component to change its color using the ComponentDidMount method? Parent component export class ListComponent extends Component<...> { render(): ReactNode { return ( ...

React TypeScript Context - problem with iterating through object

Can someone please help me with an error I am encountering while trying to map an object in my code? I have been stuck on this problem for hours and despite my efforts, I cannot figure out what is causing the issue. Error: const categoriesMap: { item: ...

How to selectively disable options in p-dropdown using Angular Reactive Forms

Implementing PrimeNg p-dropdown in a component. <p-dropdown [options]="productRequest" formControlName="request" optionLabel="ProductName" (onChange)="someFunction('request')"> </p-dropdown> ...

Is there a way to pass around jest mocks across numerous tests?

In my test scenarios, I've created a mock version of the aws-sdk, which is functioning perfectly: jest.mock("aws-sdk", () => { return { Credentials: jest.fn().mockImplementation(() => ({})), Config: jest.fn().mockImplementati ...

Angular2 (RC5) global variables across the application

I am seeking a solution to create a global variable that can be accessed across different Angular2 components and modules. I initially considered utilizing dependency injection in my `app.module` by setting a class with a property, but with the recent angu ...

Discovering the Solution: Angular 17's Answer to Troubleshooting Peer Dependency Conflicts

After upgrading Angular to version 17 using npm --force, my application was running smoothly in a local environment. However, when attempting to deploy it (via octopus deploy), the npm install process was automatically triggered by .Net, resulting in a lis ...

Error: The 'itemsNav' property is not part of the '{}' type. (Code: 2339)

I'm struggling to figure out the issue with itemsNav. <script setup lang="ts"> import { ref } from 'vue' import { list } from '../../constants/NAV'; const itemsNav = ref(list) </script> < ...

Maintain the nullability of object fields when casting

I have been working on a type called DateToNumber that converts all the Date properties of an object to number. Here is what I have come up with so far: type LiteralDateToNumber<T> = T extends Date ? number : T extends Date | null ? number | nu ...