Error thrown by custom draggable directive in AngularJS due to range issue

I am having trouble with a custom draggable directive in AngularJS. I keep getting a RangeError. Can someone please help me diagnose the issue in this code?

(function (window, angular, undefined) {

    var app = angular.module('ngDraggableModule', []);

    app.directive('easyDrag', ['$document', function ($document) {
        return {
            restrict: 'EA',
            scope: {
                params: '=',
                elemId: '='
            },
            link: function (scope, elem, attrs) {
                var isMouseDown = false,
                    startDrag = false,
                    position = {},
                    x = 0,
                    y = 0,
                    startX = 0,
                    startY = 0,
                    changedPos = 0;

                elem.bind('mousedown', onMouseDown);

                function onMouseDown(e) {
                    if (angular.isDefined(scope.params.disabled) && scope.params.disabled === true) {
                        return false;
                    }
                    isMouseDown = true;
                    startX = e.screenX - x;
                    startY = e.screenY - y;
                    $document.bind('mousemove', onMouseMove);
                    $document.bind('mouseup', onMouseUp);
                }

                function onMouseMove(e) {
                    if (isMouseDown) {
                        if (!startDrag) {
                            startDrag = true;
                            if (angular.isFunction(scope.params.start)) {
                                scope.params.start(changedPos, e, scope.elemId);
                            }
                        }
                        y = e.screenY - startY;
                        x = e.screenX - startX;
                        position = {};
                        if (angular.isDefined(scope.params.axis)) {
                            if (scope.params.axis.toLowerCase() == 'x') {
                                position.marginLeft = x + 'px';
                            }
                            else if (scope.params.axis.toLowerCase() == 'y') {
                                position.marginTop = y + 'px';
                            }
                        } else {
                            position.marginTop = y + 'px';
                            position.marginLeft = x + 'px';
                        }
                        changedPos = position;
                        elem.css(position);
                        if (angular.isFunction(scope.params.drag)) {
                            scope.params.drag(e, changedPos, scope.elemId);
                        }
                    }
                }

                function onMouseUp(e) {
                    if (!isMouseDown) {
                        return false;
                    }
                    isMouseDown = false;
                    startDrag = false;
                    if (angular.isFunction(scope.params.stop)) {
                        scope.params.stop(changedPos, e, scope.elemId);
                    }
                }

            }
        }
    }]);
})(window, window.angular, undefined);

var app = angular.module('DemoApp',['ngDraggableModule']);

