天天看點

第三十四天 我為內建平台狂(七)-步履輕盈的JQuery(五)

           7月13日,晴。“别院深深夏席清,石榴開遍透簾明。 樹陰滿地日當午,夢覺流莺時一聲。”

      在JQuery的法則裡,風格重于一切,IT牛人們從來沒有把自己束縛在一張乏味的表單上,懷着對JavaScript的了解,在不斷的嘗試中尋求着轉化的靈感。    

      大多購票、旅遊網站上都提供了一個城市和日期輸入查詢的功能。使用者在輸入框中隻需輸入城市的拼音或者簡稱就可以彈出相關城市的名稱,選擇日期時則是出現一個月的月曆控件,隻需點選日期即可,整個操作一目了然。

      本文講解如何使用jQuery實作城市查詢和月曆顯示的整個流程,用到了jquery ui庫的datepicker插件來控制月曆以及輸入城市提示的插件。

第三十四天 我為內建平台狂(七)-步履輕盈的JQuery(五)

           1、index.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<meta name="keywords" content="jquery插件" />
		<meta name="description" content="CSS、jquery示例" />

		<title>示範:jQuery實作往返城市和日期查詢</title>

		<link rel="stylesheet" type="text/css" href="css/main.css" target="_blank" rel="external nofollow"  />
		<link rel="stylesheet" type="text/css" href="css/minor.css" target="_blank" rel="external nofollow"  />
		<link rel="stylesheet" type="text/css" href="css/jquery-ui.css" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  />

		<script type="text/javascript" src="js/jquery.js"></script>
		<!--
		<script type="text/javascript" src="js/jquery.validate.js"></script>
		<script src="js/jquery.validate.extends.js"></script>

		<script type="text/javascript" src="js/myValidate.js"></script>
		-->
		<script type="text/javascript" src="js/jquery-ui.js"></script>
		<script type="text/javascript" src="js/aircity.js"></script>
		<script type="text/javascript" src="js/j.suggest.js"></script>

		<script type="text/javascript" src="js/index.js"></script>

	</head>
	<body >
		<div id="header">
			<div id="logo">
				<h1><a href="http://blog.csdn.net/zwszws" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  title="傳回醉撈明月專欄">醉撈明月專欄</a></h1>
			</div>
		</div>

		<div id="main">
			<h2 class="top_title"><a href="http://blog.csdn.net/zwszws/article/details/37737043" target="_blank" rel="external nofollow" >jQuery實作往返城市和日期查詢</a></h2>
			<div class="demo">
				<form name="query" id="myform" action="#" method="post">
					<div class="qline">
						<label for="arrcity">出發城市:</label>
						<input type="text" name="arrcity" class="input" id="arrcity" />
						<div id='suggest' class="ac_results"> </div>
						<label for="city2">目的城市:</label>
						<input type="text" name="city2" class="input" id="city2" />
						<div id='suggest2' class="ac_results"> </div>
					</div>
					<div class="qline">
						<label for="startdate">出發日期:</label>
						<input type="text" name="startdate" class="input" id="startdate" />
						<label for="enddate">傳回日期:</label>
						<input type="text" name="enddate" class="required enddate" id="enddate" />
					</div>
				</form>
			</div>

		</div>

		<div id="footer">
			<p>
				Powered by blog.csdn.net/zwszws  允許轉載、修改和使用本部落格DEMO,但請注明出處:<a href="http://blog.csdn.net/zwszws" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >醉撈明月專欄</a>
			</p>
		</div>

	</body>
</html>
           

            本頁面分三部分,那就 定義三個id,分别是header,main,footer,代表腦袋、身體和腳丫。

             腦袋裡面又定義了一個id是logo;身體裡定義了 class為demo。

       設計城市和日期的輸入框,注意使用了div#suggest和div#suggest2兩個DIV是用來顯示城市清單的,預設CSS控制為不顯示。

     2、三個CSS

        其中minor.css如下,其餘見源代碼

.demo {
				width: 600px;
				margin: 60px auto
			}
			.input {
				border: 1px solid #999
			}
			.qline {
				line-height: 24px;
				margin: 10px
			}
			#suggest, #suggest2 {
				width: 200px;
			}
			.gray {
				color: gray;
			}
			.ac_results {
				background: #fff;
				border: 1px solid #7f9db9;
				position: absolute;
				z-index: 10000;
				display: none;
			}
			.ac_results ul {
				margin: 0;
				padding: 0;
				list-style: none;
			}
			.ac_results li a {
				white-space: nowrap;
				text-decoration: none;
				display: block;
				color: #05a;
				padding: 1px 3px;
			}
			.ac_results li {
				border: 1px solid #fff;
				line-height: 18px
			}
			.ac_over, .ac_results li a:hover {
				background: #c8e3fc;
			}
			.ac_results li a span {
				float: right;
			}
			.ac_result_tip {
				border-bottom: 1px dashed #666;
				padding: 3px;
			}
           

          上述樣式主要是控制城市查詢的外觀,而月曆控件的樣式我們單獨使用jquery ui的樣式:

