You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

0 lines
3.9 KiB

  1. !function(t){t.add("module","autocomplete",{init:function(t,e){this.app=t,this.$doc=t.$doc,this.$win=t.$win,this.$body=t.$body,this.animate=t.animate;var i={url:!1,min:2,labelClass:!1,target:!1,param:!1};this.context=e,this.params=e.getParams(i),this.$element=e.getElement(),this.$target=e.getTarget()},start:function(){this._build(),this.timeout=null,this.$element.on("keyup.kube.autocomplete",this._open.bind(this))},stop:function(){this.$box.remove(),this.$element.off(".kube.autocomplete"),this.$doc.off(".kube.autocomplete"),this.$win.off(".kube.autocomplete")},_build:function(){if(this.$box=t.dom("<div />"),this.$box.addClass("autocomplete"),this.$box.addClass("is-hidden"),this.$body.append(this.$box),this.$target&&!this._isInputTarget()){this.$target.addClass("autocomplete-labels");var e=this.$target.find(".close");e.on("click",this._removeLabel.bind(this))}},_open:function(t){t&&t.preventDefault(),clearTimeout(this.timeout);var e=this.$element.val();e.length>=this.params.min?(this._resize(),this.$win.on("resize.kube.autocomplete",this._resize.bind(this)),this.$doc.on("click.kube.autocomplete",this._close.bind(this)),this.$box.addClass("is-open"),this._listen(t)):this._close(t)},_close:function(t){t&&t.preventDefault(),this.$box.removeClass("is-open"),this.$box.addClass("is-hidden"),this.$doc.off(".kube.autocomplete"),this.$win.off(".kube.autocomplete")},_getPlacement:function(t,e){return this.$doc.height()-(t.top+e)<this.$box.height()?"top":"bottom"},_resize:function(){this.$box.width(this.$element.width())},_getParamName:function(){return this.params.param?this.params.param:this.$element.attr("name")},_getTargetName:function(){var t=this.$target.attr("data-name");return t?t:this.$target.attr("id")},_lookup:function(){var e=this._getParamName()+"="+this.$element.val();t.ajax.post({url:this.params.url,data:e,success:this._complete.bind(this)})},_complete:function(e){if(this.$box.html(""),0===e.length)return this._close();for(var i=0;i<e.length;i++){var s=t.dom("<a>");s.attr("href","#"),s.attr("rel",e[i].id),s.html(e[i].name),s.on("click",this._set.bind(this)),this.$box.append(s)}var a=this.$element.offset(),n=this.$element.height(),o=this.$element.width(),h=this._getPlacement(a,n),l="top"===h?a.top-this.$box.height()-n:a.top+n;this.$box.css({width:o+"px",top:l+"px",left:a.left+"px"}),this.$box.removeClass("is-hidden")},_listen:function(t){switch(t.which){case 40:t.preventDefault(),this._select("next");break;case 38:t.preventDefault(),this._select("prev");break;case 13:t.preventDefault(),this._set();break;case 27:this._close(t);break;default:this.timeout=setTimeout(this._lookup.bind(this),300)}},_select:function(t){var e=this.$box.find("a"),i=this.$box.find(".is-active");e.removeClass("is-active");var s=this._selectItem(i,e,t);s.addClass("is-active")},_selectItem:function(t,e,i){var s,a=0!==t.length,n="next"===i?0:e.length-1;return a&&(s=t[i]()),a&&s&&0!==s.length||(s=e.eq(n)),s},_set:function(e){var i=this.$box.find(".is-active");e&&(e.preventDefault(),i=t.dom(e.target));var s=i.attr("rel"),a=i.html();if(0!==this.$target.length){if(this._isInputTarget())this.$target.val(a);else{var n=this.$target.find('[data-id="'+s+'"]');0===n.length&&this._addLabel(s,a)}this.$element.val("")}else this.$element.val(a);this.$element.focus(),this.app.broadcast("autocomplete.set",this,a),this._close()},_addLabel:function(e,i){var s=t.dom("<span>");s.addClass("label"),s.attr("data-id",e),s.text(i+" "),this.params.labelClass&&s.addClass(this.params.labelClass);var a=t.dom("<span>");a.addClass("close"),a.on("click",this._removeLabel.bind(this));var n=t.dom("<input>");n.attr("type","hidden"),n.attr("name",this._getTargetName()+"[]"),n.val(i),s.append(a),s.append(n),this.$target.append(s)},_isInputTarget:function(){return"INPUT"===this.$target.get().tagName},_removeLabel:function(e){e.preventDefault();var i=t.dom(e.target),s=i.closest(".label");this.animate.run(s,"fadeOut",function(){s.remove()}.bind(this))}})}(Kube);