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


    版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/zwszws/article/details/37737043

               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 {
    				 600px;
    				margin: 60px auto
    			}
    			.input {
    				border: 1px solid #999
    			}
    			.qline {
    				line-height: 24px;
    				margin: 10px
    			}
    			#suggest, #suggest2 {
    				 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 || ' '; options.onSelect = options.onSelect || false; options.dataDelimiter = options.dataDelimiter || ' '; 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









  • 相关阅读:
    【leetcode】对称二叉树
    【leetcode】判断回文数
    053686
    053685
    053684
    053683
    053682
    053681
    053680
    053477
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10922017.html
Copyright © 2020-2023  润新知