/[drupal]/contributions/modules/quicksearch/quicksearch.js
ViewVC logotype

Contents of /contributions/modules/quicksearch/quicksearch.js

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.6 - (show annotations) (download) (as text)
Wed May 9 10:09:37 2007 UTC (2 years, 6 months ago) by stevemckenzie
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +38 -10 lines
File MIME type: text/javascript
few bug fixes, tweaks and added user searching support with content / user tabs in search results
1 // $Id: quicksearch.js,v 1.5 2007/04/16 22:35:35 stevemckenzie Exp $
2
3 // Create an object for quicksearch data.
4 Drupal.quicksearch = { }
5
6 /**
7 * Auto attach quicksearch features.
8 */
9 Drupal.quicksearch.autoAttach = function() {
10 $('input.autocomplete').each(function () {
11 Drupal.quicksearch.input = $('#' + this.id.substr(0, this.id.length - 13)).attr('autocomplete', 'OFF')[0];
12
13 // Only add quicksearch functionality to quicksearch configured forms.
14 if (Drupal.quicksearch.form(Drupal.quicksearch.input.id)) {
15 // Add a label to display inside the textfield only if the textfield has no value.
16 $(Drupal.quicksearch.input).val(Drupal.settings.quicksearch.fieldLabel).bind('click', function() { if($(this).val() == Drupal.settings.quicksearch.fieldLabel) { $(this).val(''); } });
17 $(Drupal.quicksearch.input).val(Drupal.settings.quicksearch.fieldLabel).bind('blur', function() { if($(this).val() == '') { $(this).val(Drupal.settings.quicksearch.fieldLabel); } });
18
19 // Hide the search form's submit button.
20 $('input[@type=submit]||[@type=image]', Drupal.quicksearch.input.form).hide();
21 // Setup craqbox.
22 if (!Drupal.settings.quicksearch.selector) {
23 Drupal.quicksearch.craqbox = $.craqbox(Drupal.quicksearch.input, {
24 type: 'dom',
25 title: Drupal.settings.quicksearch.title,
26 attachEvent: null,
27 width: Drupal.settings.quicksearch.uiWidth,
28 closeButtonTitle: Drupal.settings.quicksearch.closeButton,
29 verticalAlign: false
30 });
31 }
32 }
33 });
34 };
35
36 /**
37 * Setup the search pager queue to use AJAX vs its actual links.
38 */
39 Drupal.quicksearch.pagerSetup = function(db) {
40 var parent;
41
42 // Setup pager caching.
43 Drupal.quicksearch.pagerCache = Drupal.quicksearch.pagerCache || [];
44
45 // Grab the right parent element based on what type of display quicksearch is setup for.
46 if (Drupal.settings.quicksearch.selector) {
47 parent = $(Drupal.settings.quicksearch.selector);
48 } else {
49 var craqbox = Drupal.quicksearch.craqbox;
50 parent = $('#'+ craqbox.o.craqboxId +' .'+ craqbox.o.contentClass).get(0);
51 }
52
53 // Loop through the links in the pager turning the links into AJAX.
54 $('.pager a', parent).each(function() {
55 $(this).click(function(event) {
56 // Cache id for this content.
57 var key = this.href.replace('http://', '').replace(/\//g, '_');
58 if (Drupal.quicksearch.pagerCache[key]) {
59 Drupal.quicksearch.display(db, Drupal.quicksearch.pagerCache[key]);
60 } else {
61 $.get(this.href, function(results) {
62 Drupal.quicksearch.pagerCache[key] = results;
63 Drupal.quicksearch.display(db, results);
64 });
65 }
66
67 return false;
68 })
69 });
70 };
71
72 /**
73 * Setup content / user tabs to load via AJAX.
74 */
75 Drupal.quicksearch.tabSetup = function(db) {
76 var parent;
77
78 // Use the right parent.
79 if (Drupal.settings.quicksearch.selector) {
80 parent = $('#'+ Drupal.settings.quicksearch.selector);
81 } else {
82 parent = $('#'+ Drupal.quicksearch.craqbox.o.craqboxId);
83 }
84
85 // Add AJAX functionality.
86 $('.quicksearch-tabs a', parent).each(function() {
87 if ($(this).is('.active')) {
88 Drupal.quicksearch.searchType = $(this).parent().id().replace('quicksearch-', '').replace('-link', '');
89 }
90 $(this).
91 click(function(event) {
92 if (Drupal.quicksearch.searchTab != $(this).html()) {
93 $.get(this.href, function(results) {
94 Drupal.quicksearch.display(db, results);
95 });
96 // Save this tab name as the current tab to avoid unnecessary AJAX calls.
97 Drupal.quicksearch.searchTab = $(this).html();
98 }
99 return false;
100 });
101 });
102 };
103
104 /**
105 * Handle displaying the search results.
106 */
107 Drupal.quicksearch.display = function(db, results) {
108 // Search results added to an element.
109 if (Drupal.settings.quicksearch.selector) {
110 var el = $(Drupal.settings.quicksearch.selector);
111 // A close button so the original page content can be restored.
112 var closeButton = $('<a>')
113 .attr({ title: Drupal.settings.quicksearch.closeButtonTitle, className: 'quicksearch_close_button', href: '#close' })
114 .click(function() { Drupal.quicksearch.remove(db.input); return false; })
115 .html(Drupal.settings.quicksearch.closeButtonLabel);
116
117 // Cache the original page content before quicksearch occurred.
118 if ($('#quicksearch_cache').length == 0) {
119 $('<div>').attr('id', 'quicksearch_cache').css('display', 'none').append($(el).children()).appendTo(document.body);
120 }
121 $(el).fadeOut('fast', function() {
122 $(el).html(results).prepend(closeButton).fadeIn('fast');
123 });
124 Drupal.quicksearch.pagerSetup(db);
125 Drupal.quicksearch.tabSetup(db);
126 }
127 // Search results displayed in craqbox.
128 else {
129 // Save the original parent so we can restore the element to its original state.
130 if (!db.input.originalParent) {
131 db.input.originalParent = db.input.parentNode;
132 }
133
134 // Remove craqbox on escape key.
135 $(db.input).bind('keyup', Drupal.quicksearch.removeEsc);
136
137 // Display in craqbox.
138 Drupal.quicksearch.craqbox.build({
139 content: $('<div>').append($(db.input)).append($('<div>').html(results)),
140 completeCallback: function() {
141 db.input.focus();
142 Drupal.quicksearch.pagerSetup(db);
143 Drupal.quicksearch.tabSetup(db);
144 },
145 removeCallback: function() {
146 Drupal.quicksearch.remove(db.input);
147 }
148 });
149 }
150 };
151
152 /**
153 * Check if a form is a quicksearch form.
154 */
155 Drupal.quicksearch.form = function(id) {
156 for (var i in Drupal.settings.quicksearch.fields) {
157 field = 'edit-'+ Drupal.settings.quicksearch.fields[i].replace(/_/g, '-') +'-keys';
158 if (id == field) {
159 return true;
160 }
161 }
162 };
163
164 /**
165 * Remove the newly searched content.
166 */
167 Drupal.quicksearch.remove = function(input) {
168 if (Drupal.settings.quicksearch.selector) {
169 // Remove the search results and bring back the original page content.
170 $(Drupal.settings.quicksearch.selector).html('').append($('#quicksearch_cache').children());
171 $('#quicksearch_cache').remove();
172 } else {
173 // Save the original display because one faded in, jQuery will set the display = block even if it was inline.
174 $(input)
175 .attr('originalDisplay', $(input).css('display'))
176 .css('display', 'none')
177 .unbind('keyup', Drupal.quicksearch.removeEsc)
178 .appendTo(input.originalParent)
179 .fadeIn('fast', function() {
180 input.focus();
181 $(input).css('display', $(input).attr('originalDisplay'));
182 });
183 }
184 }
185
186 /**
187 * Used by the textfield so the user can press escape to remove the UI version of the search results.
188 */
189 Drupal.quicksearch.removeEsc = function(event) {
190 if (event.keyCode == 27) {
191 Drupal.quicksearch.craqbox.remove();
192 }
193 }
194
195 /**
196 * These functions below are taken from autocomplete.js and slightly modified to work for live searching.
197 * One noted improvement is that if it is a search autocomplete, use drupal's search module setting for min characters allowed in a search.
198 * Live search requests are also cached like normal autocomplete calls.
199 */
200
201 /**
202 * Performs a cached and delayed search
203 */
204 Drupal.ACDB.prototype.search = function (searchString, input) {
205 var db = input ? input : this;
206 db.searchString = searchString;
207 var quicksearch = Drupal.quicksearch.form(db.owner.input.id);
208
209 // Check the search module's min character count for a search so we don't get errors.
210 if (quicksearch && searchString.length < Drupal.settings.quicksearch.minCharacters) {
211 return false;
212 }
213
214 // See if db key has been searched for before
215 if (db.cache[searchString]) {
216 return db.owner.found(db.cache[searchString]);
217 }
218
219 // Initiate delayed search
220 if (db.timer) {
221 clearTimeout(db.timer);
222 }
223 db.timer = setTimeout(function() {
224 db.owner.setStatus('begin');
225
226 // Set a search type of node or user.
227 if (quicksearch && Drupal.quicksearch.searchType) {
228 db.uri = Drupal.settings.quicksearch.searchPath +'/'+ Drupal.quicksearch.searchType;
229 }
230
231 // Ajax GET request for autocompletion
232 $.ajax({
233 type: "GET",
234 url: db.uri +'/'+ Drupal.encodeURIComponent(searchString),
235 success: function (data) {
236 // Custom solution for live searching.
237 if (quicksearch && data) {
238 db.cache[searchString] = data;
239 // Verify if these are still the matches the user wants to see
240 if (db.searchString == searchString) {
241 db.owner.found(data);
242 }
243 db.owner.setStatus('found');
244 } else {
245 // Parse back result
246 var matches = Drupal.parseJson(data);
247 if (typeof matches['status'] == 'undefined' || matches['status'] != 0) {
248 db.cache[searchString] = matches;
249 // Verify if these are still the matches the user wants to see
250 if (db.searchString == searchString) {
251 db.owner.found(matches);
252 }
253 db.owner.setStatus('found');
254 }
255 }
256 },
257 error: function (xmlhttp) {
258 alert('An HTTP error '+ xmlhttp.status +' occured.\n'+ db.uri);
259 }
260 });
261 }, (quicksearch) ? Drupal.settings.quicksearch.uiDelay : db.delay);
262 }
263
264 /**
265 * Fills the suggestion popup with any matches received
266 */
267 Drupal.jsAC.prototype.found = function (matches) {
268 // If no value in the textfield, do not show the popup.
269 if (!this.input.value.length) {
270 return false;
271 }
272
273 // Custom solution for live searching.
274 if (Drupal.quicksearch.form(this.input.id)) {
275 // We're not using the popup so just hide it.
276 if (this.popup) {
277 $(this.popup).css({visibility: 'hidden'});
278 }
279 // Do not redraw because we now have the search textfield in this element and this would break functionality.
280 if (this.lastMatches != matches) {
281 Drupal.quicksearch.display(this, matches);
282 this.lastMatches = matches;
283 }
284 } else {
285 // Prepare matches
286 var ul = document.createElement('ul');
287 var ac = this;
288 for (key in matches) {
289 var li = document.createElement('li');
290 $(li)
291 .html('<div>'+ matches[key] +'</div>')
292 .mousedown(function () { ac.select(this); })
293 .mouseover(function () { ac.highlight(this); })
294 .mouseout(function () { ac.unhighlight(this); });
295 li.autocompleteValue = key;
296 $(ul).append(li);
297 }
298
299 // Show popup with matches, if any
300 if (this.popup) {
301 if (ul.childNodes.length > 0) {
302 $(this.popup).empty().append(ul).show();
303 }
304 else {
305 $(this.popup).css({visibility: 'hidden'});
306 this.hidePopup();
307 }
308 }
309 }
310 }
311
312 // Global Killswitch.
313 if (Drupal.jsEnabled) {
314 $(document).ready(Drupal.quicksearch.autoAttach);
315 }

  ViewVC Help
Powered by ViewVC 1.1.2