PageSourceSearch

https://www.openpolytechnic.ac.nz/_resources/themes/openpolytechni…/TypeAheadSearch.jquery-ui.js?m=1790920551

js openpolytechnic.ac.nz collected 2026-10-02 06:21:15 UTC 6,034 bytes, 185 lines download raw bytes

1/**
2 * Requires Jquery UI AutoComplete
3 */
4 $(document).ready(function() {
5	var QualAndCourseheadings = {
6		'Programme': 'Qualifications',
7		'Course': 'Courses'
8	};
9
10	jQuery.widget('custom.typeaheadsearch', jQuery.ui.autocomplete, {
11		_init: function(){
12			this._setOptions({
13				appendTo: '#result-typeahead',
14				position: {
15					my: 'left+24 top+24',
16					at: 'left top',
17					of: '#result-typeahead'
18				},
19				autoFocus: true
20			});
21		},
22		_create: function () {
23			this._super();
24			this.widget().menu('option', 'items', '> :not(.ui-autocomplete-category)');
25			this._on(this.element, {
26				input: function(event) {
27					this.search();
28				},
29				propertychange: function(event) {
30					this.search();
31				},
32      			focus: function(event) {
33        			this.search();
34      			},
35				paste: function(event) {
36        			this.search();
37      			}
38    		});
39		},
40		_renderMenu: function (ul, items) {
41			var self = this;
42			currenttype = "";
43			$.each(items, function(index, item) {
44				if (item.ClassName != currenttype) {
45					var header = $('<li class="ui-autocomplete-category">'
46                        + '<div>'
47                            + '<h3 class="tas-heading"></h3>'
48                        + '</div>'
49                    + '</li>');
50					var heading = item.ClassName;
51					if(typeof QualAndCourseheadings[item.ClassName] != 'undefined') {
52						heading = QualAndCourseheadings[item.ClassName];
53					}
54					header.find('.tas-heading').text(heading);
55					ul.append(header);
56					currenttype = item.ClassName;
57				}
58				var li = self._renderItemData(ul, item);
59				if ( typeof item.ClassName != "undefined") {
60					li.attr( "aria-label", item.ClassName + " : " + item.Code + " " + item.Title );
61					li.attr( "aria-value", item.Code + " " + item.Title );
62				}
63			});
64		},
65		_renderItem: function (ul, item) {
66			var label = item.Code + " " + item.Title;
67			return $('<li>')
68				// .data( 'ui-autocomplete-item', item ) // Not working
69				.append('<a href="' + item.Link + '" class="item-type-' + item.ClassName +
70					'" title="' + label + '" alt="' + label
71					+ '" onclick="$(\'input[name=TypeAheadInput]\').val(\'\');"'
72        			+ 'data-gaevent-category="' + item.ClassName + '" data-gaevent-action="TypeAheadSearch" '
73					+ 'data-gaevent-label="' + item.Code + '">'
74						+ '<div>'
75						+ '<span>' + label + '</span>'
76					+ '</div>'
77				+ '</a>')
78				.appendTo(ul);
79		},
80		_resizeMenu: function(){
81			var wdth = this.element[0].offsetWidth;
82			wdth = wdth - 48;
83			this.menu.element.outerWidth(wdth);
84		}
85	});
86
87	var TypeAheadSearch = {
88		path: $('input[name=TypeAheadInput]').attr('data-src'),
89		selector: 'input[name=TypeAheadInput]',
90		noResultSelector: '#no-result-typeahead',
91		resultSelector: '#result-typeahead',
92		instance: null,
93		ignoreWords: ['and', 'the', 'in', 'of'],
94		items: [],
95		minLength: 3,
96		init: function () {
97			// make sure the "no results" div doesn't show up on load
98			$(TypeAheadSearch.noResultSelector).hide();
99
100			// remove the "no results" div when the character number goes below the minimum length
101			$(TypeAheadSearch.selector).on('input propertychange', function(){
102				var val = $(this).val();
103				if (val.length < TypeAheadSearch.minLength) {
104					$(TypeAheadSearch.noResultSelector).hide();
105				}
106			});
107
108			// remove the "no results" div when the INPUT has focus
109			$(TypeAheadSearch.selector).on('blur', function(){
110				$(TypeAheadSearch.noResultSelector).hide();
111			});
112
113			TypeAheadSearch.load(function(){
114				TypeAheadSearch.instance = jQuery(TypeAheadSearch.selector).typeaheadsearch({
115					source: function (request, response) {
116						var searchText = TypeAheadSearch.cleanQuery(request.term);
117						var result = [];
118						var querys = searchText.split(' ');
119						if ($.trim(searchText) != '' && querys.length > 0) {
120							jQuery.each(TypeAheadSearch.items, function (index, item) {
121								var matched = true;
122								querys.forEach(function(query) {
123									matched = matched && (new RegExp(query, "i")).test(item.SearchText);
124								});
125								if (matched) {
126									result.push(item);
127								}
128							});
129						}
130						if (result.length === 0) {
131							$(TypeAheadSearch.noResultSelector).show();
132							if (typeof ga_send_event === "function") {
133								ga_send_event({
134									eventCategory: $('input[name=TypeAheadPageType]').val(),
135									eventAction: "TypeAheadSorry",
136									eventLabel: $('input[name=TypeAheadInput]').val()
137								});
138							}
139						}
140						else {
141							$(TypeAheadSearch.resultSelector).show();
142						}
143						response(result);
144					},
145					minLength: TypeAheadSearch.minLength,
146					select: function (event, ui) {
147                        event.preventDefault();
148                        var item = $(TypeAheadSearch.resultSelector + ' .ui-menu-item a.ui-state-active');
149						if (typeof ga_send_event === "function") {
150							ga_send_event({
151								eventCategory: $('input[name=TypeAheadPageType]').val(),
152								eventAction: item.attr("data-gaevent-action"),
153								eventLabel: item.attr("data-gaevent-label")
154							});
155						}
156						$('input[name=TypeAheadInput]').val(item.text());
157						window.location = item.attr('href');
158						$(TypeAheadSearch.resultSelector).hide();
159                        return false;
160					},
161					close: function(event,ui){
162						$(TypeAheadSearch.noResultSelector).hide();
163						$(TypeAheadSearch.resultSelector).hide();
164					}
165				}).autocomplete("instance");
166			});
167
168		},
169		load: function (callback) {
170			$('input[name=TypeAheadInput]').val('');
171			$.getJSON(TypeAheadSearch.path, function (data) {
172				TypeAheadSearch.items = data;
173				if (typeof callback != "undefined") {
174					callback();
175				}
176			});
177		},
178		cleanQuery: function (query) {
179			return (query.replace(new RegExp("^" + TypeAheadSearch.ignoreWords.join("\\s|^") + "\\s", "gi"), ' ')
180				.replace(new RegExp("\\s" + TypeAheadSearch.ignoreWords.join("$|\\s") + "$", "gi"), ' ')
181				.replace(new RegExp("\\s" + TypeAheadSearch.ignoreWords.join("\\s|\\s") + "\\s", "gi"), ' ')).trim();
182		}
183	};
184	TypeAheadSearch.init();
185});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.