-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
204 lines (175 loc) · 7.03 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// TODO: Consider https://github.com/vuejs/vue-devtools
//
// Application Features:
// - Remembers previous criteria
// - Goes to trusted CoE site to complete registration and pay
//
// Future:
// - Warning if number registered exceeds capacity
// - Filter out duplicates in data which have identical course_id and activity_id
// - User input validation (i.e. start date)
//
// Trying to use doc comments as per https://github.com/Microsoft/tsdoc
//
// Acknowledgements:
// - https://www.sitepoint.com/fetching-data-third-party-api-vue-axios/
// -
// - https://vuejsdevelopers.com/2017/05/20/vue-js-safely-jquery-plugin/
//
// Vue component wrapping JQuery's datepicker.
// See https://vuejsdevelopers.com/2017/05/20/vue-js-safely-jquery-plugin/
// TODO: Move related JS and CSS references into component
//
Vue.component('date-picker', {
template: '<div><input v-bind:placeholder="placeholderValue" v-bind:value="initialValue" /><span v-on:click="$emit(\'update-date\', \'\');"><i class="fas fa-trash-alt"></i></span></div>',
props: [ 'dateFormat', 'placeholderValue', 'initialValue' ],
mounted: function() {
var self = this;
$(this.$el).datepicker({
dateFormat: this.dateFormat,
onSelect: function(date) {
// See https://vuejs.org/v2/guide/components.html
self.$emit('update-date', date);
}
});
},
beforeDestroy: function() {
$(this.$el).datepicker('hide').datepicker('destroy');
}
});
const vm = new Vue({
el: '#app',
data: {
results: [],
// Some static data for testing purposes
version: "0.8.2",
facilities: [],
selectedFacilities: [],
selectedStartDate: "",
includeFutureActivities: false,
ageRanges: [],
selectedAgeRanges: [],
activityTypes: [],
selectedActivityTypes: [],
initiatedSearch: false
},
mounted() {
// Initialization for Foundation UI behaviors
$(document).foundation();
console.log("Querying for data at " + new Date() + " ...");
axios.get("https://data.edmonton.ca/resource/bcq5-mvix.json?$$app_token=mGU6RS7ckRjIiKwH0k120LJkb")
.then(response => {
this.results = response.data;
// Sort by start date so that closest activities are shown first
this.results = this.results.sort(function(a, b) { return new Date(Date.parse(a.start_date)).getTime() - new Date(Date.parse(b.start_date)).getTime() });
console.log("Received data at " + new Date());
// Get unique lists
var uniqueFacilities = new Set();
var uniqueAgeRanges = new Set();
var uniqueActivityTypes = new Set();
for (var i = 0; i < this.results.length; i++) {
uniqueFacilities.add(this.results[i].facility);
uniqueAgeRanges.add(this.results[i].age);
uniqueActivityTypes.add(this.results[i].activity_type);
}
this.facilities = Array.from(uniqueFacilities);
this.facilities.sort();
this.ageRanges = Array.from(uniqueAgeRanges);
this.ageRanges.sort();
this.activityTypes = Array.from(uniqueActivityTypes);
this.activityTypes.sort();
console.log("Finished processing data at " + new Date());
// Load previous selections
this.selectedFacilities = this.loadPreviousSelection('selectedFacilities', this.selectedFacilities);
this.selectedStartDate = this.loadPreviousSelection('selectedStartDate', this.selectedStartDate);
this.includeFutureActivities = this.loadPreviousSelection('includeFutureActivities', this.includeFutureActivities);
this.selectedAgeRanges = this.loadPreviousSelection('selectedAgeRanges', this.selectedAgeRanges);
this.selectedActivityTypes = this.loadPreviousSelection('selectedActivityTypes', this.selectedActivityTypes);
}).catch(function (error) {
// e.g. Sometimes deserialization may not work because of problems during serialization to localStorage
console.log(error);
})
},
methods: {
// @param activityDetails - see sample-data.json for object attributes
// @returns true or false
includeResult(activityDetails) {
var doInclude = true;
if (doInclude) {
// If there were any selectedFacilities, does this activityDetails have a matching facility?
doInclude = ((this.selectedFacilities.length > 0) ? (this.selectedFacilities.indexOf(activityDetails.facility) != -1) : doInclude);
}
if (doInclude) {
// If there were any selectedAgeRanges, does this activityDetails have a matching age range?
doInclude = ((this.selectedAgeRanges.length > 0) ? (this.selectedAgeRanges.indexOf(activityDetails.age) != -1) : doInclude);
}
if (doInclude) {
// If start date has been selected, does this activityDetails have a matching start date?
// Initial strings must be unambiguous.
var activityStart = new Date(Date.parse(activityDetails.start_date));
var selectedStart = new Date(Date.parse(this.selectedStartDate));
if (this.selectedStartDate !== "") {
doInclude = selectedStart.getTime() === activityStart.getTime();
if (this.includeFutureActivities) {
doInclude = activityStart.getTime() >= selectedStart.getTime();
}
}
}
if (doInclude) {
// If there were any selectedAgeRanges, does this activityDetails have a matching age range?
doInclude = ((this.selectedAgeRanges.length > 0) ? (this.selectedAgeRanges.indexOf(activityDetails.age) != -1) : doInclude);
}
if (doInclude) {
// If there were any selectedActivityTypes, does this activityDetails have a matching activity type?
doInclude = ((this.selectedActivityTypes.length > 0) ? (this.selectedActivityTypes.indexOf(activityDetails.activity_type) != -1) : doInclude);
}
return doInclude;
},
updateStartDate(date) {
this.selectedStartDate = date;
},
loadPreviousSelection(key, defaultValue) {
if (localStorage.getItem(key)) {
return JSON.parse(localStorage.getItem(key));
} else {
// Empty string seems to work better than undefined
return defaultValue;
}
},
saveSelection(key, value) {
localStorage.setItem(key, JSON.stringify(value));
}
},
watch: {
selectedFacilities: {
handler() {
this.saveSelection('selectedFacilities', this.selectedFacilities);
}
},
selectedStartDate: {
handler() {
this.saveSelection('selectedStartDate', this.selectedStartDate);
}
},
includeFutureActivities: {
handler() {
this.saveSelection('includeFutureActivities', this.includeFutureActivities);
}
},
selectedAgeRanges: {
handler() {
this.saveSelection('selectedAgeRanges', this.selectedAgeRanges);
}
},
selectedActivityTypes: {
handler() {
this.saveSelection('selectedActivityTypes', this.selectedActivityTypes);
}
},
initiatedSearch: {
handler() {
console.log("initiatedSearch changed")
}
},
}
});