Przeglądaj źródła

dragula plugin and demo

Adam Shaw 7 lat temu
rodzic
commit
6694074ffa

+ 139 - 0
demos/external-dragging-dragula.html

@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../node_modules/dragula/dist/dragula.css' rel='stylesheet' />
+<link href='../dist/fullcalendar.css' rel='stylesheet' />
+<link href='../dist/fullcalendar.print.css' rel='stylesheet' media='print' />
+<script src='../node_modules/moment/moment.js'></script>
+<script src='../node_modules/dragula/dist/dragula.js'></script>
+<script src='../dist/fullcalendar.js'></script>
+<script src='../dist/dragula.js'></script>
+<script>
+
+  document.addEventListener('DOMContentLoaded', function() {
+
+    /* initialize the external events
+    -----------------------------------------------------------------*/
+
+    var containerEl = document.getElementById('external-events-list');
+    var eventEls = Array.prototype.slice.call(
+      containerEl.querySelectorAll('.fc-event')
+    );
+
+    eventEls.forEach(function(eventEl) {
+      eventEl.setAttribute('data-event', JSON.stringify({
+        title: eventEl.innerText.trim(),
+        stick: true
+      }));
+    });
+
+    FullCalendar.dragula({
+      containers: [ containerEl ],
+      copy: true
+    });
+
+    /* initialize the calendar
+    -----------------------------------------------------------------*/
+
+    var calendarEl = document.getElementById('calendar');
+    var calendar = new FullCalendar.Calendar(calendarEl, {
+      header: {
+        left: 'prev,next today',
+        center: 'title',
+        right: 'month,agendaWeek,agendaDay'
+      },
+      editable: true,
+      droppable: true, // this allows things to be dropped onto the calendar
+      drop: function() {
+        // is the "remove after drop" checkbox checked?
+        if (document.getElementById('drop-remove').checked) {
+          // if so, remove the element from the "Draggable Events" list
+          this.parentNode.removeChild(this);
+        }
+      }
+    });
+    calendar.render();
+
+  });
+
+</script>
+<style>
+
+  body {
+    margin-top: 40px;
+    text-align: center;
+    font-size: 14px;
+    font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
+  }
+
+  #wrap {
+    width: 1100px;
+    margin: 0 auto;
+  }
+
+  #external-events {
+    float: left;
+    width: 150px;
+    padding: 0 10px;
+    border: 1px solid #ccc;
+    background: #eee;
+    text-align: left;
+  }
+
+  #external-events h4 {
+    font-size: 16px;
+    margin-top: 0;
+    padding-top: 1em;
+  }
+
+  #external-events .fc-event {
+    margin: 10px 0;
+    cursor: pointer;
+  }
+
+  #external-events p {
+    margin: 1.5em 0;
+    font-size: 11px;
+    color: #666;
+  }
+
+  #external-events p input {
+    margin: 0;
+    vertical-align: middle;
+  }
+
+  #calendar {
+    float: right;
+    width: 900px;
+  }
+
+</style>
+</head>
+<body>
+  <div id='wrap'>
+
+    <div id='external-events'>
+      <h4>Draggable Events</h4>
+
+      <div id='external-events-list'>
+        <div class='fc-event'>My Event 1</div>
+        <div class='fc-event'>My Event 2</div>
+        <div class='fc-event'>My Event 3</div>
+        <div class='fc-event'>My Event 4</div>
+        <div class='fc-event'>My Event 5</div>
+      </div>
+
+      <p>
+        <input type='checkbox' id='drop-remove' />
+        <label for='drop-remove'>remove after drop</label>
+      </p>
+    </div>
+
+    <div id='calendar'></div>
+
+    <div style='clear:both'></div>
+
+  </div>
+</body>
+</html>

+ 2 - 2
demos/external-dragging.html

@@ -19,10 +19,10 @@
     $('#external-events .fc-event').each(function() {
 
       // store data so the calendar knows to render an event upon drop
-      $(this).data('event', {
+      $(this).attr('data-event', JSON.stringify({
         title: $.trim($(this).text()), // use the element's text as the event title
         stick: true // maintain when user navigates (see docs on the renderEvent method)
-      });
+      }));
 
       // make the event draggable using jQuery UI
       $(this).draggable({

+ 49 - 0
package-lock.json

@@ -461,6 +461,12 @@
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
       "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
     },
+    "atoa": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/atoa/-/atoa-1.0.0.tgz",
+      "integrity": "sha1-DMDpGkgOc4+SPrwQNnZHF3mzSkk=",
+      "dev": true
+    },
     "atob": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz",
@@ -1410,6 +1416,16 @@
       "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=",
       "dev": true
     },
+    "contra": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/contra/-/contra-1.9.4.tgz",
+      "integrity": "sha1-9TveQtfltZhcrk2ZqNYQUm3o8o0=",
+      "dev": true,
+      "requires": {
+        "atoa": "1.0.0",
+        "ticky": "1.0.1"
+      }
+    },
     "cookie": {
       "version": "0.3.1",
       "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
@@ -1485,6 +1501,23 @@
         "which": "1.3.0"
       }
     },
