Created
July 1, 2014 10:05
-
-
Save user20161119/049c4e685930e61a1552 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($) { | |
$.Address = { | |
Share: { | |
initialRegion: function () { | |
_initialRegion(); | |
}, | |
callback:function(){}, | |
geoGPSInfo: {}, | |
geoIPInfo: {} | |
}, | |
defaults: { | |
debug: false, | |
maxHeight: 0, | |
maxItem: 0, | |
platform: 'web', | |
isfilter:true, | |
limit:Number.MAX_VALUE, | |
autocompleteOption: { | |
minLength: 5, | |
}, | |
mapOption: { sensor: false, language: 'en', }, | |
callback: function () { }, | |
}, | |
onPhone:{ | |
remote: '' | |
}, | |
online: { | |
searchArea: true, | |
isExtend: true, | |
zeroCallback: function () { } | |
} | |
}; | |
//get geoip | |
//private fields | |
var googleGeocodeApiUrl = 'http://maps.googleapis.com/maps/api/geocode/json'; | |
var googleDistancematrixApiUrl = 'http://maps.googleapis.com/maps/api/distancematrix/json'; | |
//private method | |
var _geoCode = function (mapOption, getGeoCallback) { | |
if (!(mapOption && (mapOption.address || mapOption.latlng))) { | |
$.error('address or latlng is required.'); | |
} | |
$.getJSON(googleGeocodeApiUrl, mapOption, function (data) { | |
if (getGeoCallback != null){ | |
getGeoCallback(data.results, data.status); | |
} | |
}); | |
}; | |
var _getRegionByGPS = function () { | |
var timeout= 5000,isTimeout=false; | |
useIpGeo(); | |
if (window.navigator.geolocation){ | |
if ($.Address.Share.geoGPSInfo.region) { | |
$.Address.Share.callback.call(null, 'GPS', $.Address.Share.geoGPSInfo.latitude, $.Address.Share.geoGPSInfo.longitude);//call geolocation again | |
} | |
else { | |
setTimeout(function(){ | |
error_callback(); | |
},timeout); | |
navigator.geolocation.getCurrentPosition(success_callback, error_callback); | |
} | |
} | |
function useIpGeo(){ | |
var geoIPInfoInterval = window.setInterval(function () { | |
if (!$.Address.Share.geoIPInfo.region) { | |
if (window.geoip_region_name) { | |
$.Address.Share.geoIPInfo = { | |
region: geoip_region_name(), | |
latitude: geoip_latitude(), | |
longitude: geoip_longitude() | |
}; | |
} | |
} | |
else { | |
window.clearInterval(geoIPInfoInterval); | |
$.Address.Share.callback.call(null, 'IP',geoip_latitude(), geoip_longitude()); | |
} | |
}, 100); | |
}; | |
function success_callback(position) { | |
var tmpMapOption = {}; | |
$.extend(tmpMapOption, $.Address.defaults.mapOption, { latlng: position.coords.latitude + ',' + position.coords.longitude }); | |
$.Address.Share.callback.call(null, 'GPS',position.coords.latitude, position.coords.longitude); | |
_geoCode(tmpMapOption, function (results, status) { | |
if (status === 'OK') { | |
var addr, types, addrIndex, addrType, | |
levels, lvlIndex, lvladdr, lvlTypes, lvltype; | |
for (addrIndex in results) { | |
addr = results[addrIndex], | |
types = addr.types; | |
for (addrType in types) { | |
if (types[addrType] === 'locality') { | |
levels = addr.address_components; | |
for (lvlIndex in levels) { | |
lvladdr = levels[lvlIndex]; | |
lvlTypes = lvladdr.types; | |
for (lvltype in lvlTypes) { | |
if (lvlTypes[lvltype] === 'locality') { | |
$.Address.Share.geoGPSInfo = { | |
region: lvladdr.short_name | |
}; | |
$.extend($.Address.Share.geoGPSInfo, position.coords); | |
return; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
}); | |
}; | |
function error_callback(position) { | |
if(!isTimeout){ | |
isTimeout=true; | |
if (typeof geoip_city !== 'function') { | |
$.getScript("http://j.maxmind.com/app/geoip.js"); | |
} | |
} | |
}; | |
}; | |
var _initialRegion = function () { | |
_getRegionByGPS(); | |
}; | |
var _iniAutoComplate = function ($e, Option) { | |
var autoCompleteWrapper, autoComplete, uuid, | |
tmpOption = Option; | |
$e.autocomplete(tmpOption.autocompleteOption); | |
uuid = $('.ui-autocomplete:not(.auto-used)').attr('id'); | |
if (tmpOption.platform.toUpperCase() === 'MOBILE') { | |
if (iScroll) { | |
var maxheight = (+tmpOption.maxHeight) ? 'max-height:' + tmpOption.maxHeight + 'px' : ''; | |
$('.ui-autocomplete:not(.auto-used)') | |
.css('position', 'static') | |
.addClass('auto-used') | |
.wrap('<div id="wrapper-' + uuid + '" class="addresses-Wrapper" style="text-align: left;position:absolute;' + maxheight + '"/>') | |
.wrap('<div id="scroll-' + uuid + '"/>'); | |
autoComplete = $('#wrapper-' + uuid); | |
autoCompleteWrapper = new iScroll('wrapper-' + uuid, { | |
onBeforeScrollStart: function (e) { | |
var target = e.target; | |
while (target.nodeType != 1) target = target.parentNode; | |
if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') | |
e.preventDefault(); | |
} | |
}); | |
} | |
else { | |
$.error('iScroll plugin is required.'); | |
} | |
} | |
else { | |
if (+tmpOption.maxHeight) { | |
autoComplete = $('.ui-autocomplete:not(.auto-used)').css({ | |
'overflow-y': 'auto', | |
'text-align': 'left', | |
'max-height': +tmpOption.maxHeight + 'px' | |
}); | |
} | |
} | |
$($e).trigger('initialized', [autoComplete]); | |
return { | |
autoCompleteWrapper: autoCompleteWrapper | |
, autoComplete: autoComplete | |
}; | |
}; | |
//get Region | |
_initialRegion(); | |
// Constructor | |
var Address = function ($e, options) { | |
var _namespaces = 'jaddress', | |
_data = $e.data('jaddress'), | |
_userOptions = (typeof options === 'function') ? { callback: options } : options, | |
_addressOption = { | |
address: '' | |
, suite: '' | |
, street: '' | |
, city: '' | |
, state: '' | |
, country: '' | |
, zip: '' | |
, lat: NaN | |
, lng: NaN | |
}, | |
_$autoCompleteMenu, | |
_options = $.extend({}, $.Address.defaults,$.Address.online, _userOptions, _data || {}, { address: _addressOption },_iniMethod()), | |
_$element = $e; | |
$e.data('jaddress', $.extend({}, _data, { initialized: true, waiting: false }, _options)); | |
_load(); | |
function _load() { | |
_$autoCompleteMenu=_iniAutoComplate(_$element, _Data({ autocompleteOption: _getAutoComplateOption() })); | |
_$element.bind('keyup', function (e) { | |
if (_$element.val() !== _$element.data('jaddress').address.address) { | |
_iniAddress(); | |
} | |
}); | |
}; | |
function _Data(data) { | |
var tmpOption = _$element.data(_namespaces); | |
if (data) { | |
tmpOption = $.extend(true,tmpOption, data); | |
_$element.data(_namespaces, tmpOption); | |
} | |
return tmpOption; | |
}; | |
function _iniAddress() { | |
var tmpOption = _$element.data('jaddress'); | |
tmpOption.address = { | |
address: '' | |
, suite: '' | |
, street: '' | |
, city: '' | |
, state: '' | |
, country: '' | |
, zip: '' | |
, lat: NaN | |
, lng: NaN | |
}; | |
_$element | |
.data('jaddress', tmpOption) | |
.trigger('iniAddressed',[]); | |
return; | |
} | |
/*function _combinAddress(results, status) { | |
if (status === "OK") { | |
addressList = []; | |
for (var i in results) { | |
var address; | |
address = _analyzeAddress(results[i]); | |
if (!$.isEmptyObject(address)) { | |
addressList.push({ value: address.address,data:address}); | |
} | |
} | |
return addressList; | |
} | |
else {//if (data.status === 'ZERO_RESULTS') { | |
//zeroCallback(); | |
} | |
}*/ | |
// Private methods | |
function _combinAddress(mapOption, callback) { | |
callback = callback || function () { }; | |
_geoCode(mapOption, function (results,status) { | |
if (status === "OK") { | |
addressList = []; | |
for (var i in results) { | |
var address; | |
if(_Data().isfilter){ | |
address= _analyzeAddress(results[i]); | |
} | |
else{ | |
address= _directAddress(results[i]); | |
} | |
if (!$.isEmptyObject(address)&&addressList.length<=_Data().limit) { | |
addressList.push(address); | |
} | |
} | |
callback(addressList); | |
} | |
else {//if (data.status === 'ZERO_RESULTS') { | |
//zeroCallback(); | |
} | |
}); | |
}; | |
function _directAddress(googleAddress){ | |
return _formatAddress(googleAddress); | |
}; | |
function _formatAddress(googleAddress){ | |
var _address={}; | |
if (googleAddress.address_components != null && googleAddress.address_components.length > 0) { | |
for (var index in googleAddress.address_components) { | |
var val = googleAddress.address_components[index]; | |
if (val.types[0] == "street_number") { | |
//_address.suite = val.long_name; | |
_address.suite = val.short_name; | |
} else if (val.types[0] == "route") { | |
_address.street = val.long_name; | |
//_address.street = val.short_name; | |
} else if (val.types[0] == "neighborhood") { | |
//_address.street = val.long_name; | |
} else if (val.types[0] == "locality") { | |
_address.city = val.long_name; | |
//_address.city = val.short_name; | |
} else if (val.types[0] == "sublocality") { | |
_address.street = (_address.street&&(_address.street + ', ')||'') + val.long_name; | |
//_address.city = val.short_name; | |
} else if (val.types[0] == "administrative_area_level_1") { | |
//_address.state = val.long_name; | |
_address.state = val.short_name; | |
} else if (val.types[0] == "administrative_area_level_2") { | |
//_address.street = val.long_name; | |
} else if (val.types[0] == "administrative_area_level_3") { | |
//_address.street = val.long_name; | |
} else if (val.types[0] == "country") { | |
//_address.country = val.long_name; | |
_address.country = val.short_name; | |
} else if (val.types[0] == "postal_code") { | |
_address.zip = val.long_name; | |
} | |
} | |
_address.lat = googleAddress.geometry.location.lat; | |
_address.lng = googleAddress.geometry.location.lng; | |
_address.address = googleAddress.formatted_address;// _address.suite + ' ' + _address.street + ' ' + _address.city + ', ' + _address.state + ' ' + _address.zip; | |
} | |
return _address; | |
}; | |
function _analyzeAddress(googleAddress) { | |
var _address = {}; | |
var _analyzeAccurate = function (googleAddress) { | |
_address=_formatAddress(googleAddress); | |
}; | |
var _analyzeApproximate = function (googleAddress) { | |
if (googleAddress.types != null && googleAddress.types.length > 0) { | |
var isMatch = false; | |
for (index in googleAddress.types) { | |
if (googleAddress.types[index] == "subpremise" || | |
googleAddress.types[index] == "premise" || | |
googleAddress.types[index] == "street_address" || | |
googleAddress.types[index] == "route") { | |
isMatch = true; | |
} | |
} | |
if (isMatch) { | |
_address=_formatAddress(googleAddress); | |
} | |
} | |
}; | |
if (googleAddress) { | |
switch (googleAddress.geometry.location_type) { | |
case "ROOFTOP": | |
case "RANGE_INTERPOLATED": | |
case "GEOMETRIC_CENTER": | |
_analyzeAccurate(googleAddress); | |
break; | |
case "APPROXIMATE": | |
_analyzeApproximate(googleAddress); | |
break; | |
} | |
} | |
return _address; | |
}; | |
function _iniMethod(){ | |
return { | |
isValid: function () { | |
var _option = _$element.data('jaddress'), | |
tmpaddress = _option.address; | |
if (+tmpaddress.lat && +tmpaddress.lng && _$element.val() === tmpaddress.address) { | |
return true; | |
} | |
return false; | |
} | |
}; | |
} | |
function _refreshWrapper() { | |
_$autoCompleteMenu.autoCompleteWrapper && _$autoCompleteMenu.autoCompleteWrapper.refresh(); | |
}; | |
function _getAutoComplateOption() { | |
return { | |
source: function (request, response) { | |
var tmpOption = _$element.data('jaddress'), | |
tmpMapOption = {}, | |
addsearch = ''; | |
if (tmpOption.searchArea) { | |
addsearch = $.Address.Share.geoIPInfo.region || $.Address.Share.geoGPSInfo.region || ''; | |
} | |
$.extend(tmpMapOption, tmpOption.mapOption, { address: request.term + ' ' + addsearch }); | |
_combinAddress(tmpMapOption, function (data) { | |
var _renderAddress = function (data) { | |
if (+tmpOption.maxItem) { | |
data = data.slice(0, +tmpOption.maxItem); | |
} | |
response($.map(data, function (item) { | |
return { | |
label: item.address, | |
value: item.address, | |
address: item | |
}; | |
})); | |
_refreshWrapper(); | |
}; | |
if (data.length === 0 && addsearch && tmpOption.isExtend && tmpOption.searchArea) { | |
var tmpMapOption = {}; | |
$.extend(tmpMapOption, tmpOption.mapOption, { address: request.term }); | |
_combinAddress(tmpMapOption, function (data) { | |
_renderAddress(data); | |
}); | |
} else { | |
_renderAddress(data); | |
} | |
}); | |
}, | |
select: function (event, ui) { | |
var _option = _$element.data('jaddress'); | |
$.extend(_option.address, ui.item.address); | |
_$element.data('jaddress', _option); | |
_$element.val(ui.item.address.address); | |
if (_option.callback) { | |
_option.callback.call(_$element[0], ui.item.address); | |
} | |
}, | |
open: function () { | |
_iniAddress(); | |
//$(this).removeClass("ui-corner-all").addClass("ui-corner-top"); | |
} | |
}; | |
}; | |
// Remove the jaddress behavior and data from an element | |
function _destroy() { | |
return _$element.removeData('jaddress'); | |
} | |
// Safe console debug - http://klauzinski.com/javascript/safe-firebug-console-in-javascript | |
function _debug(m) { | |
if (_options.debug && typeof console === 'object' && (typeof m === 'object' || typeof console[m] === 'function')) { | |
if (typeof m === 'object') { | |
var args = []; | |
for (var sMethod in m) { | |
if (typeof console[sMethod] === 'function') { | |
args = (m[sMethod].length) ? m[sMethod] : [m[sMethod]]; | |
console[sMethod].apply(console, args); | |
} else { | |
console.log.apply(console, args); | |
} | |
} | |
} else { | |
console[m].apply(console, Array.prototype.slice.call(arguments, 1)); | |
} | |
} | |
} | |
// Expose API methods via the jQuery.jscroll namespace, e.g. $('sel').jscroll.method() | |
$.extend($e.jscroll, { | |
destroy: _destroy | |
}); | |
return $e; | |
}; | |
var Contact = function ($e, options) { | |
var _namespaces = 'jcontact', | |
_data = $e.data(_namespaces), | |
_userOptions = (typeof options === 'function') ? { callback: options } : options, | |
_contactOption = { | |
address: '' | |
, suite: '' | |
, street: '' | |
, city: '' | |
, state: '' | |
, country: '' | |
, zip: '' | |
, lat: NaN | |
, lng: NaN | |
, contact_name: '' | |
, contact_phone:'' | |
}, | |
_$autoCompleteMenu, | |
_options = $.extend({}, $.Address.defaults,$.Address.onPhone, _userOptions, _data || {}, { contact: _contactOption }, _iniMethod()), | |
_$contact = $e; | |
$e.data(_namespaces, $.extend({}, _data, { initialized: true, waiting: false }, _options)); | |
_load(); | |
function _iniMethod() { }; | |
function _iniContact() { | |
_contactOption = { | |
address: '' | |
, suite: '' | |
, street: '' | |
, city: '' | |
, state: '' | |
, country: '' | |
, zip: '' | |
, lat: NaN | |
, lng: NaN | |
, contact_name: '' | |
, contact_phone: '' | |
}, | |
_Data({ contact: _contactOption }); | |
_$contact.trigger('iniContacted', []); | |
return; | |
}; | |
function _load() { | |
_$autoCompleteMenu = _iniAutoComplate(_$contact, _Data({ autocompleteOption: _getAutoComplateOption() })); | |
_$contact.bind('keyup', function (e) { | |
if ($(this).val() !== _Data().contact.contact_phone) { | |
_iniContact(); | |
} | |
}); | |
}; | |
//@FIXME quick search address book janwen | |
function _getAutoComplateOption() { | |
return { | |
source: function (request, response) { | |
$.get(_Data().remote, { params: JSON.stringify({ phoneOrNameOrAddress: request.term }) }, function (data) { | |
if (data.status === 'SUCCESS') { | |
response($.map(data.data, function (item) { | |
return { | |
label: item.foramt_address, | |
value: item.foramt_address, | |
contact: item | |
}; | |
})); | |
_refreshWrapper(); | |
} | |
}); | |
}, | |
select: function (event, ui) { | |
var tmpOption=_Data({ contact: ui.item.contact }); | |
if (tmpOption.callback) { | |
tmpOption.callback.call(_$contact[0], ui.item.contact); | |
} | |
}, | |
open: function () { | |
_iniContact(); | |
//$(this).removeClass("ui-corner-all").addClass("ui-corner-top"); | |
}, | |
close: function () { | |
//var phone=_Data().contact.contact_phone; | |
//if(phone){ | |
// _$contact.val(phone); | |
//} | |
} | |
} | |
}; | |
function _Data(data) { | |
var tmpOption = _$contact.data(_namespaces); | |
if (data) { | |
tmpOption = $.extend(true, tmpOption, data); | |
_$contact.data(_namespaces, tmpOption); | |
} | |
return tmpOption; | |
}; | |
function _refreshWrapper() { | |
_$autoCompleteMenu.autoCompleteWrapper && _$autoCompleteMenu.autoCompleteWrapper.refresh(); | |
}; | |
}; | |
$.fn.address = function (option, m, params) { | |
if (typeof option === 'string') { | |
var $this = $(this), | |
data = $this && $this.data('jaddress'); | |
if (!data) { | |
$.error('address is not initialized.'); | |
} | |
result = data[option]; | |
if (m !== undefined) {//set | |
if ($.isPlainObject(result)) { | |
$.extend(result, m); | |
if (option === 'address') { | |
$this.val(result.address);//no check | |
} | |
} | |
else { | |
data[option] = m; | |
} | |
$this.data('jaddress', data); | |
} | |
else {//get | |
if(typeof result ==='function'){ | |
return result.call(this, params); | |
} | |
else{ | |
return result; | |
} | |
} | |
} | |
else { | |
m = option; | |
} | |
return this.each(function() { | |
var $this = $(this), | |
data = $this.data('jaddress'); | |
// Instantiate jScroll on this element if it hasn't been already | |
if (data && data.initialized) return; | |
var address = new Address($this, m); | |
}); | |
}; | |
$.fn.contact = function (option, m, params) { | |
if (typeof option === 'string') { | |
var $this = $(this), | |
data = $this && $this.data('jcontact'); | |
if (!data) { | |
$.error('contact is not initialized.'); | |
} | |
result = data[option]; | |
if (m !== undefined) {//set | |
if ($.isPlainObject(result)) { | |
$.extend(result, m); | |
} | |
else { | |
data[option] = m; | |
} | |
$this.data('jcontact', data); | |
} | |
else {//get | |
if (typeof result === 'function') { | |
return result.call(this, params); | |
} | |
else { | |
return result; | |
} | |
} | |
} | |
else { | |
m = option; | |
} | |
return this.each(function () { | |
var $this = $(this), | |
data = $this.data('jcontact'); | |
// Instantiate jScroll on this element if it hasn't been already | |
if (data && data.initialized) return; | |
var contact = new Contact($this, m); | |
}); | |
}; | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment