PageSourceSearch

https://www.saskatoon.ca/themes/saskatoon_ca/js/address-autocomplete.js?tlu0aq

js saskatoon.ca collected 2026-09-24 09:19:53 UTC 6,207 bytes, 180 lines download raw bytes

1(function (window, document, $, wb, Drupal) {
2
3  'use strict';
4
5  function AutocompleteField(elementId) {
6    this.$document = wb.doc;
7    this.$element = $('#'+elementId);
8    this.elementList = elementId+'list';
9    this.itemList = [];
10    this.initAutocomplete();
11  }
12
13  AutocompleteField.prototype.enableEvents = function() {
14    this.$element.on('keydown', null, $.proxy(this.fetchData, this));
15    this.$element.on('focusout', null, $.proxy(this.fetchData, this));
16    this.currentLetter = '';
17  };
18
19  AutocompleteField.prototype.fetchData = function() {
20    /*jshint camelcase: false */
21    var searchString = this.$element.val();
22    if(!searchString || !searchString.length || searchString === this.currentLetter) {
23      return;
24    }
25
26    this.currentLetter = searchString;
27    this.$document.trigger({
28      type: 'ajax-fetch.wb',
29      element: this.$element,
30      fetch: {
31      url: encodeURI(Drupal.settings.COS.address_autocomplete_api + '?string=' + searchString)
32      }
33    });
34  };
35
36  AutocompleteField.prototype.updateList = function(items) {
37    var options = '';
38
39    this.$dataList.empty();
40    $.each(items, function (index, item) {
41      options += '<option label="' + item.label + '" value="' + item.value + '"></option>';
42    });
43
44    if (wb.ielt10) {
45      options ='<select>' + options + '</select>';
46    }
47
48    this.itemList = $.map(items, function (item) { return item.value; } );
49    this.$dataList.append(options);
50    this.$element.trigger('wb-update.wb-datalist');
51  };
52
53  AutocompleteField.prototype.initAutocomplete = function() {
54    this.$element.after('<datalist id="'+this.elementList+'"><!--[if lte IE 9]><select><![endif]--><!--[if lte IE 9]></select><![endif]--></datalist>');
55    this.$dataList = $('#' + this.$element.attr('list'));
56  };
57
58  AutocompleteField.prototype.clearInvalid = function() {
59    if(this.itemList.indexOf(parseInt(this.$element.val(), 10)) === -1) {
60      this.$element.val('');
61    }
62  };
63
64  function AddressForm(element) {
65    this.$element = $(element);
66    this.$element.on('keypress', $.proxy(this.nextField, this));
67    this.$element.find('.form-item-building-number').parent().removeClass('hidden');
68    this.streetField = new AutocompleteField('street');
69    this.buildingField = new AutocompleteField('building');
70    this.unitField = new AutocompleteField('unit');
71    this.$page = this.$element.find('#page');
72
73    this.streetField.enableEvents();
74    this.streetField.$document.on('ajax-fetched.wb', null, $.proxy(this.parseData, this));
75    this.streetField.$element.on('focusout', $.proxy(this.updateBuildings, this));
76    this.buildingField.$element.on('focusout', $.proxy(this.updateUnits, this));
77    this.buildingCache = '';
78  }
79
80  AddressForm.prototype.initalize = function() {
81    this.streetField.$element.trigger('focusout');
82  };
83
84  AddressForm.prototype.parseData = function(event) {
85    /*jshint camelcase: false */
86    var data = wb.ielt10 ? event.fetch.response.data : event.fetch.response.data;
87    if(data === null) {
88      return;
89    }
90    var streets = $.map(data, function(street) { return {label: street.Street_Name, value: street.Street_Name}; });
91    this.streetField.updateList(streets);
92
93    var buildings = $.map(data, function(street) {
94      return $.map(street.Street_Number, function(streetNum) {
95        return $.extend({}, streetNum, {Street_Name: street.Street_Name});
96      });
97    });
98    this.buildingCache = buildings;
99    this.buildingField.updateList($.map(buildings, function(building) { return {label: building.Street_Number, value: building.Street_Number }; }));
100
101    this.updateUnits();
102  };
103
104  AddressForm.prototype.updateBuildings = function() {
105    /*jshint camelcase: false */
106    var streetName = this.streetField.$element.val();
107    var buildings = $.map(this.buildingCache, function(cached) { return (cached.Street_Name.indexOf(streetName) > -1) ? cached : null; });
108    this.buildingField.updateList($.map(buildings, function(building) { return {label: building.Street_Number, value: building.Street_Number }; }));
109    this.updateUnits();
110  };
111
112  AddressForm.prototype.updateUnits = function() {
113    /*jshint camelcase: false */
114    var buildingNum = this.buildingField.$element.val();
115    var building = $.map(this.buildingCache, function(cached) { return (cached.Street_Number === buildingNum) ? cached : null; });
116    if(!building.length) {
117      return;
118    }
119    var units = $.map(building[0].Unit, function(unit) {
120      return {label: unit.Unit_Number, value: unit.Unit_Number};
121    });
122    units = units.filter(function (unit) {
123      return parseInt(unit.label, 10) !== -1;
124    });
125
126    if(!units.length || parseInt(units[0].label, 10) === -1) {
127      this.$element.find('.form-item-unit-number').parent().addClass('hidden');
128    } else {
129      this.$element.find('.form-item-unit-number').parent().removeClass('hidden');
130    }
131    this.unitField.updateList(units);
132    this.unitField.clearInvalid();
133  };
134
135  AddressForm.prototype.nextField = function(event) {
136    if (event.keyCode === 13) {
137      var $this = $(event.target);
138      var index = parseFloat($this.attr('data-index'));
139      var $unFocusEl;
140      var $focusEl;
141
142      if(index === 1) {
143        $unFocusEl = this.streetField.$element;
144        $focusEl = this.buildingField.$element;
145        this.updateBuildings();
146      } else if(index === 2) {
147        $unFocusEl = this.buildingField.$element;
148        $focusEl = this.unitField.$element; 
149      } else {
150        $unFocusEl = this.unitField.$element;
151        $focusEl = this.$element.find('[data-index="' + (index + 1).toString() + '"]');
152      }
153
154      $unFocusEl.focusout();
155      $focusEl.focus();
156      if($focusEl.is(':visible')) {
157        event.preventDefault();
158      } else {
159        this.$page.val(index);
160        $unFocusEl.focus();
161        this.$element.submit();
162      }
163    }
164  };
165
166  $(function () {
167    if($('.address-search-form').length) {
168      var addressForm = new AddressForm('.address-search-form');
169      addressForm.initalize();
170    }
171  });
172
173  window.COS = {
174    Autocomplete: {
175      AutocompleteField: AutocompleteField,
176      AddressForm: AddressForm
177    }
178  };
179
180})(this, this.document, this.jQuery, this.wb, this.Drupal);

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.