7月13日。晴。“别院深深夏席清。石榴开遍透帘明。 树阴满地日当午,梦觉流莺时一声。”
在JQuery的法则里。风格重于一切,IT牛人们从来没有把自己束缚在一张乏味的表单上,怀着对JavaScript的理解。在不断的尝试中寻求着转化的灵感。
大多购票、旅游站点上都提供了一个城市和日期输入查询的功能。用户在输入框中仅仅需输入城市的拼音或者简称就能够弹出相关城市的名称。选择日期时则是出现一个月的日历控件,仅仅需点选日期就可以。整个操作一目了然。
本文解说怎样使用jQuery实现城市查询和日历显示的整个流程。用到了jquery ui库的datepicker插件来控制日历以及输入城市提示的插件。
1、index.htm
本页面分三部分。那就 定义三个id,各自是header,main,footer。代表脑袋、身体和脚丫。演示:jQuery实现往返城市和日期查询
脑袋里面又定义了一个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的样式:
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+='
- '+html+'
- ' + html + '
<\/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。
到此,城市和日期选择功能已经实现。
本文未涉及到日期的验证。如返回日期不能小于出发日期,这个须要做怎么样的改动呢?
能够。使用自己定义验证方法(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("-", "/"))); }, "结束日期必须大于開始日期!");
这种方法的缺点是文字提示不美观,还是想一想别的方法
终于,改动例如以下:
$(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;}效果例如以下:
本文 源码下载: