一、布局样式:
1.1 基本HTML和视图
<span style="font-size:14px;">
<div class="ajax-input">
<label for="name">ajax请求输入框:</label>
<input type="text" id="name" placeholder="输入内容获取相关信息">
</div>
</span>
说明:确保最外的div的class为”ajax-input”,并且里面包含一个label和一个input,对label和input的参数并没有其他要求。
图1.1 基本视图
默认的CSS样式中,input的宽度是div的100%,如果需要修改,在ajax-input.css中修改即可。
1.2 AJAX请求后的HTML和视图
图1.3 AJAX请求后的HTML
图1.4 AJAX请求后显示的样式
二、参数设计:
因为需要发送AJAX请求到后台请求数据,所以必须传入AJAX请求的地址以及要显示的内容所属的键名,目前是只支持返回json格式的数据。
也就是说,”ajaxUrl”和”showName”这两个参数一定不能不传入。extraParams提供传入更多的参数给AJAX请求。
// 构造方法ele指调用插件的元素,opts指传入的参数
var AjaxInput = function (ele, opts) {
this.$element = ele;
this.defaults = {
'ajaxUrl': '', // 请求路径
'requestMethod': 'get', // 默认请求为get,(目前只支持get)
'extraParams': {}, // 扩展ajax参数,默认没有更多的请求参数
'showName': '' // 要显示的json数组的键(也就是某一个字段名)
};
this.options = $.extend({}, this.defaults, opts);
};
扩展:目前的AJAX只是用到了$get方法,可以自己想方法去扩展更多的方法,比如$post和$ajax。
三、详细设计:
3.1 设计思路:
1、监听输入框的三种事件:
a) 按键抬起事件keyup(),不包括上下和回车按钮:用于捕捉用户的输入,并发送请求;
b) 按键按下事件keypress(),只是上下和回车按钮:用于提供用户使用键盘选择选项;
c) 失去焦点事件blur():当用户选择了某选项或者取消选择的时候,关闭选择提示。
2、运行流程:
输入框输入内容 --> 取输入的内容和额外提供的参数拼接成AJAX请求 --> 解释返回的json数据,生成ul和li节点 --> 给li添加mousedown事件监听(注意不能是click事件)--> 添加ul和li到包含输入框的div后 --> 当用户通过上下按键或鼠标点击选择了某项li,则把li的值添加到输入框内,并删除ul和li。
3.2 具体代码:
3.2.1 数据库数据:
图3.1 数据库数据示例
3.2.2 后台代码(django框架):
# ajax模糊查询接口
def ajax_data(request):
if request.method == 'GET':
# 获取模糊搜索关键词,默认最多返回10个
keyword = request.GET['keyword']
print keyword
if keyword:
json_data = serializers.serialize("json", Wine.objects.filter(Q(cn_name__icontains=keyword))[:10])
else:
json_data = serializers.serialize("json", Wine.objects.all()[:10])
# 如果存在关键字
return HttpResponse(json_data, content_type="application/json")
else:
return render_to_response("test.html")
3.2.3 插件样式文件(ajax-input.css)
@charset "utf-8";
/**
* Created by tanglihao on 2015/12/31.
* ajax-input.css 是一个基于jquery和ajax请求的输入框插件样式
*/
.ajax-input, .ajax-input input, .ajax-input ul, .ajax-input input ul li {
margin: 0;
padding: 0;
}
/* 默认的label是作为块元素显示的 */
.ajax-input label {
display: block;
}
.ajax-input input {
height: 2.0em;
width: 100%;
}
ul.item-list {
z-index: 1000;
width: 100%;
}
ul.item-list li {
list-style: none;
background: #fff;;
height: 2.0em;
color: #888;
cursor: pointer;
border-right: solid 1px #ddd;
border-left: solid 1px #ddd;
}
ul.item-list li:first-child {
border-top: solid 1px #ddd;
}
ul.item-list li:last-child {
border-bottom: solid 1px #ddd;
}
/* li获取焦点的样式和控制li上下键选中的样式 */
ul.item-list li:hover {
background: #ddd;
}
ul.item-list li.focus-li {
background: #ccc;
}
@charset "utf-8";
/**
* Created by tanglihao on 2015/12/31.
* ajax-input.css 是一个基于jquery和ajax请求的输入框插件样式
*/
.ajax-input, .ajax-input input, .ajax-input ul, .ajax-input input ul li {
margin: 0;
padding: 0;
}
/* 默认的label是作为块元素显示的 */
.ajax-input label {
display: block;
}
.ajax-input input {
height: 2.0em;
width: 100%;
}
ul.item-list {
z-index: 1000;
width: 100%;
}
ul.item-list li {
list-style: none;
background: #fff;;
height: 2.0em;
color: #888;
cursor: pointer;
border-right: solid 1px #ddd;
border-left: solid 1px #ddd;
}
ul.item-list li:first-child {
border-top: solid 1px #ddd;
}
ul.item-list li:last-child {
border-bottom: solid 1px #ddd;
}
/* li获取焦点的样式和控制li上下键选中的样式 */
ul.item-list li:hover {
background: #ddd;
}
ul.item-list li.focus-li {
background: #ccc;
}
3.2.4 插件js文件源码(ajax-input.js)
/**
* Created by tanglihao on 2015/12/31.
* ajax-input.js 是一个基于jquery和ajax请求的输入框插件
*/
;(function ($, window, document, undefined) {
// 构造方法ele指调用插件的元素,opts指传入的参数
var AjaxInput = function (ele, opts) {
this.$element = ele;
this.defaults = {
'ajaxUrl': '', // 请求路径
'requestMethod': 'get', // 默认请求为get,(目前只支持get)
'extraParams': {}, // 扩展ajax参数,默认没有更多的请求参数
'showName': '' // 要显示的json数组的键(也就是某一个字段名)
};
this.options = $.extend({}, this.defaults, opts);
};
// 定义方法
AjaxInput.prototype = {
ajaxRequest: function () {
// 创建ul节点
var $itemList = $('<ul></ul>').addClass("item-list");
var ajaxUrl = this.options.ajaxUrl;
var showName = this.options.showName;
var $input = this.$element;
var extraPara = this.options.extraParams;
// 监听输入框的按键松开事件,实现当输入改变时
this.$element.keyup(function (e) {
if(e.keyCode != 38 && e.keyCode != 40 && e.keyCode != 13) {
// 获取输入框的内容作为关键字和ajax请求参数
var keyword = $(this).val();
extraPara["keyword"] = keyword;
// 发送ajax到后台请求数据
$.get(ajaxUrl, extraPara, function(data){
// 删除原来的ul节点
$itemList.find("li").remove();
$itemList.remove();
// 遍历后台返回的json数组,并生成li节点
for(var item in data) {
alert(data[item].fields[showName]);
// 创建li节点
var $item = $('<li></li>').addClass("li-item");
$item.text(data[item].fields[showName]);
$item.attr("num", "li-"+item.toString());
$itemList.append($item);
}
// 监听li的鼠标点击事件
if ($itemList.find('li').length > 0) {
$('.ajax-input').append($itemList);
$itemList.find('li').mousedown(function () {
// 设置输入框的文字
$input.val($(this).text());
$itemList.remove();
});
}else {
// 如果需要设计没有选项的样式,可以在这里添加控制样式的代码
}
});
}
}).keypress(function (e) {
// 监听键盘的上下按键,实现上下选择选项的功能
var liLen = $itemList.find('li').length;
if(liLen > 0) {
//alert($itemList.find('li').hasClass("focus-li"));
if($itemList.find('li').hasClass("focus-li")) {
// 获取
var focusNum = $itemList.find('li.focus-li').attr("num").split("-")[1];
if(e.keyCode == 38) {
if(focusNum == 0) {
// 焦点在第一个li上
$itemList.find('li.focus-li').removeClass("focus-li");
$itemList.find('li').last().addClass("focus-li");
}else {
$itemList.find('li.focus-li').prev().addClass("focus-li");
$itemList.find('li.focus-li').next().removeClass("focus-li");
}
}else if(e.keyCode == 40) {
if (focusNum == liLen-1) {
// 焦点在最后一个li上
$itemList.find('li.focus-li').removeClass("focus-li");
$itemList.find('li').first().addClass("focus-li");
} else {
$itemList.find('li.focus-li').next().addClass("focus-li");
$itemList.find('li.focus-li').prev().removeClass("focus-li");
}
}else if(e.keyCode == 13) {
// 回车选中
var sel = $itemList.find('li.focus-li').text();
$input.val(sel).blur();
}
}
else{
// 没有li被选中
if (e.keyCode == 38) {
// 上按键
$itemList.find('li:last-child').addClass("focus-li");
} else if (e.keyCode == 40) {
// 下按键
$itemList.find('li:first-child').addClass("focus-li");
}
}
}
}).blur(function () {
// 删除输入框的焦点
//$itemList.remove();
});
return this;
}
};
// 使用对象
$.fn.ajaxInput = function (options) {
var objectInput = new AjaxInput(this, options);
return objectInput.ajaxRequest();
};
})(jQuery, window, document);
四、使用方式:
$(“要使用ajax-input的输入框选择式”).ajaxInput();
具体例子代码:
<script> $(function () { $("#name").ajaxInput({"ajaxUrl": "/ajax/", "showName": "cn_name", "liCss" : {"a": "ggr", "c": "tttt"}}); }); </script>
五、备注:
这是本人初学jquery写的第一个插件,扩展性和兼容性都很差。此外,插件本人只在django框架下测试成功,相信java的框架弄起来会更加简单。如有错漏或者改进意见欢迎留言,谢谢!