第三十四天 我为集成平台狂(七)-步履轻盈的JQuery(五)

           7月13日,晴。别院深深夏席清,石榴开遍透帘明。 树阴满地日当午,梦觉流莺时一声。

      在JQuery的法则里,风格重于一切,IT牛人们从来没有把自己束缚在一张乏味的表单上,怀着对JavaScript的理解,在不断的尝试中寻求着转化的灵感。    

      大多购票、旅游网站上都提供了一个城市和日期输入查询的功能。用户在输入框中只需输入城市的拼音或者简称就可以弹出相关城市的名称,选择日期时则是出现一个月的日历控件,只需点选日期即可,整个操作一目了然。

      本文讲解如何使用jQuery实现城市查询和日历显示的整个流程,用到了jquery ui库的datepicker插件来控制日历以及输入城市提示的插件。

     

           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" />
		<link rel="stylesheet" type="text/css" href="css/minor.css" />
		<link rel="stylesheet" type="text/css" href="css/jquery-ui.css" />

		<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" title="返回醉捞明月专栏">醉捞明月专栏</a></h1>
			</div>
		</div>

		<div id="main">
			<h2 class="top_title"><a href="http://blog.csdn.net/zwszws/article/details/37737043">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">醉捞明月专栏</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" />

          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+'"><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 + '"><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。

       到此,城市和日期选择功能已经实现。


       本文未涉及到日期的验证,如返回日期不能小于出发日期,这个需要做怎么样的修改呢?疑问

       可以,使用自定义验证方法(addMethodname, 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("-", "/")));
    },
    "结束日期必须大于开始日期!");

       这个方法的缺点是文字提示不美观,还是想一想别的方法偷笑快哭了

     最终,修改如下:

$(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;
}
      效果如下:


             本文 源代码下载:http://download.csdn.net/detail/zwszws/7630417









  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值