Skip to content

Commit abd9e4f

Browse files
Merge pull request #1157 from flibbertigibbet/feature/kak/drag-tour-destinations#1112
Feature/kak/drag tour destinations#1112
2 parents a0126c1 + f0bf510 commit abd9e4f

File tree

8 files changed

+110
-111
lines changed

8 files changed

+110
-111
lines changed

python/cac_tripplanner/templates/base.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@
100100
{% endif %}
101101
<script src="{% static 'scripts/vendor/index.js' %}"></script>
102102
<script src="{% static 'scripts/vendor/jquery.js' %}"></script>
103+
<script src="{% static 'scripts/vendor/Sortable.js' %}"></script>
104+
<script src="{% static 'scripts/vendor/jquery-sortable.js' %}"></script>
103105
<script src="{% static 'scripts/vendor/cartodb.uncompressed.js' %}"></script>
104106
<script src="{% static 'scripts/vendor/leaflet.awesome-markers.js' %}"></script>
105107
<script src="{% static 'scripts/vendor/js.storage.js' %}"></script>

src/app/scripts/cac/control/cac-control-directions.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ CAC.Control.Directions = (function (_, $, moment, Control, Places, Routing, User
66

77
'use strict';
88

9-
// Number of millis to wait on input changes before sending directions request
9+
// Number of milliseconds to wait on input changes before sending directions request
1010
var DIRECTION_THROTTLE_MILLIS = 750;
1111

12+
// Number of milliseconds to wait on destination list reorder before requerying directions
13+
var REORDER_TOUR_THROTTLE_MILLIS = 1000;
14+
1215
var defaults = {
1316
selectors: {
1417
directions: '.directions-results',
@@ -119,6 +122,11 @@ CAC.Control.Directions = (function (_, $, moment, Control, Places, Routing, User
119122
$(options.selectors.spinner).addClass(options.selectors.hiddenClass);
120123
}
121124
});
125+
126+
tourListControl.events.on(tourListControl.eventNames.destinationsReordered,
127+
function(e, destinations) {
128+
reorderTourDestinations(destinations);
129+
});
122130
}
123131

124132
DirectionsControl.prototype = {
@@ -248,6 +256,17 @@ CAC.Control.Directions = (function (_, $, moment, Control, Places, Routing, User
248256
});
249257
}, DIRECTION_THROTTLE_MILLIS, {leading: true, trailing: true});
250258

259+
/**
260+
* Reorder tour destination waypoints and end point and requery for directions.
261+
* Throttled to cut down on requests.
262+
*/
263+
var reorderTourDestinations = _.debounce(function(destinations) { // jshint ignore:line
264+
tour.destinations = destinations;
265+
itineraryControl.clearItineraries();
266+
mapControl.setDirectionsMarkers(null, null, true);
267+
onTypeaheadSelectDone('destination', destinations);
268+
}, REORDER_TOUR_THROTTLE_MILLIS, {leading: false, trailing: true});
269+
251270
return DirectionsControl;
252271

253272
function onTabShown(event, tabId) {

src/app/scripts/cac/control/cac-control-tour-list.js

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ CAC.Control.TourList = (function (_, $, MapTemplates) {
2727
var events = $({});
2828
var eventNames = {
2929
destinationClicked: 'cac:control:tourlist:destinationclicked',
30-
destinationHovered: 'cac:control:tourlist:destinationhovered'
30+
destinationHovered: 'cac:control:tourlist:destinationhovered',
31+
destinationsReordered: 'cac:control:tourlist:destinationsreordered'
3132
};
3233

3334
var $container = null;
3435
var destinations = [];
36+
var tourId = null;
3537

3638
function TourListControl(params) {
3739
options = $.extend({}, defaults, params);
@@ -52,16 +54,57 @@ CAC.Control.TourList = (function (_, $, MapTemplates) {
5254
return TourListControl;
5355

5456
function setTourDestinations(tour) {
55-
destinations = tour.destinations;
57+
if (tour.id !== tourId) {
58+
tourId = tour.id;
59+
destinations = tour.destinations;
60+
} else {
61+
// tour unchanged; preserve user assigned destination order
62+
tour.destinations = destinations;
63+
}
5664

5765
// Show the directions div and populate with tour destinations
5866
var html = MapTemplates.tourDestinationList(tour);
5967
$container.html(html);
6068

6169
$(options.selectors.destinationDirectionsButton).on('click', onTourDestinationClicked);
6270
$(options.selectors.destinationItem).on('mouseenter', onTourDestinationHovered);
63-
6471
$(options.selectors.destinationItem).on('mouseleave', onTourDestinationHoveredOut);
72+
73+
var $destinationList = $(options.selectors.destinationList);
74+
75+
// First remove sortable if already initialized
76+
if ($destinationList.sortable('widget')) {
77+
$destinationList.sortable('destroy');
78+
}
79+
80+
// Set up sortable list for tours (not events)
81+
if (tour.is_tour) {
82+
var $sortableList = $destinationList.sortable({
83+
animation: 150,
84+
direction: 'vertical',
85+
draggable: options.selectors.destinationItem,
86+
// Allow scrolling while dragging by not using native HTML5
87+
// See: https://github.com/SortableJS/Sortable/issues/935
88+
forceFallback: true,
89+
sort: true,
90+
onUpdate: onDestinationListReordered
91+
});
92+
}
93+
}
94+
95+
// Called when Sortable list of destinations gets updated
96+
function onDestinationListReordered(e) {
97+
var kids = e.to.children;
98+
// First list item is the header; skip it
99+
for (var i = 1; i < kids.length; i++) {
100+
var k = kids[i];
101+
var originalIndex = k.getAttribute('data-tour-place-index');
102+
// assign property with new order
103+
destinations[originalIndex].userOrder = i;
104+
}
105+
106+
destinations = _.sortBy(destinations, 'userOrder');
107+
events.trigger(eventNames.destinationsReordered, [destinations]);
65108
}
66109

67110
/**

src/gulpfile.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,22 @@ var scriptOrder = [
6767
'**/*.js',
6868
];
6969

70+
// Load jQuery and Sortable dependencies before the plugin
71+
var vendorScriptOrder = [
72+
'**/jquery.js',
73+
'**/Sortable*.js',
74+
'**/jquery-sortable*.js',
75+
'**/*.js'
76+
];
77+
7078
// Helper for copying over dependency files
7179
var copyNpmFiles = function() {
72-
return gulp.src(mainNPM({
73-
showWarnings: true
74-
}), {allowEmpty: true, ignore: '**/*gulpfile*'});
80+
return pump([
81+
gulp.src(mainNPM({
82+
showWarnings: true
83+
}), {allowEmpty: true, ignore: '**/*gulpfile*'}),
84+
order(vendorScriptOrder)
85+
]);
7586
};
7687

7788
gulp.task('collectstatic', function (done) {

src/karma/karma-coverage.conf.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ module.exports = function(config) {
1818
// console polyfills
1919
'/srv/cac/scripts/vendor/index.js',
2020
'/srv/cac/scripts/vendor/jquery.js',
21+
'/srv/cac/scripts/vendor/Sortable.js',
22+
'/srv/cac/scripts/vendor/jquery-sortable.js',
2123
'/srv/cac/scripts/vendor/lodash.js',
2224
// load moment before other vendor scripts; is requirement for bootstrap datetime picker
2325
'/srv/cac/scripts/vendor/moment.js',

src/karma/karma-dev.conf.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ module.exports = function(config) {
1818
// console polyfills
1919
'/srv/cac/scripts/vendor/index.js',
2020
'/srv/cac/scripts/vendor/jquery.js',
21+
'/srv/cac/scripts/vendor/Sortable.js',
22+
'/srv/cac/scripts/vendor/jquery-sortable.js',
2123
'/srv/cac/scripts/vendor/lodash.js',
2224
'/srv/cac/scripts/vendor/handlebars.js',
2325
// load moment before other vendor scripts; is requirement for bootstrap datetime picker

src/package-lock.json

Lines changed: 22 additions & 104 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)