app.controller('MainCtrl',['$scope',function($scope){
  $scope.assetDragParams = {
    drag : function(e,pos,id){
      console.log(id); // here is the error
    }
  }
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="MainCtrl">
 <div easy-drag params="assetDragParams" elem-id="col._id">
    drag it
 </div>
</div>

When I use this directive, I keep getting a RangeError: Maximum call stack size exceeded. Can someone please help me figure out what's causing this error? Thank you in advance.

Answer №1

To ensure proper functionality, it is crucial to bind the mousemove and mouseup events outside of the mousedown event. Within the onMouseDown function, the variable isMouseDown is set to true. The correct way to bind the functions is as follows:

elem.bind('mousedown', onMouseDown);
$document.bind('mousemove', onMouseMove);
$document.bind('mouseup', onMouseUp);

The onMouseDown function should be implemented like this:

function onMouseDown(e) {
    if (angular.isDefined(scope.params.disabled) && scope.params.disabled === true) {
        return false;
    }
    isMouseDown = true;
    startX = e.screenX - x;
    startY = e.screenY - y;
}

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

How can I incorporate a feature in my Angular application that allows users to switch between different view types, such as days, using JavaScript

Greetings, community! I am currently utilizing version 5 of the fullcalendar library from https://fullcalendar.io/ in my Angular 9 application. I have noticed that the calendar offers various options to change the view type as shown below: https://i.stac ...

Inadequate text alignment

Trying to create a header mockup for a website featuring branding elements like a logo and brand name. Utilizing Angular.js for the webpage development process, incorporating a URL for the logo image from an online source. Encountering alignment issues th ...

Is Angular's ngOnChanges failing to detect any changes?

Within one component, I have a dropdown list. Whenever the value of the dropdown changes, I am attempting to detect this change in value in another component. However, I am encountering an unusual issue. Sometimes, changing the dropdown value triggers the ...

I've come across certain challenges when setting values for Vue data objects

I'm having trouble with a Vue assignment. Here is my code: new Vue({ el: "#alarmEchartBar", data: { regusterUrl: Ohttp + "historicalAlarmRecord/chart", regDistrictUrl: Ohttp + "district", regStreetUrl: Ohttp + "street/", regCameraUrl: ...

Vue.js displaying the error message: "The maximum size of the call stack has been exceeded"

Could you assist me in resolving this issue? router.js routes: [{ path: "", component: () => import("@/layouts/full-page/FullPage.vue"), children: [{ path: "/pages/login", name: "page-login", component: () => import("@/views/pages ...

What is the best way to hear an event emitted by a component?

I am trying to listen for an event in Chrome DevTools Vue, but I'm not sure how to target it. For a Root event, I typically use: this.$root.$on("note_id", (note_id) => (this.note_id = note_id)); But how do I address an event that origina ...

Encountered a deployment issue when trying to deploy an HTML application on Heroku due

After uploading an html application on GitHub, I encountered an error while attempting to deploy it on Heroku: No default language could be detected for this app. HINT: This happens when Heroku is unable to automatically determine the buildpack to use f ...

Having trouble converting JSON object to regular object?

I'm trying to change a JSON object into a regular object by using this method... var slaobj = eval('('+s+')'); However, it doesn't appear to be working correctly (the `.length' is returning as undefined). What m ...

Discover siblings in React component siblings

Creating a parent element (Board) that generates a list of children and provides a method to access this list can be done like so: export default class Board extends React.Component { constructor(props) { super(props); this.getList = t ...

Is there a way to set up an automatic pop-up for this?

Experience this code function AutoPopup() { setTimeout(function () { document.getElementById('ac-wrapper').style.display = "block"; }, 5000); } #ac-wrapper { position: fixed; top: 0; left: 0; width: 100%; height: 100%; back ...

Adding JavaScript files to a project in Ionic2 with Angular2 integration

I'm looking to incorporate jQuery into my Ionic2 app, which requires loading several JavaScript files: <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script type="text/j ...

AJAX Object Creation: Only Visible After Manual Refresh

Currently, I am in the process of building a basic to-do app that includes multiple different lists, each of which contains a variety of items. My main objective is to integrate AJAX functionality into the creation and display of lists on the lists#index p ...

leveraging parcel for importing typescript dependencies

I am currently using parcel to process typescript for a web extension. I have installed JQuery and its type definitions via npm. In my typescript file, I have the following at the top: import $ from "jquery"; import "bootstrap"; However, when running run ...

Disappearance of background image on HTML5 canvas upon mouse movement

I am looking to incorporate the ability for users to draw sketches on an image displayed on a canvas. Currently, I am utilizing the sketch.js jQuery library and have encountered the following issues: The image loads successfully onto the canvas. However, ...

Making AJAX requests to retrieve data from a JSON database array, then utilizing the CSS visibility property to conceal HTML elements dynamically

As a enthusiastic beginner, I'm facing a challenge that seems to have no easy solution. Can someone please assist me with this: How can I assign all the ids from a JSON database to the variable dotContainer, in order to hide all corresponding HTML id ...

When the properties change, React Router Redux does not get rendered

I am encountering a challenge with using react router redux, where everything seems to be working well except for rendering when props change. Index.js import React from 'react'; import ReactDOM from 'react-dom'; import {Provider} fro ...

What causes axios to return a z_buf_error?

I've encountered an issue with axios returning an error cause: Error: unexpected end of file at BrotliDecoder.zlibOnError [as onerror] (node:zlib:189:17) { errno: -5, code: 'Z_BUF_ERROR' I'm puzzled as to why this functio ...

Tips for achieving printing with the "Fit sheet on one page" option in JavaScript

Is there a way to print a large table of data with 200 or 300 rows all on one page, similar to the Online MS Excel print option 'Fit Sheet on One Page'? I attempted the code below: var tble = document.createElement("table"); tble.id = "tble"; d ...

Do we really need to invest time in understanding views and template engines in Express, if we have already mastered Angular within the MEAN Stack?

My journey with the MEAN Stack began by learning Angular through the official website (angular.io). Currently, I am delving into node.js and express.js. I have a question regarding the use of Angular for the front end in the MEAN Stack. If Angular is hand ...

Using Vue.js to pass a variable from a parent component to a child component

Parent component: ShowComment Child component: EditComment I'm attempting to pass the value stored in this.CommentRecID to the child component. In the template of ShowComment, I have included: <EditComment CommentRecID="this.CommentRecID" v-if= ...