<link rel="stylesheet" type="text/css" href="css/jquery-ui.css" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  />
           

          3、JQuery

       aircity.js以數組的形式儲存城市名稱等資料。如下

//初始化常用機場城市
var commoncitys=new Array();

commoncitys[0]=new Array('SZX','深圳','SHENZHEN','SZ');
 
commoncitys[1]=new Array('PEK','北京','BEIJING','BJ');
 
commoncitys[2]=new Array('SHA','上海','SHANGHAI','SH');
 
commoncitys[3]=new Array('CAN','廣州','GUANGZHOU','GZ');
 
commoncitys[4]=new Array('CTU','成都','CHENGDU','CD');
 
commoncitys[5]=new Array('HGH','杭州','HANGZHOU','HZ');
 
commoncitys[6]=new Array('CSX','長沙','CHANGSHA','CS');
 
commoncitys[7]=new Array('CKG','重慶','CHONGQING','CQ');
 
commoncitys[8]=new Array('KMG','昆明','KUNMING','KM');
 
commoncitys[9]=new Array('XIY','西安','XIAN','XA');
 
commoncitys[10]=new Array('WUH','武漢','WUHAN','WH');
 
commoncitys[11]=new Array('NKG','南京','NANJING','NJ');
 
commoncitys[12]=new Array('TAO','青島','QINGDAO','QD');
 
commoncitys[13]=new Array('SYX','三亞','SANYA','SY');
 
commoncitys[14]=new Array('XMN','廈門','XIAMEN','XM');
           

      j.suggest.js是控制輸入查詢城市,如下:

