magicsearch
Version:
An input plugin based on jquery.
1 lines • 19.6 kB
JavaScript
"use strict";function _toConsumableArray(t){if(Array.isArray(t)){for(var i=0,e=Array(t.length);i<t.length;i++)e[i]=t[i];return e}return Array.from(t)}!function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t("undefined"!=typeof jQuery?jQuery:window.Zepto)}(function(t){var i={BACKSPACE:8,ENTER:13,ESC:27,SPACE:32,LEFT:37,UP:38,RIGHT:39,DOWN:40},e={wrapper:"magicsearch-wrapper",box:"magicsearch-box",arrow:"magicsearch-arrow",loading:"magicsearch-loading",hidden:"magicsearch-hidden",items:"multi-items",item:"multi-item",close:"multi-item-close"},s=function(i){return"string"===t.type(i)},o=function(t,i){var e=t.match(new RegExp("\\%[^\\%]+\\%","g"));if(!e)return t;for(var s=0;s<e.length;s++)e[s]=e[s].replace(new RegExp("\\%","g"),"");for(var o=0;o<e.length;o++)t=t.replace("%"+e[o]+"%",i[e[o]]?i[e[o]]:"error");return t},a=function(t){var i=t.lastIndexOf("px");return i<0?Number(t):Number(t.substring(0,i))},r=function(i,e){return t.isNumeric(i)?(i=Math.ceil(Number(i)))<=0&&(i=n.defaults[e]):i=n.defaults[e],i},n=function(i,e){this.element=i,this.$element=t(i),this.options=e};n.defaults={dataSource:[],type:"",ajaxOptions:{},id:"",hidden:!1,fields:"",format:"",inputFormat:"",maxShow:5,isClear:!0,showSelected:!0,dropdownBtn:!1,dropdownMaxItem:8,multiple:!1,maxItem:!0,showMultiSkin:!0,multiStyle:{},multiField:"",focusShow:!1,noResult:"",skin:"",disableRule:function(t){return!1},success:function(t,i){return!0},afterDelete:function(t,i){return!0}},n.prototype={init:function(){var i=this;window.MagicSearch.index+=1;var o=this.$element;if(this.options=t.extend({},n.defaults,this.options),this.props={isFirstGetDataSource:!0,style:t.extend({},this.element.style),objDataSource:{},multiStyle:{space:3,width:57}},!this.$element.is("input:text"))return console.error("magicsearch: Can not bind magicsearch to other elements except input which type is text."),!1;if(!s(this.options.id)||""===this.options.id)return console.error("magicsearch: The option id must be a string which is not empty."),!1;this.options.multiple?this.options.isClear=!0:this.options.isClear||(this.options.hidden=!1),this.props.styles={borderTopWidth:a(o.css("border-top-width")),borderRightWidth:a(o.css("border-right-width")),borderBottomWidth:a(o.css("border-bottom-width")),borderLeftWidth:a(o.css("border-left-width")),paddingTop:a(o.css("padding-top")),paddingRight:a(o.css("padding-right")),paddingBottom:a(o.css("padding-bottom")),paddingLeft:a(o.css("padding-left")),maxWidth:a(o.css("max-width"))||500},this.props.styles.height=o.height()+this.props.styles.borderTopWidth+this.props.styles.borderBottomWidth+this.props.styles.paddingTop+this.props.styles.paddingBottom,this.props.styles.sightHeight=this.props.styles.height-this.props.styles.borderTopWidth-this.props.styles.borderBottomWidth,this.props.styles.width=o.width()+this.props.styles.borderLeftWidth+this.props.styles.borderRightWidth+this.props.styles.paddingLeft+this.props.styles.paddingRight;var r=this.props.styles,d=o.attr("data-id");if("magicsearch"!==o.parent().attr("data-belong")){var h=t('<div class="'+e.wrapper+(this.options.skin?" "+this.options.skin:"")+'" data-belong="magicsearch"></div>');h.css("width",r.width),o.wrap(h)}var l=o.parent(),p=o.css("display");if(l.css({display:"inline"===p?"inline-block":p,float:o.css("float"),margin:o.css("margin")}),l.attr("data-index",window.MagicSearch.index),o.css({margin:0,"box-sizing":"border-box",width:r.width,height:r.height}),o.attr("placeholder")&&o.attr("data-placeholder",o.attr("placeholder")),o.removeAttr("disabled"),this.options.isClear&&o.val(""),void 0===d&&(o.attr("data-id",""),d=""),0===l.find("."+e.box).length&&l.append('<div class="'+e.box+'"></div>'),l.find("."+e.box).css({top:r.height}),this.options.hidden){var c=o.attr("name"),u=t('<input class="'+e.hidden+'" type="hidden" value="'+d+'">');c&&(u.attr("name",c),o.removeAttr("name")),l.append(u)}if(this.options.dropdownBtn){var f=t('<div class="'+e.arrow+'"><i></i></div>');o.addClass("dropdown"),o.css("padding-right",r.paddingRight+24),f.css({top:r.borderTopWidth,bottom:r.borderBottomWidth,right:r.borderRightWidth}),l.append(f)}if("ajax"==this.options.type){var m=t('<div class="'+e.loading+'"><div></div></div>');l.append(m);var g=setTimeout(function(){l.find("."+e.loading).find("div").show()},500),v={type:"GET",url:this.options.dataSource,dataType:"json",error:function(){console.error("magicsearch: Error with xhr.Index: "+window.MagicSearch.index)},success:function(t){}};v=t.extend({},v,this.options.ajaxOptions);var w=v.success;v.success=function(t){clearTimeout(g),i.options.dataSource=t,l.find("."+e.loading).remove(),i.initAfterAjax(),w(t)},t.ajax(v)}else this.initAfterAjax();return this},initAfterAjax:function(){var i=this.$element,a=i.parent(),n=this.props.styles,d=i.attr("data-id");if(t.isFunction(this.options.dataSource)&&(this.options.dataSource=this.options.dataSource(this.$element)),this.options.dataSource){if(s(this.options.dataSource))if("null"==this.options.dataSource.toLowerCase())this.options.dataSource=[];else try{if(this.options.dataSource=t.parseJSON(this.options.dataSource),!t.isArray(this.options.dataSource)){var h=[];for(var l in this.options.dataSource)h.push(this.options.dataSource[l]);this.options.dataSource=h}}catch(t){return this.options.dataSource=[],console.error("magicsearch: A problem is occured during parsing dataSource,please check.Index: "+window.MagicSearch.index),!1}else if(!t.isArray(this.options.dataSource)){var p=[];for(var c in this.options.dataSource)p.push(this.options.dataSource[c]);this.options.dataSource=p}}else this.options.dataSource=[];if(s(this.options.fields)?this.options.fields=[""===this.options.fields?this.options.id:this.options.fields]:t.isArray(this.options.fields)||(this.options.fields=[this.options.id]),s(this.options.format)&&""!==this.options.format||(this.options.format="%"+this.options.id+"%"),this.options.maxShow=r(this.options.maxShow,"maxShow"),this.options.dropdownBtn&&(this.options.dropdownMaxItem=r(this.options.dropdownMaxItem,"dropdownMaxItem")),this.options.multiple&&(!0!==this.options.maxItem&&(this.options.maxItem=r(this.options.maxItem,"maxItem")),this.options.showMultiSkin&&(s(this.options.multiField)&&""!==this.options.multiField||(this.options.multiField=this.options.id)),this.options.multiStyle&&(this.props.multiStyle.space=this.options.multiStyle.space?this.options.multiStyle.space:3,this.props.multiStyle.width=this.options.multiStyle.width?this.options.multiStyle.width:57)),t.isFunction(this.options.success)||(this.options.success=function(t,i){return!0}),t.isFunction(this.options.disableRule)||(this.options.disableRule=function(t){return!1}),""!==d&&this.getDataSource(),this.options.multiple&&(i.addClass("multi"),this.options.showMultiSkin&&0===a.find("."+e.items).length)){var u=t('<div class="'+e.items+'"></div>');u.css({top:this.props.multiStyle.space+n.borderTopWidth,left:this.props.multiStyle.space+n.borderLeftWidth,bottom:this.props.multiStyle.space+n.borderBottomWidth,right:this.props.multiStyle.space+n.borderRightWidth+(this.options.dropdownBtn?24:0)}),a.append(u)}if(this.options.multiple){var f=d?d.split(","):[];if(!0!==this.options.maxItem&&f.length>=this.options.maxItem&&(i.attr("disabled","disabled"),a.addClass("disabled")),this.options.showMultiSkin)for(var m=[],g=0;g<f.length;g++)m.push(f[g]),i.attr("data-id",m.join(",")),this.options.hidden&&a.find("."+e.hidden).val(m.join(",")),this.appendHtml(this.props.objDataSource[f[g]])}else if(""!==d){var v=this.props.objDataSource[d],w=this.options.inputFormat?this.options.inputFormat:this.options.format;i.val(o(w,v))}},destroy:function(){var t=this.$element,i=t.parent();if("magicsearch"===i.attr("data-belong")){this.element.style=this.props.style,t.css({margin:i.css("margin"),"padding-top":this.props.styles.paddingTop,"padding-right":this.props.styles.paddingRight,"padding-bottom":this.props.styles.paddingBottom,"padding-left":this.props.styles.paddingLeft,height:this.props.styles.height,width:this.props.styles.width});var e=t.attr("data-placeholder");void 0!==e&&(t.attr("placeholder",e),t.removeAttr("data-placeholder")),t.removeClass("dropdown multi").removeAttr("disabled data-id"),t.siblings().remove(),t.unwrap(),t.off(),t.val("")}},getDataSource:function(){var t=this.options.dataSource;if(this.props.isFirstGetDataSource){for(var i={},e=0;e<t.length;e++)for(var s in t[e])this.options.dataSource[e][s]=String(t[e][s]);this.props.isFirstGetDataSource=!1;for(var o=0;o<t.length;o++)i[t[o][this.options.id]]=t[o];this.props.objDataSource=i}return this.options.dataSource},setData:function(){var t=this.$element,i=t.parent(),s=i.find("."+e.box),a=(i.find("."+e.arrow),s.find("li.ishover")),r=this.options,n=t.attr("data-id"),d=this.props.objDataSource[a.attr("data-id")];if(r.multiple){if(s.is(":hidden"))return;t.val("");var h=n?n.split(","):[];if(!0!==r.maxItem&&h.length>=r.maxItem)return this;h.push(a.attr("data-id")),!0!==r.maxItem&&h.length==r.maxItem&&(t.attr("disabled","disabled"),i.addClass("disabled")),t.attr("data-id",h.join(",")),r.hidden&&i.find("."+e.hidden).val(h.join(",")),r.showMultiSkin&&this.appendHtml(d)}else t.val(r.inputFormat?o(r.inputFormat,d):a.text()),t.attr("data-id",a.attr("data-id")),r.hidden&&i.find("."+e.hidden).val(a.attr("data-id"));return r.success(t,d),this},deleteData:function(i){var s=this.$element,o=s.parent(),a=o.find("."+e.box),r=(o.find("."+e.arrow),this),n=i?i.split(","):[],d=s.attr("data-id"),h=d?d.split(","):[],l=this.options,p=this.props.styles;if(!l.multiple)return i=s.attr("data-id"),s.val("").attr("data-id",""),l.hidden&&o.find("."+e.hidden).val(""),l.afterDelete(s,r.props.objDataSource[i]),this;for(var c=function(){t(this).remove()},u=0;u<n.length;u++)o.find("."+e.item+'[data-id="'+n[u]+'"]').fadeOut(400,c),h.splice(h.indexOf(n[u]),1);return setTimeout(function(){var t=parseInt((p.maxWidth-(l.dropdownBtn?24:0)-p.borderLeftWidth-p.borderRightWidth-r.props.multiStyle.space)/(r.props.multiStyle.width+r.props.multiStyle.space)),i=parseInt(h.length/t);if(s.attr("data-id",h.join(",")),l.hidden&&o.find("."+e.hidden).val(h.join(",")),o.removeClass("disabled"),s.removeAttr("disabled"),l.showMultiSkin&&(0===h.length&&s.attr("data-placeholder")&&s.attr("placeholder",s.attr("data-placeholder")),s.css("padding-left",h.length%t*(r.props.multiStyle.width+r.props.multiStyle.space)+p.paddingLeft),s.css("height",p.height+i*p.sightHeight),s.css("padding-top",i*p.sightHeight+p.paddingTop),a.css("top",p.height+i*p.sightHeight),0===i)){var d=(h.length%t+1)*(r.props.multiStyle.width+r.props.multiStyle.space)+2*r.props.multiStyle.space+p.borderLeftWidth+p.borderRightWidth+(l.dropdownBtn?24:0);s.css("min-width",d),o.css("min-width",d)}1==n.length&&l.afterDelete(s,r.props.objDataSource[n[0]])},400),this},searchData:function(i,s){var a=this.$element,r=a.parent().find("."+e.box),n=this.options,d=this.getDataSource(),h=a.attr("data-id"),l=h?h.split(","):[],p=t.trim(a.val()),c="",u=[],f=!0;if(!0!==s&&r.html(""),""===p&&!i)return this;if(i){var m=a.data("page")||1;if(u=d.slice(0),!n.showSelected)for(var g=0,v=0;g<u.length;g++){var w=l.indexOf(u[g][n.id]);if(w>-1&&(u.splice(g,1),v++,g--,v==l.length))break}m<=Math.ceil(u.length/100)&&a.data("page",m+1),u=u.slice(100*(m-1),100*m),1!=m&&0===u.length&&(f=!1)}else{for(var S=[].concat(_toConsumableArray(new Set(p.toLowerCase().split(" ")))),y=[],x=0;x<S.length;x++)""!==S[x]&&y.push({value:S[x],flag:!1});for(var b=0;b<d.length;b++)if(n.showSelected||!l.includes(d[b][n.id])){y=y.map(function(t){return t.flag=!1,t});for(var C=0;C<n.fields.length;C++){for(var B=0;B<y.length;B++)null!==d[b][n.fields[C]]&&d[b][n.fields[C]].toLowerCase().includes(y[B].value)&&(y[B].flag=!0);var D=y.every(function(t){return t.flag});if(D){u.push(d[b]);break}}if(u.length>=n.maxShow)break}}if(0===u.length){var A=n.noResult?n.noResult:"未搜索到结果";c='<span class="no-result">'+A+"</span>"}else{for(var W=[].concat(_toConsumableArray(new Set(p.split(" ")))).filter(function(t){return""!==t}),T=[],E=0;E<W.length-1;E++)for(var R=E+1;R<W.length;R++)T.push(W[E]+" "+W[R]);W=W.concat(T);var I=void 0;i||(I=t.extend(!0,[],u),u.forEach(function(t,i){n.fields.forEach(function(e){var s=[];if(null!==t[e]){for(var o=0;o<t[e].length;o++)s[o]=0;W.forEach(function(i){var o=t[e].toLowerCase().indexOf(i.toLowerCase());if(o>-1)for(var a=o;a<i.length+o;a++)s[a]=1})}for(var a=[],r=!1,n=-1,d=0,h=s.length-1;h>=0;h--)1==s[h]?(r?n--:(r=!0,n=h),d++,0===h&&a.push({start:n,length:d})):r&&(r=!1,a.push({start:n,length:d}),d=0);void 0!==I[i][e]&&(I[i][e]=a)})})),c+="<ul>",u.forEach(function(e,s){var a=t.extend({},e);c+='<li class="',c+=n.disableRule(e)?"disabled":"enabled",n.showSelected&&(c+=l.includes(e[n.id])?" selected":""),c+='" data-id="'+(void 0===e[n.id]?"":e[n.id])+'"',i||n.fields.forEach(function(t){null!==e[t]&&I[s][t].forEach(function(i){var e=a[t].substr(i.start,i.length);a[t]=a[t].replace(new RegExp(e,"i"),'<span class="keyword">'+e+"</span>")})}),c+=' title="'+o(n.format,e)+'">'+o(n.format,a)+"</li>"}),c+="</ul>"}return i?(f&&r.html(r.html()+c),r.addClass("all")):(r.html(c),r.removeClass("all").css("max-height","none")),this},showSearchBox:function(t){var i=this.$element,s=i.parent(),o=s.find("."+e.box);if(o.is(":visible"))return!1;if(this.options.dropdownBtn){var a=s.find("."+e.arrow);a.removeClass("arrow-rotate-360"),a.addClass("arrow-rotate-180")}return o.slideDown(200,t),this},hideSearchBox:function(t){var i=this.$element,s=i.parent(),o=s.find("."+e.box);if(!o.is(":visible"))return!1;if(void 0===t?this.options.isClear&&(this.options.multiple||""===i.attr("data-id"))&&i.val(""):t&&i.val(""),this.options.dropdownBtn){var a=s.find("."+e.arrow);a.removeClass("arrow-rotate-180"),a.addClass("arrow-rotate-360")}return setTimeout(function(){o.scrollTop(0)},199),o.slideUp(200,function(){o.html("")}),this},appendHtml:function(i){var s=this.$element,a=s.parent(),r=a.find("."+e.box),n=(a.find("."+e.arrow),r.find("li.ishover"),this.options),d=this.props.styles,h=this,l=s.attr("data-id").split(",");s.attr("placeholder")&&s.removeAttr("placeholder");var p=parseInt((d.maxWidth-(n.dropdownBtn?24:0)-d.borderLeftWidth-d.borderRightWidth-h.props.multiStyle.space)/(h.props.multiStyle.width+h.props.multiStyle.space)),c=t('<div class="'+e.item+'" data-id="'+i[n.id]+'" title="'+o(n.format,i)+'"><span>'+o("%"+n.multiField+"%",i)+'</span><a class="'+e.close+'" data-id="'+i[n.id]+'" href="javascript:;"></a></div>');c.css({height:d.sightHeight-2*h.props.multiStyle.space,width:h.props.multiStyle.width,"margin-bottom":2*h.props.multiStyle.space,"margin-right":h.props.multiStyle.space,"line-height":d.sightHeight-2*h.props.multiStyle.space-2+"px"}),c.find("."+e.close).css({top:parseInt((d.sightHeight-2*h.props.multiStyle.space-2-12)/2)});var u=parseInt(l.length/p);if(s.css("padding-left",d.paddingLeft+l.length%p*(h.props.multiStyle.width+h.props.multiStyle.space)),l.length%p==0)s.css("height",d.height+u*d.sightHeight),s.css("padding-top",u*d.sightHeight),r.css("top",d.height+u*d.sightHeight);else if(0===u){var f=(l.length%p+1)*(h.props.multiStyle.width+h.props.multiStyle.space)+2*h.props.multiStyle.space+d.borderLeftWidth+d.borderRightWidth+(n.dropdownBtn?24:0);s.css("min-width",f),a.css("min-width",f)}c.find("."+e.close).click(function(){h.deleteData(t(this).attr("data-id")).hideSearchBox()}),a.find("."+e.items).append(c)}},t.fn.magicsearch=function(o){var a=!1,r=null,d="",h=this.each(function(){var h=t(this),l=t.data(this,"magicsearch");if(l&&l.destroy(),l=new n(this,o),!1!==l.init()){t.data(this,"magicsearch",l);var p=l.options,c=h.parent(),u=c.find("."+e.box),f=function(){if(c.hasClass("disabled"))return!1;u.is(":visible")?l.hideSearchBox():(u.css({"max-height":30*p.dropdownMaxItem+8}),u.unbind("scroll"),h.data("page",1),l.searchData(!0).showSearchBox(function(){u.on("scroll",function(i){this.scrollHeight-t(this).scrollTop()<300&&l.searchData(!0,!0)})}))};h.off().on("keyup",function(e){var s=t(this);if(e.which==i.ESC)s.val("").focus(),l.hideSearchBox();else{if(e.which==i.DOWN){var o=u.find("li"),a=u.find("li.ishover");return o.length>0&&(a.length>0?(a.toggleClass("ishover"),a.next().length>0?a.next().toggleClass("ishover"):u.find("li:first").toggleClass("ishover")):u.find("li:first").toggleClass("ishover")),!1}if(e.which==i.UP){var n=u.find("li"),h=u.find("li.ishover");return n.length>0&&(h.length>0?(h.toggleClass("ishover"),h.prev().length>0?h.prev().toggleClass("ishover"):u.find("li:last").toggleClass("ishover")):u.find("li:last").toggleClass("ishover")),!1}if(e.which==i.ENTER){var c=u.find("li.ishover");c.length>0&&c.trigger("click")}else{if(e.which==i.LEFT||e.which==i.RIGHT)return!0;var f=s.val();if(t.trim(d)==t.trim(f))return!0;if(""!==f){if(""===t.trim(f))return l.hideSearchBox(e.which!=i.BACKSPACE&&e.which!=i.SPACE&&void 0),!1;if(!p.multiple&&""!==s.attr("data-id"))return void l.hideSearchBox();clearTimeout(r),r=setTimeout(function(){l.searchData().showSearchBox()},200)}else l.hideSearchBox()}}}).on("keydown",function(s){var o=t(this);if(s.which==i.ESC);else{if(s.which==i.UP)return!1;if(s.which==i.DOWN)return!1;if(s.which==i.ENTER)return!u.is(":visible");if(s.which==i.BACKSPACE)if(d=o.val(),p.multiple){var a=c.find("."+e.items+" ."+e.item+":last");p.showMultiSkin&&""===o.val()&&l.deleteData(a.attr("data-id")).hideSearchBox()}else""!==t(this).attr("data-id")&&(l.deleteData(),l.hideSearchBox());else{if(s.which==i.LEFT||s.which==i.RIGHT)return!0;if(""!==(d=o.val())&&!p.multiple&&""!==o.attr("data-id"))return void l.deleteData()}}}).on("focus",function(){c.addClass("focus"),p.isClear||""===h.val()||""!==h.attr("data-id")?p.focusShow&&f():l.searchData().showSearchBox()}).on("blur",function(){c.removeClass("focus"),l.hideSearchBox()}),u.off().on("mousedown","ul",function(){return!1}).on("mouseenter","li",function(){t(this).parent().find("li.ishover").removeClass("ishover"),t(this).addClass("ishover")}).on("mouseleave","li",function(){t(this).removeClass("ishover")}).on("click","li",function(){var i=t(this);i.hasClass("selected")&&p.multiple?l.deleteData(i.attr("data-id")).hideSearchBox():l.setData().hideSearchBox()}),p.dropdownBtn&&(a=!0,c.on("click","."+e.arrow,function(){return f()})),h.on("clear",function(){h.val(""),p.multiple&&p.showMultiSkin?l.deleteData(h.attr("data-id")):(h.attr("data-id",""),p.hidden&&c.find("."+e.hidden).val(""))}).on("update",function(i,e){if(void 0!==e.dataSource){var o=e.dataSource;if(s(o))if("null"==e.dataSource.toLowerCase())o=[];else try{if(o=t.parseJSON(e.dataSource),!t.isArray(o)){var a=[];for(var r in o)a.push(o[r]);o=a}}catch(t){o=[],console.error("magicsearch: The dataSource you updated is wrong,please check.")}l.props.isFirstGetDataSource=!0,l.options.dataSource=o}}).on("set",function(t,i){var e=l.$element.attr("data-id"),s=l.options.multiple;l.destroy(),l.$element.attr("data-id",i.override||!s?i.id:[].concat(_toConsumableArray(new Set((e?e.split(","):[]).concat(i.id.split(",")))))),l.$element.magicsearch(l.options)}).on("destroy",function(){l.destroy()}),c.on("click","."+e.items,function(i){t(i.target).is("."+e.items)&&h.focus()}).on("mousedown","."+e.items,function(){return!1})}});return a&&!window.MagicSearch.hasBindBody&&(t("body").on("mousedown",function(i){var s=t(i.target),o=t(this).find("."+e.wrapper+" ."+e.box+":visible").first().parent(),a=o.find("input:text"),r=o.attr("data-index");void 0===r||s.is("."+e.wrapper+'[data-index="'+r+'"] *')||t.data(a.get(0),"magicsearch").hideSearchBox()}),window.MagicSearch.hasBindBody=!0),h},window.MagicSearch={v:"1.0.2",index:0,hasBindBody:!1}});