18
18
*
19
19
* Example of usage:
20
20
*
21
+ * Create a list (for example <ul> or <tbody>) where each draggable element has a drag handle.
22
+ * The best practice is to use the template core/drag_handle:
23
+ * $OUTPUT->render_from_template('core/drag_handle', ['movetitle' => get_string('movecontent', 'moodle', ELEMENTNAME)]);
24
+ *
25
+ * Attach this JS module to this list:
26
+ *
21
27
* define(['jquery', 'core/sortable_list'], function($, SortableList) {
22
- * var list = new SortableList('ul.my-awesome-list', // source list (usually <ul> or <tbody>) - selector or element
23
- * {
24
- * moveHandlerSelector: '.draghandle' // CSS selector of the crossarrow handle. Make sure that this
25
- * // element can handle keypress and mouse click events for displaying accessible move popup.
26
- * });
28
+ * var list = new SortableList('ul.my-awesome-list'); // source list (usually <ul> or <tbody>) - selector or element
29
+ *
30
+ * // Listen to the events when element is dragged.
27
31
* $('ul.my-awesome-list > *').on(SortableList.EVENTS.DROP, function(evt, info) {
28
32
* console.log(info);
29
33
* });
@@ -62,7 +66,7 @@ function($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {
62
66
*/
63
67
var defaultParameters = {
64
68
targetListSelector : null ,
65
- moveHandlerSelector : null ,
69
+ moveHandlerSelector : '[data-drag-type=move]' ,
66
70
isHorizontal : false ,
67
71
autoScroll : true
68
72
} ;
@@ -82,6 +86,36 @@ function($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {
82
86
overElementClass : 'sortable-list-over-element'
83
87
} ;
84
88
89
+ /**
90
+ * Test the browser support for options objects on event listeners.
91
+ * @return Boolean
92
+ */
93
+ var eventListenerOptionsSupported = ( function ( ) {
94
+ var passivesupported = false ,
95
+ options ,
96
+ testeventname = "testpassiveeventoptions" ;
97
+
98
+ // Options support testing example from:
99
+ // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
100
+
101
+ try {
102
+ options = Object . defineProperty ( { } , "passive" , {
103
+ get : function ( ) {
104
+ passivesupported = true ;
105
+ }
106
+ } ) ;
107
+
108
+ // We use an event name that is not likely to conflict with any real event.
109
+ document . addEventListener ( testeventname , options , options ) ;
110
+ // We remove the event listener as we have tested the options already.
111
+ document . removeEventListener ( testeventname , options , options ) ;
112
+ } catch ( err ) {
113
+ // It's already false.
114
+ passivesupported = false ;
115
+ }
116
+ return passivesupported ;
117
+ } ) ( ) ;
118
+
85
119
/**
86
120
* Allow to create non-passive touchstart listeners and prevent page scrolling when dragging
87
121
* From: https://stackoverflow.com/a/48098097
@@ -90,7 +124,7 @@ function($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {
90
124
*/
91
125
$ . event . special . touchstart = {
92
126
setup : function ( _ , ns , handle ) {
93
- if ( ns . includes ( 'notPassive' ) ) {
127
+ if ( eventListenerOptionsSupported && ns . includes ( 'notPassive' ) ) {
94
128
this . addEventListener ( 'touchstart' , handle , { passive : false } ) ;
95
129
return true ;
96
130
} else {
@@ -105,8 +139,7 @@ function($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {
105
139
* @param {(String|jQuery|Element) } root JQuery/DOM element representing sortable list (i.e. <ul>, <tbody>) or CSS selector
106
140
* @param {Object } config Parameters for the list. See defaultParameters above for examples.
107
141
* @property {(String|jQuery|Element) } config.targetListSelector target lists, by default same as root
108
- * @property {String } config.moveHandlerSelector CSS selector for a drag handle. By default the whole item is a handle.
109
- * Without drag handle sorting is not accessible!
142
+ * @property {String } config.moveHandlerSelector CSS selector for a drag handle. By default '[data-drag-type=move]'
110
143
* @property {String } config.targetListSelector CSS selector for target lists. By default the same as root
111
144
* @property {(Boolean|Function) } config.isHorizontal Set to true if the list is horizontal
112
145
* (can also be a callback with list as an argument)
@@ -607,9 +640,13 @@ function($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {
607
640
*
608
641
* @public
609
642
* @param {jQuery } element
643
+ * @param {jQuery } handler
610
644
* @return {Promise }
611
645
*/
612
- SortableList . prototype . getMoveDialogueTitle = function ( element ) {
646
+ SortableList . prototype . getMoveDialogueTitle = function ( element , handler ) {
647
+ if ( handler . attr ( 'title' ) ) {
648
+ return $ . Deferred ( ) . resolve ( handler . attr ( 'title' ) ) ;
649
+ }
613
650
return this . getElementName ( element ) . then ( function ( name ) {
614
651
return str . get_string ( 'movecontent' , 'moodle' , name ) ;
615
652
} ) ;
@@ -677,7 +714,7 @@ function($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {
677
714
SortableList . prototype . displayMoveDialogue = function ( clickedElement ) {
678
715
ModalFactory . create ( {
679
716
type : ModalFactory . types . CANCEL ,
680
- title : this . getMoveDialogueTitle ( this . info . element ) ,
717
+ title : this . getMoveDialogueTitle ( this . info . element , clickedElement ) ,
681
718
body : this . getDestinationsList ( )
682
719
} ) . then ( $ . proxy ( function ( modal ) {
683
720
var quickMoveHandler = $ . proxy ( function ( e ) {
0 commit comments