完整中英文世界國家級聯下拉列表插件【前端版】

這個小東西是以前小項目上臨時增長功能的產物,那時候在網上找了好久都沒有能用的插件,要麼是數據殘缺乏得可憐,還有就是實現手段很是低效不可維護那種,各類奇拔問題!反正就沒有逞心如意!那時候又急須要這樣一個功能,百般無奈後靈機一動,想起某企鵝功能選項不是有這樣的世界國家級聯功能嚒!那確定有地方存着這數據的哇!嘿嘿!內心忽然暗喜,終於有方向,而後就是向這企鵝開刀找!在某個i18n國際化文件夾中找到了!立馬放下心頭大石!php

 

這樣子中英文版本的數據都有了!可是問題又來了!該怎麼開始作呢?css

怎麼去調用這個數據呢?html

想法一:把數據拆分出來導入數據庫,而後Ajax級聯獲取數據前端

想法二:把數據轉換成熟悉的格式,在前端獲取後遞歸拆分jquery

想法三:直接利用jquery讀取xml而後捉取數據(這是完成這插件後好久回頭想到!逼於屌絲項目時間趕沒多考慮的結果)數據庫

後來我是選擇了第二種方案,轉換成json對象,在前端遞歸獲取數據;json

其實這個方案也是不錯的!JS對象屬性查找效率是很是不錯的!數組

那這個方案要怎麼轉換成又方便又簡單的數組數據呢?又地讓國家、省份、城市、區級之間又有關聯app

那時候是直接用元素名做爲keyName關聯;框架

其實那時候具體過程已經忘記了,直接貼那時候PHP的代碼,

<?php

	$file = dirname(__FILE__).'/LocList_en.xml';
	$obj  = simplexml_load_file($file);
	
	$CountryArr = array();
	$StateArr   = array();
	$CityArr    = array();
	$RegionArr  = array();
	
	$cCode = 1; $cState = 1; $cCity = 1; $cRegion = 1;
	
	foreach ( $obj as $CountryRegion ) {
		
		$CountryArr[] = array('Name'=>(string)$CountryRegion['Name'],'Code'=>'c'.$cCode);
		
		foreach ( $CountryRegion as $State ) {
			
			if(!empty($State['Name']))
			{
				$StateArr['c'.$cCode][] = array('Name'=>(string)$State['Name'],'Code'=>'s'.$cState);
			}
			
			foreach ( $State as $City ) {
				
				if(!empty($City['Name']))
				{
					if(!empty($State['Code']))
						$CityArr['s'.$cState][] = array('Name'=>(string)$City['Name'],'Code'=>'c'.$cCity);
					else
						$CityArr['c'.$cCode][] = array('Name'=>(string)$City['Name'],'Code'=>'c'.$cCity);
				}
				
				foreach ( $City as $Region ) {
					
					if(!empty($Region['Name']))
					{
						if(!empty($City['Code']))
							$RegionArr['c'.$cCity][] = array('Name'=>(string)$Region['Name'],'Code'=>'r'.$cRegion);
					}
					#縣級代碼
					$cRegion++;
				}
				#城市代碼
				$cCity++;	
			}
			#省份代碼
			$cState++;
		}
		#國家代碼
		$cCode++;
	}
	//echo '<pre>';print_r(array('country'=>$CountryArr,'state'=>$StateArr,'city'=>$CityArr,'region'=>$RegionArr));exit;
	echo(json_encode(array('country'=>$CountryArr,'state'=>$StateArr,'city'=>$CityArr,'region'=>$RegionArr)));exit;
?>

JSON數據的樣子

接着就是前段JS的編寫!礙於當時沒多少時間去寫!代碼很是糟糕!哎!算是一個工程版!

用jquery框架輔助!開發效率十分高!執行效率也還行!就是須要加載完整的地理數據稍稍慢!320kb的數據還能接受吧!對於客戶突來的需求!

