/
picky.controller.js
167 lines (134 loc) · 5.58 KB
/
picky.controller.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
var PickyController = function(config) {
var view = new PickyView(this, config);
var backends = config.backends;
var beforeInsertCallback = config.beforeInsert || function(query) { };
var beforeCallback = config.before || function(query, params) { };
var successCallback = config.success || function(data, query) { };
var afterCallback = config.after || function(data, query) { };
var liveRendered = config.liveRendered || false;
var liveSearchTimerInterval = config.liveSearchInterval || 180;
var lastQueryParams;
// Extracts the query part from an URL.
//
var extractQuery = function(url) {
var match = url && url.match(/q=([^&]+)/);
return match && decodeURIComponent(match[1]).replace(/\+/g, ' ').replace(/#/g, '') || "";
};
this.extractQuery = extractQuery;
// Returns the last saved query from
// the saved params.
//
var lastQuery = function() {
return lastQueryParams.length > 1 && lastQueryParams[1];
}
// Failsafe extraction of the last made query.
//
var lastFullQuery = function() {
var state = window.History && window.History.getState();
var url = state && state.url;
return extractQuery(url);
};
this.lastFullQuery = lastFullQuery;
// Saves the last query in history.
//
var saveInHistory = function(query) {
// Be extra cautious since not all browsers/histories offer pushState.
//
// Note: If this query is the same as the last, we do not save it in the history.
//
if (query != lastFullQuery()) { // TODO Not full.
var url = "?q=" + escape(query).replace(/\*/g,'%2A');
window.History && window.History.getState() && window.History.pushState && window.History.pushState(null, null, url);
}
}
// If the given backend cannot be found, ignore the search request.
//
var search = function(type, query, callback, specificParams) {
query = beforeCallback(query, specificParams) || query;
lastQueryParams = [type, query, callback, specificParams];
saveInHistory(query);
var currentBackend = backends[type];
if (currentBackend) { currentBackend.search(query, callback, specificParams); };
};
// Resend the last query as it was.
//
var resend = function() {
if (lastQueryParams) { search.apply(this, lastQueryParams); }
};
this.resend = resend;
var fullSearchCallback = function(data, query) {
data = successCallback(data, query) || data;
view.fullResultsCallback(data);
afterCallback(data, query);
};
var fullSearch = function(query, possibleParams) {
clearInterval(liveSearchTimerId);
search('full', query, fullSearchCallback, possibleParams || {});
};
var liveSearchCallback = function(data, query) {
data = successCallback(data, query) || data;
view.liveResultsCallback(data);
afterCallback(data, query);
};
var liveCallbackUsed = liveRendered ? fullSearchCallback : liveSearchCallback;
var liveSearch = function(query, possibleParams) {
search('live', query, liveCallbackUsed, possibleParams || {});
};
// The timer is initially instantly stopped.
//
var liveSearchTimerId;
var liveSearchTimerCallback = function() {
liveSearch(view.text());
clearInterval(liveSearchTimerId);
};
liveSearchTimerId = setInterval(liveSearchTimerCallback, liveSearchTimerInterval);
clearInterval(liveSearchTimerId);
// TODO Remove the full parameter?
//
var insert = function(query, params, full) {
query = beforeInsertCallback(query) || query;
view.insert(query);
if (full) { fullSearch(query, params); }
};
this.insert = insert;
var clearButtonClicked = function() { clearInterval(liveSearchTimerId); };
this.clearButtonClicked = clearButtonClicked;
var searchTextCleared = function() { clearInterval(liveSearchTimerId); };
this.searchTextCleared = searchTextCleared;
var shouldTriggerSearch = function(event) {
var validTriggerKeys = [
0, // special char (ä ö ü etc...)
8, // backspace
13, // enter
32, // space
46, // delete
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, // numbers
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 // a-z
];
return $.inArray(event.keyCode, validTriggerKeys) > -1;
};
var searchTextEntered = function(text, event) {
if (shouldTriggerSearch(event)) {
if (event.keyCode == 13) { fullSearch(text); } else { clearInterval(liveSearchTimerId); liveSearchTimerId = setInterval(liveSearchTimerCallback, liveSearchTimerInterval); /* liveSearchTimer.reset(); */ }
}
};
this.searchTextEntered = searchTextEntered;
var searchButtonClicked = function(text) { fullSearch(text); };
this.searchButtonClicked = searchButtonClicked;
var allocationChosen = function(text) { fullSearch(text); };
this.allocationChosen = allocationChosen;
// Move to a view object.
var addinationClicked = function(text, event) { fullSearch(text, { offset: event.data.offset }); };
this.addinationClicked = addinationClicked;
// Bind adapter to let the back/forward button start queries.
//
if (window.History) {
window.History.Adapter.bind(window, 'statechange', function() {
var state = window.History.getState();
var query = extractQuery(state.url);
// A back/forward is always a full query.
//
if (query && query != lastQuery()) { insert(query, {}, true); }
});
};
};