(function($) {

		$.suggest = function(input, options) {
	
			var $input = $(input).attr("autocomplete", "off");
			var $results;

			var timeout = false;		// hold timeout ID for suggestion results to appear	
			var prevLength = 0;			// last recorded length of $input.val()
			var cache = [];				// cache MRU list
			var cacheSize = 0;			// size of cache in chars (bytes?)
			
			if($.trim($input.val())=='' || $.trim($input.val())=='中文/拼音') $input.val('中文/拼音').css('color','#aaa');
			if( ! options.attachObject )
				options.attachObject = $(document.createElement("ul")).appendTo('body');

			$results = $(options.attachObject);
			$results.addClass(options.resultsClass);
			
			resetPosition();
			$(window)
				.load(resetPosition)		// just in case user is changing size of page while loading
				.resize(resetPosition);

			$input.blur(function() {
				setTimeout(function() { $results.hide() }, 200);
			});
			
			$input.focus(function(){
				if($.trim($(this).val())=='中文/拼音'){
					$(this).val('').css('color','#000');
				}
				if($.trim($(this).val())==''){
					displayItems('');//顯示熱門城市清單
				}
			});
			$input.click(function(){
				var q=$.trim($(this).val());
				displayItems(q);
				$(this).select();
			});
						
			// help IE users if possible
			try {
				$results.bgiframe();
			} catch(e) { }

			$input.keyup(processKey);//
			
			function resetPosition() {
				// requires jquery.dimension plugin
				var offset = $input.offset();
				$results.css({
					top: (offset.top + input.offsetHeight) + 'px',
					left: offset.left + 'px'
				});
			}
			
			
			function processKey(e) {
				
				// handling up/down/escape requires results to be visible
				// handling enter/tab requires that AND a result to be selected
				if ((/27$|38$|40$/.test(e.keyCode) && $results.is(':visible')) ||
					(/^13$|^9$/.test(e.keyCode) && getCurrentResult())) {
		            
		            if (e.preventDefault)
		                e.preventDefault();
					if (e.stopPropagation)
		                e.stopPropagation();

	                e.cancelBubble = true;
	                e.returnValue = false;
				
					switch(e.keyCode) {
	
						case 38: // up
							prevResult();
							break;
				
						case 40: // down
							nextResult();
							break;
						case 13: // return
							selectCurrentResult();
							break;
							
						case 27: //	escape
							$results.hide();
							break;
	
					}
					
				} else if ($input.val().length != prevLength) {

					if (timeout) 
						clearTimeout(timeout);
					timeout = setTimeout(suggest, options.delay);
					prevLength = $input.val().length;
					
				}			
					
				
			}
			
			function suggest() {
			
				var q = $.trim($input.val());
				displayItems(q);
			}		
			function displayItems(items) {
				var html = '';
				if (items=='') {//熱門城市周遊
					for(h in options.hot_list){
						html+='<li rel="'+options.hot_list[h][0]+'"><a href="#'+h+'" target="_blank" rel="external nofollow" ><span>'+options.hot_list[h][2]+'</span>'+options.hot_list[h][1]+'</a></li>';
					}
					html='<div class="gray ac_result_tip">請輸入中文/拼音或者↑↓選擇</div><ul>'+html+'</ul>';
				}
				else {
					/*if (!items)
					return;
					if (!items.length) {
						$results.hide();
						return;
					}*/
					for (var i = 0; i < options.source.length; i++) {//國内城市比對
						var reg = new RegExp('^' + items + '.*$', 'im');
						if (reg.test(options.source[i][0]) || reg.test(options.source[i][1]) || reg.test(options.source[i][2]) || reg.test(options.source[i][3])) {
							html += '<li rel="' + options.source[i][0] + '"><a href="#' + i + '" target="_blank" rel="external nofollow" ><span>' + options.source[i][2] + '</span>' + options.source[i][1] + '</a></li>';
						}
					}
					if (html == '') {
						suggest_tip = '<div class="gray ac_result_tip">對不起,找不到:' + items + '</div>';
					}
					else {
						suggest_tip = '<div class="gray ac_result_tip">' + items + ',按拼音排序</div>';
					}
					html = suggest_tip + '<ul>' + html + '</ul>';
				}

				$results.html(html).show();
				$results.children('ul').children('li:first-child').addClass(options.selectClass);
				
				$results.children('ul')
					.children('li')
					.mouseover(function() {
						$results.children('ul').children('li').removeClass(options.selectClass);
						$(this).addClass(options.selectClass);
					})
					.click(function(e) {
						e.preventDefault(); 
						e.stopPropagation();
						selectCurrentResult();
					});
			}
						
			function getCurrentResult() {
			
				if (!$results.is(':visible'))
					return false;
			
				var $currentResult = $results.children('ul').children('li.' + options.selectClass);
				if (!$currentResult.length)
					$currentResult = false;
					
				return $currentResult;

			}
			
			function selectCurrentResult() {
			
				$currentResult = getCurrentResult();
			
				if ($currentResult) {
					$input.val($currentResult.children('a').html().replace(/<span>.+?<\/span>/i,''));
					$results.hide();

					if( $(options.dataContainer) ) {
						$(options.dataContainer).val($currentResult.attr('rel'));
					}
	
					if (options.onSelect) {
						options.onSelect.apply($input[0]);
					}
				}
			
			}
			
			function nextResult() {
			
				$currentResult = getCurrentResult();
			
				if ($currentResult)
					$currentResult
						.removeClass(options.selectClass)
						.next()
							.addClass(options.selectClass);
				else
					$results.children('ul').children('li:first-child').addClass(options.selectClass);
			
			}
			
			function prevResult() {
			
				$currentResult = getCurrentResult();
			
				if ($currentResult)
					$currentResult
						.removeClass(options.selectClass)
						.prev()
							.addClass(options.selectClass);
				else
					$results.children('ul').children('li:last-child').addClass(options.selectClass);
			
			}
	
		}
		
		$.fn.suggest = function(source, options) {
		
			if (!source)
				return;
		
			options = options || {};
			options.source = source;
			options.hot_list=options.hot_list || [];
			options.delay = options.delay || 0;
			options.resultsClass = options.resultsClass || 'ac_results';
			options.selectClass = options.selectClass || 'ac_over';
			options.matchClass = options.matchClass || 'ac_match';
			options.minchars = options.minchars || 1;
			options.delimiter = options.delimiter || '\n';
			options.onSelect = options.onSelect || false;
			options.dataDelimiter = options.dataDelimiter || '\t';
			options.dataContainer = options.dataContainer || '#SuggestResult';
			options.attachObject = options.attachObject || null;
	
			this.each(function() {
				new $.suggest(this, options);
			});
	
			return this;
			
		};
		
	})(jQuery);
           

               主要看下頁面使用的jQuery----index.js

