1/* A jQuery UI widget built on the top of jQuery UI autocomplete and Google place library */ 2(function($){ 3 $.widget("limosys.suggestbox", { 4 options: { 5 source:[], 6 placeSuggestService: null, 7 placeDetailService: null, 8 blockBlur:function(){return false;} 9 }, 10 _create: function(){ 11 var $acInput = this.element.clone().removeAttr("id").addClass("ac-input").val(""); 12 var removeBtn = $("<div></div>").html("x").addClass("ac-remove-btn"); 13 var $acItem = $("<div></div>").addClass("ac-item").append($("<div></div>").addClass("ac-label")).append(removeBtn).attr("tabindex", "0"); 14 var $wrapper = $("<div>").addClass("ac-wrapper").addClass(this.element.attr("class")).addClass("form-control"); 15 this.wrapper = $wrapper; 16 $acInput.appendTo($wrapper); 17 $acItem.appendTo($wrapper).hide().click(function(){ 18 $(this).focus(); 19 }); 20 this.acItem = $acItem; 21 $wrapper.insertAfter(this.element); 22 this.acInput = $acInput; 23 this.element.hide(); 24 var $acSearchIcon = $("<span>").attr("aria-hidden", "true").addClass("ac-search-icon").addClass("fa").addClass("fa-search"); 25 $acSearchIcon.insertBefore($acInput); 26 this.acSearchIcon = $acSearchIcon; 27 $acSearchIcon.show(); 28 var widget = this; 29 removeBtn.click(function(){ 30 widget.clear(); 31 }); 32 $acItem.keydown(function(e){ 33 if(e.which == $.ui.keyCode.BACKSPACE || e.which == $.ui.keyCode.DELETE){ 34 widget.clear(); 35 e.preventDefault(); 36 } 37 }); 38 this.wrapper.click(function(){ 39 if(widget.acItem.is(":visible")){ 40 widget.acItem.focus(); 41 } 42 }); 43 $acInput.autocomplete({ 44 source:function(request, response){ 45 var respondWithSuggestions = function(items) { 46 $.each(items || [], function(_, item) { 47 var suggestionText = item.description || item.label || item.value || ""; 48 item.description = suggestionText; 49 item.label = suggestionText; 50 item.value = suggestionText; 51 }); 52 response(items || []); 53 }; 54 var suggestCache = getSuggestCache(); 55 var responseData = suggestCache[request.term]; 56 if(responseData){ 57 respondWithSuggestions(responseData); 58 } else { 59 widget.acInput.userInput = request.term; 60 widget.options.placeSuggestService.getSuggestions(request.term, suggestCache, respondWithSuggestions); 61 } 62 }, 63 delay:300, 64 autoFocus: true, 65 select:function(event, ui) { 66 widget.options.placeDetailService.getPlaceDetail(ui.item, widget); 67 } 68 }); 69 $acInput.blur(function(){ 70 if(!widget.isSelected()){ 71 $(this).val(""); 72 } 73 }); 74 $acInput.data("ui-autocomplete")._renderMenu = function( ul, items ) { 75 var that = this; 76 $(ul).attr({ 77 role: "listbox", 78 "aria-label": "Address suggestions" 79 }); 80 $.each( items, function( index, item ) { 81 that._renderItemData( ul, item ); 82 }); 83 var logoClass = widget.options.placeSuggestService.getLogoClass(); 84 if (logoClass) { 85 $( ul ).append($("<li>").addClass(logoClass)); 86 } 87 }; 88 $acInput.data("ui-autocomplete")._renderItem = function( ul, item ) { 89 var suggestionText = item.description || item.label || item.value || ""; 90 var $link = $("<a>"); 91 92 if (item.imgUrl) { 93 $link.append($("<img>", { 94 src: item.imgUrl, 95 alt: "", 96 "aria-hidden": "true", 97 height: 15, 98 width: 15 99 }).css("margin-right", "10px")); 100 } 101 $link.append($("<span>").text(suggestionText)); 102 return $("<li>", { 103 "data-value": suggestionText, 104 role: "option", 105 "aria-label": suggestionText, 106 "aria-selected": "false" 107 }).append($link).appendTo(ul); 108 }; 109 110 //Intercept key down event to control enter key down behavior 111 var eventHandler = findEventHandlers("keydown", $acInput)[0]; 112 $acInput.unbind("keydown"); 113 $acInput.keydown(function(e){ 114 if(widget.acItem.is(":visible")) { 115 if(e.which == $.ui.keyCode.BACKSPACE || e.which == $.ui.keyCode.DELETE || e.which == $.ui.keyCode.ESCAPE){ 116 widget.clear(); 117 } 118 if(e.which == $.ui.keyCode.TAB){ 119 return true; 120 } 121 return false; 122 } 123 //for some reason, $acInput cannot be used here. Need to investigate javascript var scope 124 if(e.which == $.ui.keyCode.ENTER && (!($(this).autocomplete("widget").is(":visible")) || 125 $(this).autocomplete("widget").find(".ui-menu-item a.ui-state-active").length == 0 ) ){ 126 $(this).blur(); 127 return; 128 } 129 for(var i=0;i<eventHandler.events.length;i++){ 130 eventHandler.events[i].handler(e); 131 } 132 }); 133 $acInput.data("ui-autocomplete")._resizeMenu = function() { 134 var ul = this.menu.element; 135 ul.outerWidth(this.element.outerWidth()); 136 }; 137 this._resize(); 138 $(window).resize(function(){ 139 widget._resize(); 140 }); 141 //Initiate Widget 142 if(this.element.val()!=""){ 143 var label = this.element.data("label"); 144 var value = this.element.val(); 145 if(value && $.trim(value)!="" && label && $.trim(label)!=""){ 146 this.setItem({ 147 value:value, 148 label:label 149 }, false); 150 } else if(value && $.trim(value)!="" && typeof this.options.source == "object"){ 151 for(var i=0; i< this.options.source.length; i++){ 152 if(this.options.source[i].value == value){ 153 this.setItem(this.options.source[i], false); 154 } 155 } 156 }else{ 157 this.clear(); 158 } 159 } 160 }, 161 setItem: function(item, focusAfterSetItem){ 162 if(typeof focusAfterSetItem == "undefined") focusAfterSetItem = true; 163 this._resize(); 164 this.acItem.find(".ac-label").html(item.label).attr("title", item.label); 165 this.acInput.hide();//.css("position", "fixed").css("top", "-1000px"); 166 this.acSearchIcon.hide(); 167 this.acItem.show(); 168 //this.acInput.change(); 169 //if(focusAfterSetItem) this.acItem.focus(); 170 this.element.val(item.description); 171 this.element.data("label", item.label); 172 this._trigger("itemFilled"); 173 return $(this); 174 }, 175 clear: function(){ 176 this.acItem.hide(); 177 this.acInput.val("").show();//.css("position", "relative").css("top", "0"); 178 this.acInput.focus(); 179 this.acSearchIcon.show(); 180 this.acInput.val(""); 181 this.element.val(""); 182 this._trigger("itemCleared", null); 183 }, 184 isSelected: function(){ 185 return this.acItem.is(":visible"); 186 }, 187 getDisplayValue: function(){ 188 return this.acInput.val(); 189 }, 190 focusWidget: function(){ 191 this.acInput.focus(); 192 }, 193 blurWidget: function(){ 194 this.acInput.blur(); 195 }, 196 _resize: function(){ 197// this.wrapper.width(this.element.width()); 198 var boxWidth = this.acInput.outerWidth(true); 199 var safeMargin = 5; 200 var removeBtnWidth= this.acItem.find(".ac-remove-btn").outerWidth(); 201 this.acItem.find(".ac-label").css("max-width", (boxWidth - removeBtnWidth - safeMargin) + "px"); 202 var addrItemWidth = this.acItem.find(".ac-item").outerWidth(true); 203 this.acItem.find(".ac-cursor-container").css("width", boxWidth - addrItemWidth);
204 } 205 }); 206}(jQuery)); 207 208$._isMobile=function() { 209 var check = false; 210 (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera); 211 return check; 212}; 213 214var getSuggestCache = function(){ 215 var suggestCache = $("body").data("suggestCache"); 216 if(typeof suggestCache == "undefined"){ 217 suggestCache = {}; 218 $("body").data("suggestCache", suggestCache); 219 } 220 return suggestCache; 221}; 222 223var findEventHandlers = function (eventType, jqSelector) { 224 var results = []; 225 var $ = jQuery;// to avoid conflict between others frameworks like Mootools 226 227 var arrayIntersection = function (array1, array2) { 228 return $(array1).filter(function (index, element) { 229 return $.inArray(element, $(array2)) !== -1; 230 }); 231 }; 232 233 var haveCommonElements = function (array1, array2) { 234 return arrayIntersection(array1, array2).length !== 0; 235 }; 236 237 238 var addEventHandlerInfo = function (element, event, $elementsCovered) { 239 var extendedEvent = event; 240 if ($elementsCovered !== void 0 && $elementsCovered !== null) { 241 $.extend(extendedEvent, { targets: $elementsCovered.toArray() }); 242 } 243 var eventInfo; 244 var eventsInfo = $.grep(results, function (evInfo, index) { 245 return element === evInfo.element; 246 }); 247 248 if (eventsInfo.length === 0) { 249 eventInfo = { 250 element: element, 251 events: [extendedEvent] 252 }; 253 results.push(eventInfo); 254 } else { 255 eventInfo = eventsInfo[0]; 256 eventInfo.events.push(extendedEvent); 257 } 258 }; 259 260 261 var $elementsToWatch = $(jqSelector); 262 if (jqSelector === "*")//* does not include document and we might be interested in handlers registered there 263 $elementsToWatch = $elementsToWatch.add(document); 264 var $allElements = $("*").add(document); 265 266 $.each($allElements, function (elementIndex, element) { 267 var allElementEvents = $._data(element, "events"); 268 if (allElementEvents !== void 0 && allElementEvents[eventType] !== void 0) { 269 var eventContainer = allElementEvents[eventType]; 270 $.each(eventContainer, function(eventIndex, event){ 271 var isDelegateEvent = event.selector !== void 0 && event.selector !== null; 272 var $elementsCovered; 273 if (isDelegateEvent) { 274 $elementsCovered = $(event.selector, element); //only look at children of the element, since those are the only ones the handler covers 275 } else { 276 $elementsCovered = $(element); //just itself 277 } 278 if (haveCommonElements($elementsCovered, $elementsToWatch)) { 279 addEventHandlerInfo(element, event, $elementsCovered); 280 } 281 }); 282 } 283 });
284 return results; 285}; 286 287 288function Addr() { 289 this.streetNum = ""; 290 this.streetName = ""; 291 this.city = ""; 292 this.state = ""; 293 this.zip = ""; 294 this.lat = null; 295 this.lng = null; 296 this.airportCd = ""; 297 this.airlineCd = ""; 298 this.remark = ""; 299 this.types = []; 300 this.formattedAddress = ""; 301 this.areaCode = ""; 302 this.userInput = ""; 303 this.countryId = null; 304 this.placeId = ""; 305 this.placeDetailResponse= ""; 306 307 this.setLatLng = function (lat, lng) { 308 this.lat = lat ? Number(lat) : null; 309 this.lng = lng ? Number(lng) : null; 310 }; 311 312 this.setCountryId = function (countryId) { 313 this.countryId = countryId ? Number(countryId) : null; 314 } 315} 316 317 318function setAddr_FromPlaceService(placeResult, userInput) { 319 var addr = new Addr(); 320 addr.placeDetailResponse = placeResult; 321 addr.userInput = userInput; 322 return addr; 323} 324 325function setAddr_FromUserProfile(userAddr) { 326 var parsedAddress = new Addr(); 327 parsedAddress.streetNum = userAddr.data('street-num').toString(); 328 parsedAddress.streetName = userAddr.data('street-name'); 329 parsedAddress.city = userAddr.data('city'); 330 parsedAddress.areaCode = userAddr.data('areacd'); 331 parsedAddress.zip = userAddr.data('zip').toString(); 332 parsedAddress.setLatLng(userAddr.data('lat'), userAddr.data('lng')); 333 parsedAddress.setCountryId(userAddr.data('countryid')); 334 parsedAddress.remark = userAddr.data('remark'); 335 parsedAddress.types = ["street_address"]; 336 return parsedAddress; 337 338}
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.