应需求要求,最近要做一个类似于手机端首字母排序的下拉框。
整理了一下思路,大概分为一下几个步骤:
- 由于数据库中的字段没有存首字母的信息,所以要将sql改造
- 在后台处理相关数据,将取得的数据按英文字母排序
- 前台写一个统一的js方法,以便不同位置统一调用
其实后台和sql语句没有什么难点,主要是前端的样式,滚动条滚动,点击跳转滚动条。
1)sql
SELECT
ID AS id, BRAND AS value,
CONV(HEX(left(CONVERT(BRAND USING gbk),1)),16,10) AS initial
FROM xxx WHERE 1=1
GROUP BY BRAND
ORDER BY initial
由于数据库表中没有存该字段的首字母信息,所以在查询的时候将首字母的信息查询出来。brand这个字段包括首字母包含中文英文和数字,所以要转为一个有中文的编码。
- CONVERT(BRAND USING gbk) :将要查询的字段(BRAND)转换为gbk编码
- left(CONVERT(BRAND USING gbk),1) :返回字符串的前一个字符
- HEX(x):返回x的十六进制编码
- CONV(x,f1,f2):返回f1进制x的f2进制编码
查询的结果大概是这样的,将结果放入List<Map>
中
2)处理数据
数据展示是按照A-Z排序,所以想了一下后台传过的数据大概是
[
'A':[],
'B':[],
'C':[],
'D':[],
……
]
此时从数据库查询出来的数据的首字母信息是数字形式的编码形式,对这种编码进行处理,返回首字母大写
strChinese是数据库查询出的initial字段
public static String getPYIndexChar(int strChinese, boolean bUpCase) {
int charGBK = strChinese;
String result;
if((charGBK & 255) <= 128){
return String.valueOf((char)charGBK).toUpperCase();
}
if (charGBK >= 45217 && charGBK <= 45252)
result = "A";
else if (charGBK >= 45253 && charGBK <= 45760)
result = "B";
else if (charGBK >= 45761 && charGBK <= 46317)
result = "C";
else if (charGBK >= 46318 && charGBK <= 46825)
result = "D";
else if (charGBK >= 46826 && charGBK <= 47009)
result = "E";
else if (charGBK >= 47010 && charGBK <= 47296)
result = "F";
else if (charGBK >= 47297 && charGBK <= 47613)
result = "G";
else if (charGBK >= 47614 && charGBK <= 48118)
result = "H";
else if (charGBK >= 48119 && charGBK <= 49061)
result = "J";
else if (charGBK >= 49062 && charGBK <= 49323)
result = "K";
else if (charGBK >= 49324 && charGBK <= 49895)
result = "L";
else if (charGBK >= 49896 && charGBK <= 50370)
result = "M";
else if (charGBK >= 50371 && charGBK <= 50613)
result = "N";
else if (charGBK >= 50614 && charGBK <= 50621)
result = "O";
else if (charGBK >= 50622 && charGBK <= 50905)
result = "P";
else if (charGBK >= 50906 && charGBK <= 51386)
result = "Q";
else if (charGBK >= 51387 && charGBK <= 51445)
result = "R";
else if (charGBK >= 51446 && charGBK <= 52217)
result = "S";
else if (charGBK >= 52218 && charGBK <= 52697)
result = "T";
else if (charGBK >= 52698 && charGBK <= 52979)
result = "W";
else if (charGBK >= 52980 && charGBK <= 53688)
result = "X";
else if (charGBK >= 53689 && charGBK <= 54480)
result = "Y";
else if (charGBK >= 54481 && charGBK <= 55289)
result = "Z";
else
result = "1";
if (!bUpCase)
result = result.toLowerCase();
return result;
}
判断数据,分别放入对应首字母的List,再将首字母和list分别作为key,value放入map,传到前台的数据是这样的
3)前台处理
以上,后台的数据处理完了,现在主要写前台的功能。首先来分析一下这个下拉框有哪些功能。
- 点击input,在下面生成其下拉框
- 下拉框上部分按a-z排序展示
- 下部分将后台返回数据展示
- 点击下拉框上部分字母,跳转到下部首字母相应位置
- 首字母不存在值的时候灰色显示
现在我们开始做,在input下面生成div
/**url : 请求地址
inputId : 输入框id
params : 参数,格式{ a:xx,b:xx,c:xx}
fun : inputId输入框值改变时回调函数
注 ** input改变后的值
id:$("#" + inputId).attr("data_id");
val:$("#" + inputId).val();
*/
function getSelectInfo(url, inputId, params, fun) {
/*$("#" + inputId).attr("data_id", TypeCode);*/
var inputId = inputId;
var url = url;
if (params != "" && params != null) {
url += "?" + urlEncode(params)
}
$.ajax({
url: url,
type: 'POST',
cache: false,
success: function (responseJson) {
$("#" + inputId).next().remove();
$("#" + inputId).after('<div class="select_All" id="' + inputId + "_random" + '" hidden> <div class="select_head"><p>' +
'<a name="A"><b>A</b></a><a name="B"><b>B</b></a><a name="C"><b>C</b></a><a name="D"><b>D</b></a>' +
'<a name="E"><b>E</b></a><a name="F"><b>F</b></a><a name="G"><b>G</b></a> <a name="H"><b>H</b></a>' +
'<a name="I"><b>I</b></a><a name="J"><b>J</b></a><a name="K"><b>K</b></a><a name="L"><b>L</b></a>' +
'<a name="M"><b>M</b></a><a name="N"><b>N</b></a>' +
'</p><p>' +
'<a name="O"><b>O</b></a><a name="P"><b>P</b></a><a name="Q"><b>Q</b></a><a name="R"><b>R</b></a>' +
'<a name="S"><b>S</b></a><a name="T"><b>T</b></a><a name="U"><b>U</b></a><a name="V"><b>V</b></a>' +
'<a name="W"><b>W</b></a><a name="X"><b>X</b></a><a name="Y"><b>Y</b></a><a name="Z"><b>Z</b></a>' +
'<a name="1"><b>#</b></a>' +
'</p></div> <div class="select_div_mode"> <div class="select_body"></div></div> </div>');
if (responseJson != null) {
for (var k in responseJson) {
var docList = responseJson[k];
if (docList != "" && docList != null) {
$("#" + inputId).next().find('a[name="' + k + '"] b').addClass("haveValue");
if (k == "1") {
$("#" + inputId).next().find('.select_div_mode .select_body').append('<div id=' + inputId + k + ' name=' + inputId + k + '><span class="span1">#</span></div>');
} else {
$("#" + inputId).next().find('.select_div_mode .select_body').append('<div id=' + inputId + k + ' name=' + inputId + k + '><span class="span1">' + k + '</span></div>');
}
for (var i in docList) {
{
$("#" + inputId).next().find(".select_div_mode #" + inputId + k + " span").after('<p id=' + inputId + "_" + docList[i].id + '>' + docList[i].value + '</p>');
}
}
}
}
}
}
});
$("#" + inputId + "_random .select_head a").die('click').live('click', function (e) {
var val = $(this).attr("name");
var container = $("#" + inputId + "_random .select_div_mode")
scrollTo = $("#" + inputId + val + ":first");
container.scrollTop(scrollTo.offset().top - container.offset().top + container.scrollTop());
return;
});
$("#" + inputId).off('click').on('click', function (e) {
if ($(this).val() == "" || $(this).val() == null) {
$("#" + inputId).attr("data_id", "");
}
$("#" + inputId + "_random").toggle();
stopPropagation(e);
$("#" + inputId + "_random .select_div_mode p").removeClass("hover");
var val = $(this).attr("data_id");
var container = $("#" + inputId + "_random .select_div_mode");
scrollTo = $("#" + inputId + "_" + val);
if (scrollTo.length != 0) {
scrollTo.addClass("hover");
container.scrollTop(scrollTo.offset().top - container.offset().top + container.scrollTop());
}else {
container.scrollTop(0)
}
});
$(document).live('click', function () {
$("#" + inputId + "_random").hide();
});
$("#" + inputId + "_random").live('click', function (e) {
$("#" + inputId + "_random").show();
stopPropagation(e);
});
$("#" + inputId + "_random .select_body p").die('click').live('click', function (e) {
$("#" + inputId).val($(this).text());
$("#" + inputId).attr("data_id", $(this).attr("id").split("_")[1]);
$("#" + inputId + "_random").hide();
$("#" + inputId).validationEngine('hide');
$("#" + inputId).trigger('change');
stopPropagation(e);
});
}
4)最终效果
知识点总结
没做之前觉得这个功能特别难做,但是一点一点琢磨之后发现也不是那么难,第一次记录写的很乱,以后慢慢进步吧。
$("#XXX").die('click').live('click', function (e) {
stopPropagation(e); //阻止事件冒泡
});
var container = $("#整个div");
scrollTo = $("#想滚动到哪个div");
container.scrollTop(scrollTo.offset().top - container.offset().top +