$(function(){
	$("#arrcity").suggest(citys,{
		hot_list:commoncitys,
		attachObject:'#suggest'
	});
	$("#city2").suggest(citys,{
		hot_list:commoncitys,
		attachObject:"#suggest2"
	});
	today=new Date();
        var year = today.getFullYear();
        var month = today.getMonth();
        var day = today.getDate();
	$("#startdate,#enddate").css("color","#aaa").attr("value","yyyy-mm-dd");
	$("#startdate,#enddate").datepicker({
		minDate: new Date(year, month, day+1),
		numberOfMonths: 1,
		onClose:function(){
			$(this).css("color","#000");
		}
	});
});
           

       上述代碼實作了輸入查詢城市,調用城市資料的功能。hot_list:commoncitys是指初始的熱門城市,attachObject:"#suggest"是設定輸入時關聯的顯示城市清單的DIV。

       接下來要加入控制月曆的代碼。

       我們需要控制月曆的有效日期,即顯示目前日期,在目前日期前的日期都不能選中,因為你不可能選擇已經過去的日期作為出發日期。

           代碼首先擷取了目前日期(即今天),然後初始日期輸入框的内容和樣式,再調用detepicker插件,設定最小日期為目前日期,設定numberOfMonths為連續的一個月,此外當選擇日期後,調用函數将輸入框的樣式改變。将以上代碼追加到城市輸入查詢代碼的後面即可。還有就是要顯示連續的兩個月的月曆時,把numberOfMonths: 1 改為numberOfMonths: 2。

       到此,城市和日期選擇功能已經實作。

第三十四天 我為內建平台狂(七)-步履輕盈的JQuery(五)

       本文未涉及到日期的驗證,如傳回日期不能小于出發日期,這個需要做怎麼樣的修改呢?

第三十四天 我為內建平台狂(七)-步履輕盈的JQuery(五)

       可以,使用自定義驗證方法(addMethod:name, method, message)寫了一個日期驗證,如下:

// 起始大于傳回日期驗證
	jQuery.validator.addMethod("enddate", function(value, element) {
        var startDate = $('#startdate').val();
        return new Date(Date.parse(startDate.replace("-", "/"))) < new Date(Date.parse(value.replace("-", "/")));
    },
    "結束日期必須大于開始日期!");
           

       這個方法的缺點是文字提示不美觀,還是想一想别的方法

第三十四天 我為內建平台狂(七)-步履輕盈的JQuery(五)
第三十四天 我為內建平台狂(七)-步履輕盈的JQuery(五)

     最終,修改如下:

$(function() {
	$("#arrcity").suggest(citys, {
				hot_list : commoncitys,
				attachObject : '#suggest'
			});
	$("#city2").suggest(citys, {
				hot_list : commoncitys,
				attachObject : "#suggest2"
			});
	today = new Date();
	var year = today.getFullYear();
	var month = today.getMonth();
	var day = today.getDate();
	
	$("#startdate,#enddate").css("color", "#aaa").attr("value", "yyyy-mm-dd");

	$("#startdate").datepicker({
					minDate : new Date(year, month, day + 1),
					numberOfMonths : 1,
					onClose : function() {
						$(this).css("color", "#000");
					}
				});

	$('#startdate').change(function() {
					$('#enddate').val(getDateAfter($('#startdate').val(), 2));
					year = document.getElementById('startdate').value
							.substring(0, 4);
					
					month = document.getElementById('startdate').value
							.substring(5, 7);
					month = month - 1;
					
					day = document.getElementById('startdate').value.substring(
							8, 10);
					

				});
	

	// $('#enddate').click(function() {
	document.getElementById('enddate').onclick = function() {
		
		$("#enddate").datepicker({
					minDate : new Date(year, month, day),
					numberOfMonths : 1,
					onClose : function() {
						$(this).css("color", "#000");
					}
				});		
	};
		// });

	});

function getDateAfter(theDate, n) {
	var d = StringToDate(theDate);
	var dateStr = d.getFullYear() + '-';
	d.setDate(d.getDate() + n);
	if ((d.getFullYear() + 1) < 10) {
		dateStr = dateStr + "0";
	}
	dateStr = d.getFullYear() + "-";

	if ((d.getMonth() + 1) < 10) {
		dateStr = dateStr + "0";
	}
	dateStr = dateStr + (d.getMonth() + 1) + "-";
	if ((d.getDate()) < 10) {
		dateStr = dateStr + "0";
	}
	dateStr = dateStr + d.getDate();
	return dateStr;
}

function StringToDate(DateStr) {
	var converted = Date.parse(DateStr);
	var myDate = new Date(converted);
	if (isNaN(myDate)) {
		var arys = DateStr.split('-');
		myDate = new Date(arys[0], --arys[1], arys[2]);
	}
	return myDate;
}
           

      效果如下:

第三十四天 我為內建平台狂(七)-步履輕盈的JQuery(五)

             本文 源代碼下載下傳:http://download.csdn.net/detail/zwszws/7630417

繼續閱讀