不带搜索框,数据同步请求,产品按字母分组组件

Posted 苗苗一号

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不带搜索框,数据同步请求,产品按字母分组组件相关的知识,希望对你有一定的参考价值。

组件效果:

搜索效果:

 

 

 

组件js 代码:

/* *
* 全局空间 SearchBox
* */
var SearchBox = {};
/* *
* 静态方法集
* @name _method
* */
SearchBox._method = {
/* 选择元素 */
$:function (arg, context) {
var tagAll, n, eles = [], i, sub = arg.substring(1);
context = context || document;
if (typeof arg == \'string\') {
switch (arg.charAt(0)) {
case \'#\':
return document.getElementById(sub);
break;
case \'.\':
if (context.getElementsByClassName) return context.getElementsByClassName(sub);
tagAll = SearchBox._method.$(\'*\', context);
n = tagAll.length;
for (i = 0; i < n; i++) {
if (tagAll[i].className.indexOf(sub) > -1) eles.push(tagAll[i]);
}
return eles;
break;
default:
return context.getElementsByTagName(arg);
break;
}
}
},

/* 绑定事件 */
on:function (node, type, handler) {
node.addEventListener ? node.addEventListener(type, handler, false) : node.attachEvent(\'on\' + type, handler);
},

/* 获取事件 */
getEvent:function(event){
return event || window.event;
},

/* 获取事件目标 */
getTarget:function(event){
return event.target || event.srcElement;
},

/* 获取元素位置 */
getPosition:function (node) {
var scrollx = document.documentElement.scrollLeft || document.body.scrollLeft,
scrolly = document.documentElement.scrollTop || document.body.scrollTop;
var position = node.getBoundingClientRect();
return {top:position.top + scrolly, right:position.right + scrollx, bottom:position.bottom + scrolly, left:position.left + scrollx }
},

/* 添加样式名 */
addClass:function (c, node) {
if(!node)return;
node.className = SearchBox._method.hasClass(c,node) ? node.className : node.className + \' \' + c ;
},

/* 移除样式名 */
removeClass:function (c, node) {
var reg = new RegExp("(^|\\\\s+)" + c + "(\\\\s+|$)", "g");
if(!SearchBox._method.hasClass(c,node))return;
node.className = reg.test(node.className) ? node.className.replace(reg, \'\') : node.className;
},

/* 是否含有CLASS */
hasClass:function (c, node) {
if(!node || !node.className)return false;
return node.className.indexOf(c)>-1;
},

/* 阻止冒泡 */
stopPropagation:function (event) {
event = event || window.event;
event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;
},
/* 去除两端空格 */
trim:function (str) {
return str.replace(/^\\s+|\\s+$/g,\'\');
}
};


/* *
* 城市控件构造函数
* @init
* */

SearchBox.init = function () {
this.initialize.apply(this, arguments);
};

SearchBox.init.prototype = {

constructor:SearchBox.init,
/* 初始化 */

initialize :function (options) {
this.destroy();
var input = options.inputId;
var navItem = options.navItem;
SearchBox.toggleTab = options.toggleTab;
SearchBox.onSearchValueChange = options.onSearchValueChange;
SearchBox.attrTextModel = options.attrTextModel;
SearchBox.contentList = options.contentList;
SearchBox.searchData = options.searchData;
this.currentPage = 1;
this.searchValue = [];
this.input = SearchBox._method.$(\'#\'+ input);
this.createNavbar(navItem);
this.inputEvent();
},

scrollEvent: function(){
var that = this;
$(this.rootDiv).find(\'.item-box\').scroll(function(){
if($(this).scrollTop() == 0){ // 到顶了
if(that.currentPage > 1){
$(".loading-bottom").remove();
$(this).prepend("<div class=\'loading loading-top\'><img src=\'../public/img/loading.gif\'/></div>");

that.currentPage--;
SearchBox.contentList = SearchBox.toggleTab(that.currentPage, that.index);

that.createItemBox(true);
}
}else if(($(this).scrollTop() + $(this).outerHeight()) >= $(this)[0].scrollHeight){ // 到底了
if (that.currentPage < that.pagination.totalPage) {
$(".loading-top").remove();
$(this).append("<div class=\'loading loading-bottom\'><img src=\'../public/img/loading.gif\'/></div>");

that.currentPage++;
SearchBox.contentList = SearchBox.toggleTab(that.currentPage, that.index);

that.createItemBox(true);
$(this).scrollTop(10);
}
}
});
},

scrollSearchEvent: function(){
var that = this;
$(this.rootDiv).find(\'.mCustomScrollbar\').scroll(function(){
var value = SearchBox._method.trim(that.input.value);
if($(this).scrollTop() == 0){ // 到顶了
if(that.currentPage > 1){
$(".loading-bottom").remove();
$(this).prepend("<div class=\'loading loading-top\'><img src=\'../public/img/loading.gif\'/></div>");

that.currentPage--;
SearchBox.searchData = SearchBox.onSearchValueChange(value,that.currentPage);

that.searchValue = SearchBox.searchData.data;
that.searchPagination = SearchBox.searchData.pagination;

that.createUl();
}
}else if(($(this).scrollTop() + $(this).outerHeight()) >= $(this)[0].scrollHeight){ // 到底了
if (that.currentPage < that.searchPagination.totalPage) {
$(".loading-top").remove();
$(this).append("<div class=\'loading loading-bottom\'><img src=\'../public/img/loading.gif\'/></div>");

that.currentPage++;
SearchBox.searchData = SearchBox.onSearchValueChange(value,that.currentPage);

that.searchPagination = SearchBox.searchData.pagination;
if(that.searchPagination.currentPage == that.searchPagination.totalPage && SearchBox.searchData.data.length < 10){
that.searchValue = that.searchValue.concat(SearchBox.searchData.data)
}else{
that.searchValue = SearchBox.searchData.data;
}

$(this).scrollTop(10);
that.createUl();
}
}
});
},

destroy: function(){
if($(\'.search-box-wrap\')) {
$(\'.search-box-wrap\').remove();
}
},

/*
* @createNavbar
* 创建navbar
* */

createNavbar: function(navItem){
var _html = \'\';
if(navItem && navItem.length){
_html += \'<ul>\';
_html += \'<li class="on">\'+ \'热门\' +\'</li>\';
navItem.forEach(function(val, index){
if(index==navItem.length-1){
_html += \'<li>\'+ \'其他\' +\'</li>\';
}else{
_html += \'<li>\'+ val +\'</li>\';
}
});
_html += \'</ul>\';
}
SearchBox.navItem = _html;
},

/* *
* @createWarp
* 创建城市BOX HTML 框架
* */

createWarp:function(element){
var div = this.rootDiv = document.createElement(\'div\');
var that = this;

// 设置DIV阻止冒泡
SearchBox._method.on(this.rootDiv,\'click\',function(event){
SearchBox._method.stopPropagation(event);
});

// 设置点击文档隐藏弹出的城市选择框
SearchBox._method.on(document, \'click\', function (event) {
event = SearchBox._method.getEvent(event);
var target = SearchBox._method.getTarget(event);
if(target == that.input) return false;
if (that.searchBox)SearchBox._method.addClass(\'hide\', that.searchBox);
if (that.ul)SearchBox._method.addClass(\'hide\', that.ul);
});
div.className = \'search-box-wrap\';
div.style.position = \'absolute\';
div.style.top = 34 + \'px\';
div.style.zIndex = 999999;
var childdiv = this.searchBox = document.createElement(\'div\');
childdiv.className = \'search-box\';
childdiv.id = \'searchBox\';
childdiv.innerHTML = SearchBox.navItem;
var itemBox = this.itemBox = document.createElement(\'div\');
itemBox.className = \'item-box\';
childdiv.appendChild(itemBox);
div.appendChild(childdiv);
this.createItemBox(false);
},

/* *
* @createitemBox
* TAB下面DIV:hot,a-h,i-p,q-z 分类HTML生成,DOM操作
* {HOT:{hot:[]},ABCDEFGH:{a:[1,2,3],b:[1,2,3]},IJKLMNOP:{},QRSTUVWXYZ:{}}
**/

createItemBox:function(flag){
var contentList = SearchBox.contentList.data;
this.pagination = SearchBox.contentList.pagination;
$(".loading").remove();
if(contentList && contentList.length){
if(flag && this.pagination.currentPage == this.pagination.totalPage && contentList.length < 10){
var _html = this.itemBox.innerHTML;
}else{
var _html = \'\';
}
contentList.forEach(function(val, index){
_html += \'<a href="javascript:;" data-name=\'+JSON.stringify(val)+\'>\'+ val.name +\'(\'+ val.code + \')\' +\'</a>\';
});
}
this.itemBox.innerHTML = _html || \'\';
//document.body.appendChild(this.rootDiv);
this.input.parentNode.appendChild(this.rootDiv);

this.tabChange();
this.linkEvent();
},

/* *
* tab按字母顺序切换
* @ tabChange
* */

tabChange:function(){
var lis = SearchBox._method.$(\'li\',this.searchBox);
var divs = SearchBox._method.$(\'div\',this.itemBox);
var that = this;
for(var i=0,n=lis.length;i<n;i++){
lis[i].index = i;
lis[i].onclick = function(){
for(var j=0;j<n;j++){
SearchBox._method.removeClass(\'on\',lis[j]);
SearchBox._method.addClass(\'hide\',divs[j]);
}
that.index = this.innerHTML;
SearchBox.contentList = SearchBox.toggleTab(that.currentPage,this.innerHTML);
that.createItemBox(false);
SearchBox._method.addClass(\'on\',this);
SearchBox._method.removeClass(\'hide\',divs[this.index]);
};
}
},

/* *
* 城市LINK事件
* @linkEvent
* */

linkEvent:function(){
var links = SearchBox._method.$(\'a\',this.itemBox);
var that = this;
for(var i=0,n=links.length;i<n;i++){
links[i].onclick = function(){
var dataName = $(this).attr(\'data-name\');
that.input.value = this.innerHTML;
SearchBox.attrTextModel(that.input.value,JSON.parse(dataName));
SearchBox._method.addClass(\'hide\',that.searchBox);
}
}
},

/* *
* INPUT城市输入框事件
* @inputEvent
* */

inputEvent:function(){
var that = this;
SearchBox._method.on(this.input,\'click\',function(event){
event = event || window.event;
if(!that.searchBox){
that.createWarp();
}else if(!!that.searchBox && SearchBox._method.hasClass(\'hide\',that.searchBox)){
// slideul 不存在或者 slideul存在但是是隐藏的时候 两者不能共存
if(!that.ul || (that.ul && SearchBox._method.hasClass(\'hide\',that.ul))){
SearchBox._method.removeClass(\'hide\',that.searchBox);
}
}

that.scrollEvent();
});
SearchBox._method.on(this.input,\'blur\',function(){
});
SearchBox._method.on(this.input,\'keyup\',function(event){
event = event || window.event;
var keycode = event.keyCode;
SearchBox._method.addClass(\'hide\',that.searchBox);
var value = SearchBox._method.trim(that.input.value);

SearchBox.searchData = SearchBox.onSearchValueChange(value,that.currentPage);
that.searchValue = SearchBox.searchData.data;
that.searchPagination = SearchBox.searchData.pagination;

that.createUl();

that.scrollSearchEvent();
// 下拉菜单显示的时候捕捉按键事件
if(that.ul && !SearchBox._method.hasClass(\'hide\',that.ul) && !that.isEmpty){
that.KeyboardEvent(event,keycode);
}
});
},

/* *
* 生成下拉选择列表
* @ createUl
* */

createUl:function () {
var that = this;
var str;
var value = SearchBox._method.trim(this.input.value);
$(".loading").remove();
// 当value不等于空的时候执行
if (value !== \'\') {
var reg = new RegExp("^" + value + "|\\\\|" + value, \'gi\');
// 此处需设置中文输入法也可用onpropertychange
var searchResult = [];
for (var i = 0, n = that.searchValue.length; i < n; i++) {
if (searchResult.length !== 0) {
str = \'<li class="cityname" data-name=\'+JSON.stringify(that.searchValue[i])+\'>\' + that.searchValue[i].name + \'(\'+ that.searchValue[i].code + \')\' + \'</li>\';
} else {
str = \'<li class="cityname" data-name=\'+JSON.stringify(that.searchValue[i])+\'>\' + that.searchValue[i].name +\'(\'+ that.searchValue[i].code + \')\' + \'</li>\';
}
searchResult.push(str);
}
this.isEmpty = false;
// 如果搜索数据为空
if (searchResult.length == 0) {
this.isEmpty = true;
str = \'<li class="empty">对不起,没有找到 "<em>\' + value + \'</em>"</li>\';
searchResult.push(str);
}
// 如果slideul不存在则添加ul
if (!this.ul) {
var ul = this.ul = document.createElement(\'ul\');
ul.className = \'cityslide mCustomScrollbar\';
this.rootDiv && this.rootDiv.appendChild(ul);
// 记录按键次数,方向键
this.count = 0;
} else if (this.ul && SearchBox._method.hasClass(\'hide\', this.ul)) {
this.count = 0;
SearchBox._method.removeClass(\'hide\', this.ul);
}
this.ul.innerHTML = searchResult.join(\'\');

// 绑定Li事件
this.liEvent();
}else{
SearchBox._method.addClass(\'hide\',this.ul);
SearchBox._method.removeClass(\'hide\',this.searchBox);
}
},

/* *
* 特定键盘事件,上、下、Enter键
* @ KeyboardEvent
* */

KeyboardEvent:function(event,keycode){
var lis = SearchBox._method.$(\'li\',this.ul);
var len = lis.length;
switch(keycode){
case 40: //向下箭头↓
this.count++;
if(this.count > len-1) this.count = 0;
for(var i=0;i<len;i++){
SearchBox._method.removeClass(\'on\',lis[i]);
}
SearchBox._method.addClass(\'on\',lis[this.count]);
break;
case 38: //向上箭头↑
this.count--;
if(this.count<0) this.count = len-1;
for(i=0;i<len;i++){
SearchBox._method.removeClass(\'on\',lis[i]);
}
SearchBox._method.addClass(\'on\',lis[this.count]);
break;
case 13: // enter键
this.input.value = lis[this.count].innerHTML;
SearchBox._method.addClass(\'hide\',this.ul);
SearchBox._method.addClass(\'hide\',this.ul);
break;
default:
break;
}
},

/* *
* 下拉列表的li事件
* @ liEvent
* */

liEvent:function(){
var that = this;
var lis = SearchBox._method.$(\'li\',this.ul);
for(var i = 0,n = lis.length;i < n;i++){
SearchBox._method.on(lis[i],\'click\',function(event){
event = SearchBox._method.getEvent(event);
var target = SearchBox._method.getTarget(event);
var dataName = $(target).attr(\'data-name\');
if(dataName){
that.input.value = target.innerHTML;
SearchBox.attrTextModel(target.innerHTML,JSON.parse(dataName));
SearchBox._method.addClass(\'hide\',that.ul);
}
});
SearchBox._method.on(lis[i],\'mouseover\',function(event){
event = SearchBox._method.getEvent(event);
var target = SearchBox._method.getTarget(event);
SearchBox._method.addClass(\'on\',target);
});
SearchBox._method.on(lis[i],\'mouseout\',function(event){
event = SearchBox._method.getEvent(event);
var target = SearchBox._method.getTarget(event);
SearchBox._method.removeClass(\'on\',target);
})
}
}
};


组件css代码:

*{margin:0;padding:0;box-sizing:border-box;}
.search-box-wrap{font:14px \'Source Sans Pro\',\'Helvetica Neue\',Helvetica,Arial,sans-serif,\\5b8b\\4f53;background:#fff;text-align:left;}
.cityslide{width:400px;list-style:none;margin:0;padding:0;border:1px solid #A9B2BD;overflow:auto;max-height:260px;}
.cityslide li{border-bottom: 1px solid #ddd;text-align: left;list-style:none;overflow:hidden;height:34px;padding:0px 10px;line-height:34px;font-weight:normal;width: 100%;}
.cityslide li.on{background:#01AAED;color:#555;cursor:pointer;}
.cityslide li:hover{background:#01AAED;color:#555;cursor:pointer;}
.cityslide li.empty{background:#fff2e8;color:#555;}
.cityslide li.empty em{color:red;font-style:normal;}
.cityname{float:left;}
.cityspell{float:right;}
.search-box{width:400px;border:1px solid #ddd;overflow:hidden;}
.search-box ul{margin:0;padding:0;overflow:hidden;padding-top: 5px}
.search-box ul li:first-child{margin-left:5px;}
.search-box ul li{line-height: 24px;float:left;list-style:none;padding:2px;border-bottom:1px solid #DDD;cursor:pointer;display:inline;color:#01AAED;width: auto}
.search-box ul li.on{border-bottom-color:#555;position:relative;width: auto}
.hide{display:none;}
p.tip{color:#555;line-height:20px;padding:5px;margin:0;text-indent:3px;}
.item-box{width:400px;border-top:1px solid #ddd;margin-top:-1px;clear:left;overflow:auto;_margin-bottom:8px;max-height: 260px;}
.cityTab{overflow:hidden;}
.cityinput{ font-size: 12px; padding-left: 2px; border: 1px solid #ddd; }
.item-box a{padding-left:10px;line-height:34px;display:block;color:#555;text-decoration:none;border-bottom: 1px solid #ddd;}
.item-box a:hover{color:#555;background: #01AAED;}
.item-box .loading-top{margin-top: 0px}
.item-box .loading img {position:relative;top:10px; }

组件引入:

<input ng-model="orderProduct" placeholder="请输入名称或编码" id="select-product" ng-enter="search()" ng-trim="true" type="text" maxlength="30" autocomplete="off">

 ID索引

 

$scope.contentList = orderSearchService.getProductAllData({\'urlParams\': {\'isHot\': true}});
$scope.navItem = orderSearchService.getProductNavItem();
var productBox = new SearchBox.init({
inputId:"select-product",
searchData:[],
navItem: $scope.navItem.data,
tabIndex:\'热门\',
contentList: $scope.contentList.data,
toggleTab: function(currentPage,index){
this.tabIndex = index;
var config = {
\'urlParams\': {
\'isHot\':false,
\'pageIndex\': currentPage || 1,
\'pageSize\': 10,
\'capital\': index
}
};
if(index == "热门"){
config.urlParams.isHot = true;
config.urlParams.capital = \'\';
}
if(index == "其他"){
config.urlParams.isHot = false;
config.urlParams.capital = \'_\';
}
var result = orderSearchService.getProductAllData(config);
return {data:result.data,pagination:result.pagination}
},
onSearchValueChange:function(data,currentPage) {
var config = {
\'urlParams\': {
\'q\':data,
\'isHot\':false,
\'pageIndex\': currentPage || 1,
\'pageSize\': 10,
\'capital\': \'\'
}
};
var result = orderSearchService.getProductAllData(config);
return {data:result.data,pagination:result.pagination};
},
attrTextModel: function (name, data) {
$scope.orderProduct = name || \'\';
$scope.orderProductUid = data.uid || \'\';
$scope.$apply();
}
});

 

以上是关于不带搜索框,数据同步请求,产品按字母分组组件的主要内容,如果未能解决你的问题,请参考以下文章

搜索框组件

按首字母 Javascript 按字母顺序对对象进行排序和分组

熊猫按时间和分组滚动条件总和

如何按多列分组以在熊猫数据框中列出

无法获取数据,使用包 yfinance 按格式分组下载到熊猫数据框中,仅适用于我的子列表中的特定代码

LeetCode(数据库)- 按日期分组销售产品