0

I tried many things but none of them are working. Hence, posting the same.

Here is the background:

I have this HTML element which will create a rectangular box based on ng-repeat dynamically. Within each of this Rectangular box there are various HTML elements such as HTML select and input text etc and these fields can be edited by the user. I want to make this rectangular box draggable so the user can move it around.

Hence, I have written an angularjs directive to do it and its working fine But if I add the directive then the select field and all the fields within the rectangular box are no more editable as it applies the draggable directive to the whole rectangular. If I remove this directive then it would work fine. How can I make the rectangular box draggable, as well as fields within it, are selectable or editable?

HTML CODE:

<div ng-repeat="NewField in NewFieldValues">
    <div style="width:250px;height:120px;border:1px solid #000;" draggable draggable="true">
        <select ng-model="Dynamic.BusinessStep[NewField.ID]" ng-change="BusinessStepChange(NewField.ID,'BusinessStep')" class="form-control">
            <option class="dropdown-item" value="" selected> Choose Business Step</option>
            <option class="dropdown-item" ng-repeat="businessStep in businessSteps" value="{{ businessStep.value }}"> {{ businessStep.text }} </option>
        </select>
        <br/>
        <input type="text" ng-model="Dynamic.ObjectCount[NewField.ID]" ng-blur="BusinessStepChange(NewField.ID,'EventCount')" placeholder="number of objects" class="form-control"></input>
    </div>
    <br/>
</div>

Angularjs Directive:

app.directive('draggable', function($document) {
    return function(scope, element, attr) {
        var startX = 0, startY = 0, x = 0, y = 0;
        
        element.css({
            position: 'relative',
            border: '1px solid red',
            backgroundColor: 'lightgrey',
            cursor: 'pointer',
            display: 'block'
        });
        
        element.on('mousedown', function(event) {
            console.log("MOUSE DOWN");
            // Prevent default dragging of selected content
            event.preventDefault();
            startX = event.screenX - x;
            startY = event.screenY - y;
            $document.on('mousemove', mousemove);
            $document.on('mouseup', mouseup);
            return true;
        });

        function mousemove(event) {
            console.log("MOUSE MOVE");
            y = event.screenY - startY;
            x = event.screenX - startX;
            element.css({
              top   : y + 'px',
              left  : x + 'px'
            });
            return true;
        }

        function mouseup() {
            $document.off('mousemove', mousemove);
            $document.off('mouseup', mouseup);
            return true;
        }
    };
});

A Glimpse of what I am trying to achieve

I tried to change a few things but none of them are working. As I trying to add the draggable to the rectangular box the fields within that by default get the draggable directive and hence their default behavior is overridden by the angularjs directive. I would appreciate it if someone can provide me some guidance here.

BATMAN_2008
  • 2,788
  • 3
  • 31
  • 98
  • I tried some more things but none of them are working. By default when I click on the `rectangular box` it comes `draggable` due to which I am unable to select the fields within it. Is there any other better method that I can use to make this thing work. The `rectangular box` should be `draggable` as well as the fields within it should be `editable.` – BATMAN_2008 Jul 22 '20 at 11:27
  • Have you tried `$event.stopPropagation();`? That should prevent the event from bubbling up from the input to the draggable component. If that works, I'll provide this as an answer. – Dane Brouwer Jul 23 '20 at 07:05
  • @DaneBrouwer Thanks for the response. No I have not tried this one. But I tried it now. It seems to be working. Thanks a lot. Please add the answer. I will accept it. Also, I have one small doubt let me know if you can help me. I need some sort of mechanism to `connect` these rectangular boxes. For example, using the `Arrow` buttons. User can choose the arrow button and they can connect the `rectangular box` as per their need. Any idea what I can use to achieve this? – BATMAN_2008 Jul 23 '20 at 07:28
  • I would highly suggest searching through SO and possibly opening a separate question. It sounds like you may need to look at canvases or svg arrows. – Dane Brouwer Jul 23 '20 at 08:19

1 Answers1

1

The issue you're facing is called Event-Bubbling. The click event is bubbling up to the container rectangle triggering the drag event.

The solution is simply to implement $event.stopPropagation();, what this does is prevent the related $event from bubbling up and triggering other similar events.

Dane Brouwer
  • 2,827
  • 1
  • 22
  • 30