Reputation: 31
my first post on SO!
In short, I'm researching Dart drag & drop libraries for use in an AngularDart project. I have created an example repo (https://bitbucket.org/johnryanancoa/componentdecorator/src/). The tag produces the desired markup, onto which a decorator attaches the relevant events. The Drag events are correctly printing a message to the console when an event fires. However, the Drop events are not firing.
Can anyone shed any light on this please? I'm thinking I'm making mistakes with my use of Futures although would appreciate any pointers.
Thank you in advance. John
UPDATE: adding relevant code snippets from the above repo as per @slawson's suggestion
== main.html ==
<body>
<my-component class="my-component" my-decorator></my-component>
...
</body>
== main.dart ==
import 'package:logging/logging.dart';
import 'package:angular/angular.dart';
import 'package:angular/application_factory.dart';
import 'package:componentDecorator/component/component.dart';
import 'package:componentDecorator/component/decorator.dart';
String _delimiter = "-";
class MyMod extends Module {
final Logger log = new Logger('componentDecorator');
MyMod() {
bind(MyCoolDecorator);
bind(MyCoolComponent);
}
}
void main() {
Logger.root.level = Level.ALL;
Logger.root.onRecord.listen((LogRecord rec) {
print('[${rec.level.name}: ${rec.loggerName}] ${_delimiter} ${rec.message}');
});
applicationFactory()
.addModule(new MyMod())
.run();
}
== component.dart ==
library mycomponent;
import 'dart:core';
import 'dart:html';
import 'package:angular/angular.dart';
import 'package:logging/logging.dart';
@Component(
selector: 'my-component',
templateUrl: 'packages/componentDecorator/component/component.html',
cssUrl: 'packages/componentDecorator/component/component.css',
publishAs: 'comp'
) class MyCoolComponent {
MyCoolComponent(final Element element) {
Logger.root.fine("MyCoolComponent(): element = $element, element.attributes = ${element.attributes.keys}");
}
}
== component.html ==
<ul dnd dnd-dropzone>
<li dnd dnd-draggable>one</li>
<li dnd dnd-draggable>three</li>
<li dnd dnd-draggable>five</li>
</ul>
<ul dnd dnd-dropzone class="even">
<li dnd dnd-draggable>two</li>
<li dnd dnd-draggable>four</li>
<li dnd dnd-draggable>six</li>
</ul>
== decorator.dart ==
library mydecorator;
import 'dart:core';
import 'dart:html';
import 'dart:async';
import 'package:angular/angular.dart';
import 'package:componentDecorator/dnd/dnd.dart';
@Decorator(
selector: '[my-decorator]'
) class MyCoolDecorator extends AttachAware {
final Element element;
MyCoolDecorator(this.element);
void attach() {
new Future(() {
var _el;
if (element.shadowRoot != null) {
_el = element.shadowRoot;
} else {
_el = element;
}
// common
print("${_el.hashCode} el: ${_el}");
print("${_el.hashCode} el.draggable: ${_el.querySelectorAll('[dnd-draggable]').length}");
Draggable draggable = new Draggable(_el.querySelectorAll('[dnd-draggable]'), avatarHandler: new AvatarHandler.clone())
..onDragStart.listen(onDragStart)
..onDragEnd.listen(onDragEnd)
;
print("${_el.hashCode} draggable: ${draggable}");
print("${_el.hashCode} el.dropzones: ${_el.querySelectorAll('[dnd-dropzone]').length}");
Dropzone dropzones = new Dropzone(_el.querySelectorAll('[dnd-dropzone]'), acceptor: new Acceptor.draggables([draggable]))
..onDragEnter.listen(onDragEnter)
..onDragLeave.listen(onDragLeave)
..onDragOver.listen(onDragOver)
..onDrop.listen(onDrop)
;
print("${_el.hashCode} dropzones: ${dropzones}");
});
}
Element getElement() {
var _el;
if (element.shadowRoot != null) {
_el = element.shadowRoot;
} else {
_el = element;
}
// common
print("${_el.hashCode} el: ${_el}");
print("${_el.hashCode} el.dropzones: ${_el.querySelectorAll('[dnd-dropzone]').length}");
print("${_el.hashCode} el.draggable: ${_el.querySelectorAll('[dnd-draggable]').length}");
return _el;
}
void onDragEnter(DropzoneEvent event) {
print("onDragEnter()");
}
void onDragStart(DraggableEvent event) {
print("onDragStart()");
}
void onDragEnd(DraggableEvent event) {
print("onDragEnd()");
}
void onDragOver(DropzoneEvent event) {
print("onDragOver()");
}
void onDrop(DropzoneEvent event) {
print("onDrop()");
}
void onDragLeave(DropzoneEvent event) {
print("onDragLeave()");
}
}
Upvotes: 2
Views: 511
Reputation: 3729
You must send an event.preventDefault()
in your onDrag()
handler, or else your drag event will prevent your drop event from firing properly.
import { Component } from "@angular/core";
@Component({
selector: "my-component",
template: `
<div
(dragover)="onDragOver($event)"
(drop)="onDrop($event)"
>
Drop here
</div>
`
});
export class MyComponent {
void onDragOver(event) {
event.preventDefault(); // this allows onDrop() to fire later
print("onDragOver()");
}
void onDrop(event) {
event.preventDefault();
print("onDrop()");
}
}
Upvotes: 0
Reputation: 31
UPDATE!! Modifying the @Component declaration appears to resolve the issue...
Before
@Component(
selector: 'my-component',
templateUrl: 'packages/componentDecorator/component/component.html',
cssUrl: 'packages/componentDecorator/component/component.css',
publishAs: 'comp'
) class MyCoolComponent {
After
@Component(
selector: 'my-component',
templateUrl: 'packages/componentDecorator/component/component.html',
useShadowDom: false,
publishAs: 'comp'
) class MyCoolComponent {
I need to investigate further tomorrow but at least it triggers the events and prints to the console! Thanks for your help nonetheless...
Upvotes: 0
Reputation: 657008
You need to call preventDefault
on some drag-n-drop events (dragover) to indicate you will handle the drop event.
http://www.w3schools.com/html/html5_draganddrop.asp http://www.html5rocks.com/en/tutorials/dnd/basics/
Upvotes: 1