define(function (require, exports) { var $html = '

最近查询

常用城市

'; var selector; var data = require("../station/station_data.js"); var cityMap = _(_.flatten(_.map(_.values(data.data), function (e) { return _.values(e); }))).mapObject(function (e) { return e.c; }); var CitySelector = function (options) { var that = this; var dom = $("#city_selector"); var currentList = null; var currentPage = 1; var totalPage = 1; var pageSize = options.rows * 4; var target = null; var prevTab = null; var searchKey; that.findExtractCity = function (val) { if (!val) return null; if (cityMap[val]) return cityMap[val]; for (var c in cityMap) { var city = cityMap[c]; if (city.p === val || city.c === val || city.n === val) return city; } return null; }; that.focusOnText = function () { if (target) target[0].focus(); }; that.getSelectedCity = function () { var ele = $(this); var val = ele.val(); var city = null; //取得当前选择的城市。逻辑:如果有输入内容,则查找对应的城市是否存在,存在则直接返回; //否则如果当前输入不为空,则找已选择的,有则返回,没有则取列表第一个返回; //如果都无法返回,则返回null if (val) { city = that.findExtractCity(val); } if (city === null) { //查找已经选中的 var e = dom.find("dd.selected[data-code]:visible, li.selected[data-code]:visible"); if (e.length) { var code = e.attr("data-code"); city = that.findExtractCity(code); } } if (city === null) { var nodes = that.currentShownCities; if (nodes.length) { city = that.findExtractCity(nodes.eq(0).attr("data-code")); } } return city; }; that.performSearch = function () { target = $(this); var key = target.val().replace(/\s/g, ""); if (key === searchKey) return; searchKey = key; if (!key) { that.switchTab(prevTab); return; } //清空选择 that.switchTab(); dom.find(".city-search").show().find(">p").html("搜索“" + key + "”"); //搜索城市 key = key.toUpperCase(); var lkey = key.toLowerCase(); currentList = _.filter(_.values(cityMap), function (e) { return e.p.indexOf(lkey) != -1 || e.n.indexOf(key) != -1 || e.c.indexOf(key) != -1 || e.h.indexOf(lkey) != -1; }); currentPage = 0; totalPage = Math.ceil(currentList.length / pageSize); that.renderPage(1); that.focusOnText(); }; that.showPopup = function (ele) { if (selector.isVisible) return; searchKey = null; that.switchTab(dom.find(".city-tab-nav li:first")); dom.find(".city-list-container li, dd[data-code]").removeClass("selected"); var offset = ele.offset(); dom.css({ left: offset.left + "px", top: (offset.top + ele.height()) + "px" }); dom.addClass("open"); target = ele; that.focusOnText(); }; that.hidePopup = function (force) { dom.removeClass("open"); if (force) { dom.css("top", "-2000px"); } }; that.switchTab = function (tab) { dom.find(".city-tab-nav li").removeClass("selected"); dom.find(".city-search, .city-pop, .recent-city-list").hide(); if (!tab) return; tab.addClass("selected"); prevTab = tab; var code = tab.attr("data-code"); currentPage = 0; if (code) { dom.find(".city-search>p").html("站点列表"); currentList = _.values(data.data[code]); totalPage = Math.ceil(currentList.length / pageSize); that.renderPage(1); dom.find(".city-search").show(); } else { currentList = null; dom.find(".city-pop, .recent-city-list").show(); } dom.find(".city-list-container ul, dd[data-code]").removeClass("selected"); that.currentShownCities = null; that.focusOnText(); }; that.renderPage = function (page) { /// 切换当前的分页 if (page < 1 || page === currentPage || page > totalPage) return; currentPage = page; //绑定数据 var html = []; var listCount = 0; for (var i = (currentPage - 1) * pageSize; i < currentPage * pageSize && i < currentList.length; i++) { var city = currentList[i]; listCount++; html.push("
  • " + city.n + "
  • "); } if (listCount % 4 !== 0) { for (var i = 0; i < 4 - listCount % 4; i++) { html.push("
  • "); } } dom.find(".city-search ul").empty().append(html.join("")); //上一页下一页可用性 $("button.city-prev")[0].disabled = currentPage <= 1; $("button.city-next")[0].disabled = currentPage >= totalPage - 1; that.currentShownCities = null; }; that.showNextPage = function () { that.renderPage(currentPage + 1); that.focusOnText(); }; that.showPrevPage = function () { that.renderPage(currentPage - 1); that.focusOnText(); }; that.selectNext = function (offset) { offset = offset || 1; //当前的列表 var eles = dom.find("div.recent-city-list:visible dd[data-code], ul.city-list-container:visible li[data-code]"); var current = eles.filter(".selected"); if (!current.length) { //尚没有选择 if (offset > 0) { //向下移动,则默认选择第一个 eles.first().addClass("selected"); } else { eles.last().addClass("selected"); } } else { var index = eles.index(current); index += offset; if (index < 0) { if (currentPage > 1) { that.showPrevPage(); dom.find("div.city-search ul.city-list-container li[data-code]:last").addClass("selected"); } } else if (index >= eles.length) { if (currentPage < totalPage) { that.showNextPage(); dom.find("div.city-search ul.city-list-container li[data-code]:first").addClass("selected"); } } else { current.removeClass("selected"); eles.eq(index).addClass("selected"); } } that.focusOnText(); }; dom.find("button.city-prev").click(that.showPrevPage); dom.find("button.city-next").click(that.showNextPage); Object.defineProperty(this, "isVisible", { get: function () { return dom.is(":visible"); } }); //当前显示的城市节点 var _currnetShownNodes; Object.defineProperty(this, "currentShownCities", { get: function () { return _currnetShownNodes || (_currnetShownNodes = dom.find("div.recent-city-list:visible dd[data-code], ul.city-list-container:visible li[data-code]")); }, set: function (value) { _currnetShownNodes = value; } }); dom.click(function () { that.focusOnText(); }); dom.find(".city-tab-nav li").click(function () { var tab = $(this); if (tab.hasClass("selected")) return; selector.switchTab(tab); }); that.selectToTarget = function (city, ele) { ele = ele || target; if (!ele) return; if (typeof (city) === "string") city = that.findExtractCity(city); if (!city) city = that.getSelectedCity.call(ele); if (!city) return; ele.data("data-code", city.c); ele.val(city.n); ele[0].blur(); }; $(document).on("click", ".recent-city-list dd[data-code], .city-list-container li[data-code]", function () { //选定城市 that.selectToTarget(this.dataset.code); that.hidePopup(true); }); return this; }; exports.init = function (eleSelector, args) { $("body").append($html); //初始化常用城市 (function () { var html = []; _.each(data.popcity, function (c) { var city = cityMap[c]; html.push("
  • " + city.n + "
  • "); }); if (data.popcity.length % 4 !== 0) { for (var i = 0; i < 4 - data.popcity.length % 4; i++) { html.push("
  • "); } } $("#city_selector .city-pop ul").append(html.join("")); })(); args = $.extend({ rows: 9 }, args); selector = new CitySelector(args); $(document).on("focus", eleSelector, function () { this.select(); selector.showPopup($(this)); }).on("blur", eleSelector, function () { selector.hidePopup(); }).on("keydown", eleSelector, function (e) { var code = e.key || e.keyCode; if ((code >= 37 && code <= 40) || code === 13) { e.stopPropagation(); e.preventDefault(); switch (code) { case 37: //< selector.selectNext(-1); break; case 38: //^ selector.selectNext(-4); break; case 39: //> selector.selectNext(); break; case 40: //下 selector.selectNext(4); break; case 13: //选定 console.log(selector.getSelectedCity.call(this)); break; default: } return false; } }).on("keyup", eleSelector, selector.performSearch); } });