+    "crossvent": {
+      "version": "1.5.4",
+      "resolved": "https://registry.npmjs.org/crossvent/-/crossvent-1.5.4.tgz",
+      "integrity": "sha1-2ixPj0DJR4JRe/K+7BBEFIGUq5I=",
+      "dev": true,
+      "requires": {
+        "custom-event": "1.0.0"
+      },
+      "dependencies": {
+        "custom-event": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.0.tgz",
+          "integrity": "sha1-LkYovhncSyFLXAJjDFlx6BFhgGI=",
+          "dev": true
+        }
+      }
+    },
     "cryptiles": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
@@ -1825,6 +1858,16 @@
       "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
       "dev": true
     },
+    "dragula": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmjs.org/dragula/-/dragula-3.7.2.tgz",
+      "integrity": "sha1-SjXJ05gf+sGpScKcpyhQWOhzk84=",
+      "dev": true,
+      "requires": {
+        "contra": "1.9.4",
+        "crossvent": "1.5.4"
+      }
+    },
     "dts-generator": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/dts-generator/-/dts-generator-2.1.0.tgz",
@@ -9930,6 +9973,12 @@
         "xtend": "4.0.1"
       }
     },
+    "ticky": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ticky/-/ticky-1.0.1.tgz",
+      "integrity": "sha1-t8+nHnaPHJAAxJe5FRswlHxQ5G0=",
+      "dev": true
+    },
     "tildify": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz",

+ 1 - 0
package.json

@@ -34,6 +34,7 @@
     "components-jqueryui": "github:components/jqueryui",
     "css-loader": "^0.28.10",
     "del": "^2.2.1",
+    "dragula": "^3.7.2",
     "dts-generator": "^2.1.0",
     "eslint": "^4.18.2",
     "eslint-config-standard": "^11.0.0",

+ 48 - 0
plugins/dragula/main.ts

@@ -0,0 +1,48 @@
+import * as dragula from 'dragula'
+import * as FullCalendar from 'fullcalendar'
+
+
+let visibleCalendars = []
+
+FullCalendar.Calendar.on('initialRender', function(calendar) {
+  visibleCalendars.push(calendar)
+
+  calendar.one('destroy', function() {
+    FullCalendar.removeExact(visibleCalendars, calendar)
+  })
+})
+
+
+let recentEvent
+
+[
+  'mousedown',
+  'touchstart',
+  'pointerdown'
+].forEach(function(eventName) {
+  document.addEventListener(eventName, function(ev) {
+    recentEvent = ev
+  })
+})
+
+
+function constructDragula(...args) {
+  let drake = dragula.apply(window, args)
+
+  drake.on('drag', function(draggingEl) { // dragging started
+    for (let calendar of visibleCalendars) {
+      calendar.handlExternalDragStart(
+        recentEvent,
+        draggingEl,
+        false // have FullCalendar watch for mouse/touch events
+          // because dragula doesn't expose a 'move' event
+      )
+    }
+  })
+
+  return drake
+}
+
+
+(FullCalendar as any).dragula = constructDragula
+export default constructDragula

+ 1 - 1
plugins/jquery-ui-draggable/main.ts

@@ -31,7 +31,7 @@ Calendar.on('initialRender', function(calendar) {
 
   $document.on('dragstart sortstart', handleDragStart)
 
-  calendar.on('destroy', function(calendar) {
+  calendar.one('destroy', function(calendar) {
     $document.off('dragstart sortstart', handleDragStart)
   })
 })

+ 1 - 6
src/component/interactions/ExternalDropping.ts

@@ -225,7 +225,7 @@ function getDraggedElMeta(el) {
   if (startTime == null) { startTime = getEmbeddedElData(el, 'start') }
   if (startTime == null) { startTime = getEmbeddedElData(el, 'time') } // accept 'time' as well
   if (duration == null) { duration = getEmbeddedElData(el, 'duration') }
-  if (stick == null) { stick = getEmbeddedElData(el, 'stick') }
+  if (stick == null) { stick = getEmbeddedElData(el, 'stick', true) }
 
   // massage into correct data types
   startTime = startTime != null ? moment.duration(startTime) : null
@@ -245,10 +245,5 @@ function getEmbeddedElData(el, name, shouldParseJson = false) {
     data = JSON.parse(data)
   }
 
-  if (data === null && window['jQuery']) {
-    // jQuery will automatically parse JSON
-    data = window['jQuery'](el).data(prefixedName)
-  }
-
   return data
 }

+ 4 - 0
webpack.config.js

@@ -15,6 +15,7 @@ const MODULES = {
   'dist/fullcalendar.print.css': './src/common/print.scss',
   'dist/gcal': './plugins/gcal/main.ts',
   'dist/jquery-ui-draggable': './plugins/jquery-ui-draggable/main.ts',
+  'dist/dragula': './plugins/dragula/main.ts',
   'tmp/automated-tests': './tests/automated/index'
 }
 
@@ -43,6 +44,9 @@ module.exports = {
       root: 'jQuery'
     },
 
+    // for plugins
+    dragula: 'dragula',
+
     // plugins reference the root 'fullcalendar' namespace
     fullcalendar: {
       commonjs: 'fullcalendar',