Frage

I know there are a lot of similar questions on here, but, when putting them to action, I still resolve in the same problem.

I have 2 angular directives (drag and drop) and one angular factory (dndAPI). This is all based off of fisshy's Angular Drag and Drop on github.

I finally got firefox to accept and drag movement by adding data to the event, however I can't seem to keep it from doing it's default behavior (and loading that data as a url). I also apologize I couldn't get it to work at all on jsfiddle...at all. I'll try again if someone can't see if I'm doing something outrageously wrong.

angular.module('dragAndDrop', [])
.directive('drag',function (dndApi) {

    var drags = [],
        dragging = new RegExp('(\\s|^)dragging(\\s|$)');

    return {
        restrict: 'A',
        scope: {
            item: '=drag',
            whenStart: '&',
            whenEnd: '&',
            dropzones: '='
        },
        link: function (scope, elem, attr, ctrl) {

            elem.bind('dragstart', function (e) {
                angular.element('query-tool-tip').removeClass('active');
                //if ( drags.length === 0 ) {
                drags = document.querySelectorAll('.drop');
                //}

                angular.forEach(drags, function (value, key) {
                    if (scope.dropzones.indexOf(value.getAttribute('drop')) >= 0) {
                        value.className = value.className + ' dragging';
                    }
                });

                elem.addClass('dragging');

                dndApi.setData(scope.item, scope.dropzones);

                e.originalEvent.dataTransfer.effectAllowed = 'move';

                //KEEPS FIREFOX FROM CRAPPING OUT:
                e.originalEvent.dataTransfer.setData( 'text/plain', 'stop' );

                scope.$apply(function () {
                    scope.whenStart({ data: dndApi.getData() });
                });

            });

            elem.bind('dragleave', function(e){});

            elem.bind('dragend', function (e) {

                elem.removeClass('dragging');

                angular.forEach(drags, function (value, key) {
                    value.className = value.className.replace(dragging, '');
                });

                scope.$apply(function () {
                    scope.whenEnd({ data: dndApi.getData() });
                });

                dndApi.removeData();

                e.preventDefault();

            });

            elem[0].draggable = true;

            elem[0].className = elem[0].className + ' drag';

        }
    };
}).directive('drop',function (dndApi) {

    var drags = [],
        dragging = new RegExp('(\\s|^)dragging(\\s|$)');

    return {
        scope: {
            drop: '=drop',
            whenDrop: '&',
            whenEnter: '&',
            whenLeave: '&',
            queryIndex: "=queryIndex",
            hideElem: '='
        },
        link: function (scope, elem, attr, ctrl) {

            var left = elem[0].offsetLeft,
                right = left + elem[0].offsetWidth,
                top = elem[0].offsetTop,
                bottom = top + elem[0].offsetHeight;

            elem.bind('drop', function (e) {

               // e.originalEvent.preventDefault();


                //if (e.stopPropagation()) {
               // e.stopPropagation();
                //e.originalEvent.stopPropagation();
                    //e.preventDefault();
                //e.originalEvent.preventDefault();
                //}

                e.originalEvent.dataTransfer.clearData();

                if (dndApi.getDropZones().indexOf(scope.drop) >= 0) {
                    scope.$apply(function () {
                        scope.whenDrop({ data: dndApi.getData(), queryI: scope.queryIndex });
                    });
                }

                if (drags.length === 0) {
                    drags = document.querySelectorAll('.drop');
                }

                angular.forEach(drags, function (value, key) {

                    value.className = value.className.replace(dragging, '');

                });

                dndApi.removeData();

                e.stopPropagation();
                e.originalEvent.stopPropagation();
                e.preventDefault();
                e.originalEvent.preventDefault();

            });

            elem.bind('dragenter', function (e) {
                e.preventDefault();
                e.originalEvent.preventDefault();

                if (elem[0] == e.target) {
                    scope.$apply(function () {
                        scope.whenEnter({ data: dndApi.getData() });
                    });
                }


                return false;

            });

            elem.bind('dragleave', function (e) {
                e.preventDefault();
                e.originalEvent.preventDefault();


                if ((e.x < left || e.x > right) ||
                    (e.y < top || e.y > bottom)) {
                    scope.$apply(function () {
                        scope.whenLeave({ data: dndApi.getData() });
                    });
                }

                return false;
            });

            elem.bind('dragover', function (e) {

                //if (e.preventDefault) {
                    e.preventDefault();
                e.originalEvent.preventDefault();
                //}

                return false;

            });

            elem[0].className = elem[0].className + ' drop';
            scope.$watch('hideElem', function () {
                if (scope.hideElem === true) {
                    elem.hide();
                } else {
                    elem.show();
                }
            });

        }
    };
}).factory('dndApi', function () {

    var dnd = {
        dragObject: {},
        dropzones: []
    };

    return {
        setData: function (data, areas) {
            dnd.dragObject = data;
            dnd.dropzones = areas;
        },
        removeData: function () {
            dnd.dragObject = null;
            dnd.dropZones = [];
        },
        getData: function () {
            return dnd.dragObject;
        },
        getDropZones: function () {
            return dnd.dropzones;
        }
    };
});

I've done a lot of what's recommended on other questions. I've added event.preventDefault() to the dragenter and dragleave spots. And then when that didn't work I added them everywhere. I have a feeling it has to do with my drop method. If i put event.prevendDefault() at the beginning of the binding, the rest of my code isn't executed.

Any advice, even if it's something small that I might've overlooked, will be helpful.

Thanks!

War es hilfreich?

Lösung

You are calling e.originalEvent.dataTransfer.clearData(); in the drop event handler which will cause an exception to be thrown (you won't have permission to alter the original dataTransfer object). This is preventing e.originalEvent.preventDefault(); from being called.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top