/**
* jquery.jpostal.js ver2.7
*
* Copyright 2014, Aoki Makoto, Ninton G.K. http://www.ninton.co.jp
*
* Released under the MIT license - http://en.wikipedia.org/wiki/MIT_License
*
* Requirements
* jquery.js
*/
function JpostalDatabase ( i_options ) {
this.address = []; // database cache
this.map = {
};
this.url = {
'http' : '//jpostal-1006.appspot.com/json/',
'https' : '//jpostal-1006.appspot.com/json/'
};
this.find = function ( i_postcode ) {
var address = [];
for ( var i = 0; i < this.address.length; ++i ) {
if ( this.address[i][0] == '_' + i_postcode ) {
address = this.address[i];
}
}
return address;
};
this.get = function ( i_postcode ) {
// --------------------------------------------------
// i_postcode find() find() result
// 1234567 123
// --------------------------------------------------
// 1 - - defaults
// 12 - - defaults
// 123 - Y find( '123' )
// 123 - N defaults
// 1234 - Y find( '123' )
// 1234 - N defaults
// 1234567 Y - find( '1234567' )
// 1234567 N Y find( '123' )
// 1234567 N N defaults
// --------------------------------------------------
var defaults = ['', '', '', '', '', '', '', '', ''];
var address;
var head3;
switch ( i_postcode.length ) {
case 3:
case 4:
case 5:
case 6:
head3 = i_postcode.substr(0, 3);
address = this.find(head3);
address = $.extend( defaults, address );
break;
case 7:
address = this.find(i_postcode);
if ( !address ) {
head3 = i_postcode.substr(0, 3);
address = this.find(head3);
}
address = $.extend( defaults, address );
break;
default:
address = defaults;
break;
}
return address;
};
this.getUrl = function ( i_head3 ) {
var url = '';
switch ( window.location.protocol ) {
case 'http:':
url = this.url['http'];
break;
case 'https:':
url = this.url['https'];
break;
}
url = url + i_head3 + '.json';
return url;
};
this.request = function ( i_postcode, i_callback ) {
var _this = this;
var head3 = i_postcode.substr(0, 3);
if ( i_postcode.length <= 2 || this.getStatus(head3) != 'none' || head3.match(/[^0-9]/) ) {
return false;
}
this.setStatus(head3, 'waiting');
var url = this.getUrl( head3 );
var options = {
async : false,
dataType : 'jsonp',
jsonpCallback : 'jQuery_jpostal_callback',
type : 'GET',
url : url,
success : function(i_data, i_dataType) {
i_callback();
},
error : function(i_XMLHttpRequest, i_textStatus, i_errorThrown) {
},
timeout : 5000 // msec
};
$.ajax( options );
return true;
};
this.save = function ( i_data ) {
for ( var i = 0; i < i_data.length; ++i ) {
var rcd = i_data[i];
var postcode = rcd[0];
if ( typeof this.map[postcode] == 'undefined' ) {
this.address.push( rcd );
this.map[postcode] = {state : 'complete', time : 0};
} else if ( this.map[postcode].state == 'waiting' ) {
this.address.push( rcd );
this.map[postcode].state = 'complete';
}
}
};
this.getStatus = function ( i_postcode ) {
// --------------------------------------------------
// # ['_001'] ..state .time result
// --------------------------------------------------
// 1 =undefined - - none
// 2 !=undefined 'complete' - complete
// 3 !=undefined 'waiting' <5sec waiting
// 4 !=undefined 'waiting' >=5sec none
// --------------------------------------------------
var st = '';
var postcode = '_' + i_postcode;
if ( typeof this.map[postcode] == 'undefined' ) {
// # 1
st = 'none';
} else if ( 'complete' == this.map[postcode].state ) {
// # 2
st = 'complete';
} else {
var t_ms = (new Date()).getTime() - this.map[postcode].time;
if ( t_ms < 5000 ) {
// # 3
st = 'waiting';
} else {
// # 4
st = 'none';
}
}
return st;
};
this.setStatus = function ( i_postcode ) {
var postcode = '_' + i_postcode;
if ( typeof this.map[postcode] == 'undefined' ) {
this.map[postcode] = {
state : 'waiting',
time : 0
};
}
this.map[postcode].time = (new Date()).getTime();
};
}
function Jpostal ( i_JposDb ) {
this.address = '';
this.jposDb = i_JposDb;
this.options = {};
this.postcode = '';
this.minLen = 3;
this.displayAddress = function () {
if ( this.postcode == '000info') {
this.address[2] += ' ' + this.getScriptSrc();
}
for ( var key in this.options.address ) {
var s = this.formatAddress( this.options.address[key], this.address );
if ( this.isSelectTagForPrefecture( key, this.options.address[key] ) ) {
this.setSelectTagForPrefecture( key, s );
} else {
$(key).val( s );
}
}
};
this.isSelectTagForPrefecture = function( i_key, i_fmt ) {
// 都道府県のSELECTタグか?
switch ( i_fmt ) {
case '%3':
case '%p':
case '%prefecture':
if ( $(i_key).get(0).tagName.toUpperCase() == 'SELECT' ) {
f = true;
} else {
f = false;
}
break;
default:
f = false;
break;
}
return f;
}
this.setSelectTagForPrefecture = function ( i_key, i_value ) {
// 都道府県のSELECTタグ
// ケース1:
$(i_key).val(i_value);
if ( $(i_key).val() == i_value ) {
return;
}
// ケース2: valueが数値(自治体コードの場合が多い)
// テキストが「北海道」を含むかどうかで判断する
//
//
value = '';
var el = $(i_key)[0];
for ( var i = 0; i < el.options.length; ++i ) {
var p = el.options[i].text.indexOf( i_value );
if ( 0 <= p ) {
value = el.options[i].value;
break;
}
}
if ( value != '' ) {
$(i_key).val( value );
}
}
this.formatAddress = function ( i_fmt, i_address ) {
var s = i_fmt;
s = s.replace( /%3|%p|%prefecture/, i_address[1] );
s = s.replace( /%4|%c|%city/ , i_address[2] );
s = s.replace( /%5|%t|%town/ , i_address[3] );
s = s.replace( /%6|%a|%address/ , i_address[4] );
s = s.replace( /%7|%n|%name/ , i_address[5] );
s = s.replace( /%8/ , i_address[6] );
s = s.replace( /%9/ , i_address[7] );
s = s.replace( /%10/ , i_address[8] );
return s;
};
this.getScriptSrc = function () {
var src = '';
var el_arr = document.getElementsByTagName('script');
for ( var i = 0; i < el_arr.length; ++i ) {
if ( 0 <= el_arr[i].src.search(/jquery.jpostal.js/) ) {
src = el_arr[i].src;
}
}
return src;
}
this.init = function ( i_options ) {
if ( typeof i_options.postcode == 'undefined' ) {
throw new Error('postcode undefined');
}
if ( typeof i_options.address == 'undefined' ) {
throw new Error('address undefined');
}
this.options.postcode = [];
if ( typeof i_options.postcode == 'string' ) {
this.options.postcode.push( i_options.postcode );
} else {
this.options.postcode = i_options.postcode;
}
this.options.address = i_options.address;
if ( typeof i_options.url != 'undefined' ) {
this.jposDb.url = i_options.url;
}
};
this.main = function () {
this.scanPostcode();
if ( this.postcode.length < this.minLen ) {
// git hub issue #4: 郵便番号欄が0~2文字のとき、住所欄を空欄にせず、入力内容を維持してほしい
return ;
}
var _this = this;
var f = this.jposDb.request( this.postcode, function () {
_this.callback();
});
if ( !f ) {
this.callback();
}
};
this.callback = function () {
this.address = this.jposDb.get( this.postcode );
this.displayAddress();
};
this.scanPostcode = function () {
var s = '';
switch ( this.options.postcode.length ) {
case 0:
break;
case 1:
// github issue #8: 1つ目を空欄、2つ目を「001」としても、「001」として北海道札幌市を表示してしまう
// ----------------------------------------
// case postcode result
// ----------------------------------------
// 1 '' ''
// 1 12 ''
// 2 123 123
// 2 123- 123
// 2 123-4 123
// 3 123-4567 1234567
// 2 1234 123
// 4 1234567 1234567
// ----------------------------------------
s = String($(this.options.postcode[0]).val());
if ( 0 <= s.search(/^([0-9]{3})([0-9A-Za-z]{4})/) ) {
// case 4
s = RegExp.$1 + '' + RegExp.$2;
} else if ( 0 <= s.search(/^([0-9]{3})-([0-9A-Za-z]{4})/) ) {
// case 3
s = RegExp.$1 + '' + RegExp.$2;
} else if ( 0 <= s.search(/^([0-9]{3})/) ) {
// case 2
s = RegExp.$1;
} else {
// case 1
s = '';
}
break;
case 2:
// github issue #8: 1つ目を空欄、2つ目を「001」としても、「001」として北海道札幌市を表示してしまう
// ----------------------------------------
// case post1 post2 result
// ----------------------------------------
// 1 '' --- ''
// 1 12 --- ''
// 2 123 '' 123
// 2 123 4 123
// 3 123 4567 1234567
// ----------------------------------------
var s3 = String($(this.options.postcode[0]).val());
var s4 = String($(this.options.postcode[1]).val());
if ( 0 <= s3.search(/^[0-9]{3}$/) ) {
if ( 0 <= s4.search(/^[0-9A-Za-z]{4}$/) ) {
// case 3
s = s3 + s4;
} else {
// case 2
s = s3;
}
} else {
// case 1
s = '';
}
break;
}
this.postcode = s;
};
}
// MEMO: For the following reason, JposDb was put on the global scope, not local scope.
// ---------------------------------------------------------------------
// data file callback JposDb scope
// ---------------------------------------------------------------------
// 001.js JposDb.save global scope
// 001.js.php $_GET['callback'] local scopde for function($){}
// ---------------------------------------------------------------------
var JposDb = new JpostalDatabase();
function jQuery_jpostal_callback( i_data ) {
JposDb.save( i_data );
}
(function($) {
$.fn.jpostal = function( i_options ){
var Jpos = new Jpostal( JposDb );
Jpos.init( i_options );
if ( typeof i_options.click == 'string' && i_options.click != '' ) {
$(i_options.click).bind('click', function(e) {
Jpos.main();
});
} else {
for ( var i = 0; i < Jpos.options.postcode.length; ++i ) {
var selector = Jpos.options.postcode[i];
$(selector).bind('keyup change', function(e) {
Jpos.main();
});
}
}
};
})(jQuery);