(function($){
	$.fn.extend({
		GlobalGeography:function(){
			
			/* ._GlobalGeography_ { width:282px; height:30px !important; position:relative; left:-282px; top:2px; } */
			
			var relatedObj = ['div[id="country"]','div[id="state"]','div[id="city"]','div[id="region"]'];
			var excludeObj = ['div[id="region"]'];	
			var selectmenu = ['country','state','city','region'];
			var selector   = this.selector;
			
			/*輸出下拉列表*/
			function _traversal(source,type){
				if(typeof(source)!='undefined'){
					var _select_  = '<select class="_GlobalGeography_">';
						_select_ += '<option value=""></option>';
					$.each(source,function(i,v){
						_select_ += '<option value="'+v.Code+'">'+v.Name+'</option>';
					});
					_select_ += '</select>';
					return _select_;
				}
				return false;
			};
			
			/*清除/還原下級關聯下拉菜單*/
			function cleanNextMenu(index){
				for(var i=index;i<relatedObj.length;i++){
					if(typeof(relatedObj[(i+1)])!='undefined'){
						$(relatedObj[(i+1)]).find('._GlobalGeography_').remove();
						$(relatedObj[(i+1)]).find('input').val('');
					}
				}
			}
			
			/*遍歷獲取下拉菜單內容*/
			function checkMenu(json){
				/*遍歷賦值全部類型*/
				$.each(relatedObj,function(i,v){
					if($.inArray(v,excludeObj)==-1){
						$(v).find('select').bind('change',function(){
							var _code_ = $(this).val(); cleanNextMenu(i);
							if(typeof(json[selectmenu[(i+1)]][_code_])!='undefined'){
								$(relatedObj[(i+1)]).append(_traversal(json[selectmenu[(i+1)]][_code_],selectmenu[(i+1)]));
								/*綁定方法*/
								$(relatedObj[(i+1)]).find('._GlobalGeography_').bind('change',function(){
									$(relatedObj[(i+1)]).find('input').val($(this).find('option:selected').text());
								});
								checkMenu(json);
							} else {
								$(relatedObj[(i+2)]).append(_traversal(json[selectmenu[(i+2)]][_code_]));
								/*綁定方法*/
								$(relatedObj[(i+2)]).find('._GlobalGeography_').bind('change',function(){
									$(relatedObj[(i+2)]).find('input').val($(this).find('option:selected').text());
								});
							}
						});
					}
				});
			}
			
			/*加載世界國家城市數據*/
			$.getJSON("db_en.dat",function(json){
				/*輸出國家列表*/
				$(selector).append(_traversal(json.country,'country'));
				$(selector).find('._GlobalGeography_').bind('change',function(){
					$(selector).find('input').val($(this).find('option:selected').text());
				});
				checkMenu(json);
			});
		}
	})
})(jQuery);

html代碼

<!DOCTYPE>
<html>
	<head>
		<meta charset="utf-8">
		<script src="jquery.js"></script>
		<script src="country_noinv.js"></script>
		<style type="text/css">
			._GlobalGeography_ { width:200px; }
		</style>
	</head>
	<body>
		<div id="country"></div>
		<div id="state"></div>
		<div id="city"></div>
		<div id="region"></div>
	</body>
</html>
<script>
$(document).ready(function(){
	$('#country').GlobalGeography();
});
</script>

執行效果,這裏有一個問題,就是英文版只去到城市就沒了!因此數據包大小也減半隻有148kb

//這裏主要是用了非入侵方式,數組元素分別對應selectmenu
var relatedObj = ['div[id="country"]','div[id="state"]','div[id="city"]','div[id="region"]'];
//這裏主要控制級聯到哪一個級別就再也不繼續執行
var excludeObj = ['div[id="region"]'];
var selectmenu = ['country','state','city','region'];

這個小東西是拋磚引玉了!實現手段並不高效!代碼有不少地方能夠改進!

整理代碼時候翻出來,但願能幫助到有須要的人!

相關文章
相關標籤/搜索