From 643215d0be3f1066b8239dfd072e8485bd648c75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20FRERE?= Date: Mon, 5 Aug 2013 16:58:30 +0200 Subject: [PATCH] Adds creationText option to display a line in the results to indicate it will create a new keyword --- demo/demo.html | 30 +++++++++++++++++++++ dist/jquery.autoSuggest.js | 40 +++++++++++++++++++++++++--- dist/jquery.autoSuggest.min.js | 2 +- src/jquery.autoSuggest.coffee | 32 +++++++++++++++++++++-- test/jquery.autoSuggest_test.js | 46 +++++++++++++++++++++++++++++++++ 5 files changed, 144 insertions(+), 6 deletions(-) diff --git a/demo/demo.html b/demo/demo.html index 8bc6f06..bf8a059 100644 --- a/demo/demo.html +++ b/demo/demo.html @@ -149,6 +149,36 @@ }); }()); + (function () { + var container = builder('Demo with static data, native Placeholder and creationText.', 'name', 'Name'); + var form = container.find('form'); + var input = container.find('input[type=text]'); + var output = container.find('pre'); + + var data = [ + {value : "21", name : "Mick Jagger"}, + {value : "43", name : "Johnny Storm"}, + {value : "46", name : "Richard Hatch"}, + {value : "54", name : "Kelly Slater"}, + {value : "55", name : "Rudy Hamilton"}, + {value : "79", name : "Michael Jordan"} + ]; + var options = { + selectedItemProp : "name", + searchObjProps : "name", + fadeOut : 'slow', + usePlaceholder : true, + startText : '', + creationText: ' - Add this keyword' + }; + input.autoSuggest(data, options); + + form.submit(function (event) { + event.preventDefault(); + output.text('Selected: ' + input.parent('.as-original').find(':hidden').val()); + }); + }()); + (function () { var container = builder('Demo with static data + renderer + fake placeholder.', 'name', 'Name'); container.addClass('user-list'); diff --git a/dist/jquery.autoSuggest.js b/dist/jquery.autoSuggest.js index d0fcb06..0491ea2 100644 --- a/dist/jquery.autoSuggest.js +++ b/dist/jquery.autoSuggest.js @@ -775,7 +775,9 @@ Based on the 1.6er release dated in July, 2012 return fetcher(string, processData); }; processData = function(data, query) { - var formatted, forward, matchCount, name, num, regex, resultsContainerVisible, str, text, workingData, _k, _l, _len2, _len3, _ref2; + var creation_hint, formatted, forward, matchCount, name, num, original_query, regex, resultsContainerVisible, str, text, workingData, _k, _l, _len2, _len3, _ref2; + creation_hint = false; + original_query = query; if (!options.matchCase) { query = query.toLowerCase(); } @@ -783,6 +785,38 @@ Based on the 1.6er release dated in July, 2012 matchCount = 0; resultsContainer.hide().html(resultsList.html('')); num = 0; + if (options.creationText && $.grep(data, function(item) { + return item[options.selectedItemProp].toLowerCase() === query; + }).length === 0 && !currentSelection.exist(query)) { + formatted = $("
  • "); + formatted.on({ + click: function() { + var n_data; + n_data = {}; + n_data["" + options.selectedItemProp] = original_query; + n_data["" + options.selectedValuesProp] = original_query; + input.val('').focus(); + prev = ''; + addSelection(n_data, "00" + (selectionsContainer.find('li').length + 1)); + resultsContainer.hide(); + }, + mousedown: function() { + input_focus = false; + }, + mouseover: function() { + element = $(this); + resultsList.find('li').removeClass('active'); + element.addClass('active'); + } + }); + formatted.data('data', { + attributes: data[num], + num: num_count + }); + formatted = formatted.html('' + original_query + '' + options.creationText); + resultsList.append(formatted); + creation_hint = true; + } for (_k = 0, _len2 = data.length; _k < _len2; _k++) { item = data[_k]; num_count++; @@ -867,7 +901,7 @@ Based on the 1.6er release dated in July, 2012 num += 1; } selectionsContainer.removeClass('loading'); - if (matchCount <= 0) { + if (matchCount <= 0 && !creation_hint) { text = options.emptyText; if ($.type(options.emptyTextPlaceholder) === 'regexp') { text = text.replace(options.emptyTextPlaceholder, query); @@ -877,7 +911,7 @@ Based on the 1.6er release dated in July, 2012 resultsList.css({ width: selectionsContainer.outerWidth() }); - resultsContainerVisible = matchCount > 0 || options.showResultListWhenNoMatch; + resultsContainerVisible = matchCount > 0 || options.showResultListWhenNoMatch || options.creationText; if (resultsContainerVisible) { resultsContainer.show(); } diff --git a/dist/jquery.autoSuggest.min.js b/dist/jquery.autoSuggest.min.js index db134ee..775b5e6 100644 --- a/dist/jquery.autoSuggest.min.js +++ b/dist/jquery.autoSuggest.min.js @@ -3,4 +3,4 @@ * Copyright (c) 2013 Jan Philipp * Licensed MIT, GPL */ -!function(){var a,b,c,d,e,f,g,h=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1},i=[].slice;a=jQuery,e=function(){function b(){}return b.prototype._=void 0,b.escapeQuotes=function(a){return a?a.replace(/"/g,'\\"'):void 0},b.escapeHtml=function(b){return a("").text(b).html()},b.setPlaceholderEnabled=function(a,b){var c,d,e;d=["placeholder","disabled-placeholder"],b?(c=d[1],e=d[0]):(c=d[0],e=d[1]),!a.attr(e)&&a.attr(c)&&(a.attr(e,function(){return a.attr(c)}),a.removeAttr(c))},b}(),b=function(){function b(){}return b.prototype._=void 0,b.getExtraParams=function(b){var c,d,e,f,g,h,i;if(f=b.extraParams,a.isFunction(f)&&(f=f(this)),"string"===a.type(f)){for(c={},i=f.split("&"),g=0,h=i.length;h>g;g++)d=i[g],""!==d&&(e=d.split("=",2),e.length&&(c[e[0]]=e[1]));f=c}return f},b}(),d=function(){function b(a,b){this.hiddenField=a,this.items=null!=b?b:[]}return b.prototype._=void 0,b.prototype.hiddenField=null,b.prototype.items=null,b.prototype.syncToHiddenField=function(){var a,b,c,d,e;if(this.hiddenField){for(b="",e=this.items,c=0,d=e.length;d>c;c++)a=e[c],b+=","+a;b&&(b+=","),this.hiddenField.val(b||",")}},b.prototype.add=function(a){this.exist(a)||this.items.push(a),this.syncToHiddenField()},b.prototype.remove=function(b){this.items=a.grep(this.items,function(a){return a!==b}),this.syncToHiddenField()},b.prototype.isEmpty=function(){return 0===this.items.length},b.prototype.exist=function(b){return-1!==a.inArray(b,this.items)},b.prototype.getAll=function(){return this.items.slice(0)},b.prototype.clear=function(){this.items=[],this.syncToHiddenField()},b}(),c=function(){function b(){}return b.onSelectionAdd=function(b,c,d,f,g,h){var i;i=f.onSelectionAdd.call(b,c,d,f),e.setPlaceholderEnabled(b,0===h.length),a.isFunction(f.afterSelectionAdd)&&f.afterSelectionAdd.call(b,i,g,h)},b.onSelectionRemove=function(b,c,d,f,g){a.isFunction(d.onSelectionRemove)&&d.onSelectionRemove.call(b,c,d),e.setPlaceholderEnabled(b,0===g.length),a.isFunction(d.afterSelectionRemove)&&d.afterSelectionRemove.call(b,c,f,g)},b.onSelectionClick=function(b,c,d,f,g){a.isFunction(d.afterSelectionClick)&&d.afterSelectionClick.call(b,c,f,g),e.setPlaceholderEnabled(b,0===g.length)},b.onAjaxRequestDone=function(b,c,d){a.isFunction(d.onAjaxRequestDone)&&c.done(d.onAjaxRequestDone)},b.onAjaxRequestFail=function(b,c,d){a.isFunction(d.onAjaxRequestFail)&&c.fail(d.onAjaxRequestFail)},b.onAjaxRequestAlways=function(b,c,d){a.isFunction(d.onAjaxRequestAlways)&&c.always(d.onAjaxRequestAlways)},b}(),f={asHtmlID:!1,useOriginalInputName:!1,usePlaceholder:!1,preFill:null,startText:"Enter Name Here",emptyText:"No Results Found",emptyTextPlaceholder:/\{\d+\}/,limitText:"No More Selections Are Allowed",selectedItemProp:"value",selectedValuesProp:"value",searchActive:!0,searchObjProps:"value",queryParam:"q",limitParam:"limit",retrieveLimit:null,extraParams:null,matchCase:!1,minChars:1,keyDelay:400,resultsHighlight:!0,selectionLimit:!1,showResultList:!0,showResultListWhenNoMatch:!1,canGenerateNewSelections:!0,start:null,afterSelectionClick:null,afterSelectionAdd:null,afterSelectionRemove:null,onSelectionAdd:function(a,b){return a.before(b),a.prev()},onSelectionRemove:function(a,b){return b.fadeOut?a.fadeOut(b.fadeOut,function(){return a.remove()}):a.remove()},formatList:null,beforeRequest:null,afterRequest:null,onAjaxRequestDone:null,onAjaxRequestFail:null,onAjaxRequestAlways:null,onResultItemClick:null,afterResultListShow:null,neverSubmit:!1,preventPropagationOnEscape:!1,ajaxOptions:{type:"get",dataType:"json"},inputAttrs:{autocomplete:"off"},fadeOut:!1,remoteFilter:!1},g={init:function(g,i){var j,k;return i=a.extend({},f,i),j=null,"auto"===i.remoteFilter&&(i.remoteFilter="string"===a.type(g)),(k=function(){switch(a.type(g)){case"function":return g;case"string":return function(d,e){var f,h,k,l;l={},l[""+i.queryParam]=encodeURIComponent(decodeURIComponent(d)),i.retrieveLimit&&(l[i.limitParam]=encodeURIComponent(i.retrieveLimit)),h=b.getExtraParams(i),"object"===a.type(h)&&a.extend(l,h),f=a.extend({},i.ajaxOptions,{url:g,data:l}),k=function(b){return a.isFunction(i.afterRequest)&&(b=i.afterRequest.apply(this,[b])),e(b,d)},j=a.ajax(f).done(k),c.onAjaxRequestDone(this,j,i),c.onAjaxRequestFail(this,j,i),c.onAjaxRequestAlways(this,j,i)};case"array":case"object":return function(a,b){return b(g,a)}}}())?this.each(function(){var b,f,g,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R;switch(i.inputAttrs=a.extend(i.inputAttrs,{}),u=!1,s=a(this),m=null,n=null,o=null,p=null,q=null,i.asHtmlID?(m=i.asHtmlID,n=m,p="as-values-"+m,i.useOriginalInputName?(q=s.attr("name"),s.attr({name:"old_"+s.attr("name")})):q="as_values_"+m):(m=""+(m||"")+Math.floor(100*Math.random()),n="as-input-"+m,p="as-values-"+m,i.useOriginalInputName?(q=s.attr("name"),s.attr({name:"old_"+s.attr("name")})):q="as_values_"+m),i.inputAttrs.id=n,i.usePlaceholder||(i.inputAttrs.placeholder=i.startText),s.attr(i.inputAttrs),s.addClass("as-input"),i.usePlaceholder||s.val(i.startText),s.wrap('').wrap('
  • '),J=a("#as-selections-"+m),t=a("#as-original-"+m),H=a('
    '),I=a(''),o=a(''),l=new d(o),v=null,K=null,D="",z=!1,y=null,C=0,G={add:function(b){var c,d;c=a(J).find("li").length,d=f(b,"u"+c),null!=d&&d.addClass("blur")},remove:function(a){l.remove(a),J.find('li[data-value="'+e.escapeHtml(a)+'"]').remove()}},g=function(){return{add:G.add,remove:G.remove}},s.bind("addSelection",function(a,b){return G.add(b)}),s.bind("removeSelection",function(a,b){return G.remove(b)}),f=function(b,d){var f,g;return l.add(b[i.selectedValuesProp]),g=a('
  • '),g.on({click:function(){m=a(this),c.onSelectionClick(s,m,i,b[i.selectedValuesProp],l.getAll()),J.children().removeClass("selected"),m.addClass("selected")},mousedown:function(){u=!1}}),f=a('×'),f.click(function(){return l.remove(b[i.selectedValuesProp]),c.onSelectionRemove(s,g,i,null,l.getAll()),u=!0,s.focus(),!1}),"string"!=typeof b[i.selectedItemProp]?c.onSelectionAdd(s,t,g.append(b[i.selectedItemProp]).prepend(f),i,b,l.getAll()):c.onSelectionAdd(s,t,g.text(b[i.selectedItemProp]).prepend(f),i,b,l.getAll()),t.prev()},a.isFunction(i.start)&&i.start.call(this,g()),a.type(i.preFill)){case"string":for(Q=i.preFill.split(","),M=0,O=Q.length;O>M;M++)L=Q[M],w={},w[""+i.selectedValuesProp]=L,""!==L&&f(w,"000"+r);break;case"array":if(i.preFill.length)for(a.isFunction(i.afterRequest)&&(i.preFill=i.afterRequest.call(this,i.preFill)),R=i.preFill,r=N=0,P=R.length;P>N;r=++N)w=R[r],B=w[i.selectedValuesProp],"undefined"==typeof B&&(B=""),""!==B&&f(w,"000"+r)}return l.isEmpty()||(s.val(""),J.find("li.as-selection-item").addClass("blur").removeClass("selected"),e.setPlaceholderEnabled(s,!1)),s.after(o),J.on({click:function(){u=!0,s.focus()},mousedown:function(){J.children().removeClass("selected"),u=!1}}),J.after(H),x=function(){var a,b,c;return 46===y||h.call(function(){for(c=[],b=9;31>b;b++)c.push(b);return c}.apply(this),y)>=0?(H.hide(),void 0):(a=s.val().replace(/[\\]+|[\/]+/g,""),""===a||a!==D?(D=a,a.length>=i.minChars||0===i.minChars&&0===a.length?(J.addClass("loading"),F(a)):(J.removeClass("loading"),H.hide())):void 0)},F=function(c){return a.isFunction(i.beforeRequest)&&(c=i.beforeRequest.apply(this,[c,i])),b(),k(c,E)},E=function(b,c){var d,g,h,j,k,n,o,p,q,r,t,v,x,y,A;for(i.matchCase||(c=c.toLowerCase()),c=c.replace("(","(","g").replace(")",")","g"),h=0,H.hide().html(I.html("")),k=0,t=0,x=b.length;x>t;t++){if(w=b[t],C++,g=!1,"value"===i.searchObjProps)p=w.value;else for(p="",A=i.searchObjProps.split(","),v=0,y=A.length;y>v;v++)j=A[v],p+=""+w[a.trim(j)]+" ";if(p&&(i.matchCase||(p=p.toLowerCase()),i.searchActive&&(-1===p.indexOf(c)&&!i.remoteFilter||l.exist(w[i.selectedValuesProp]))||(g=!0)),g&&(d=a('
  • '),d.on({click:function(){var c,d;m=a(this),d=m.data("data"),c=d.num,J.find("#as-selection-"+c).length<=0&&!z&&(b=d.attributes,s.val("").focus(),D="",f(b,c),a.isFunction(i.onResultItemClick)&&i.onResultItemClick.call(this,d),H.hide()),z=!1},mousedown:function(){u=!1},mouseover:function(){m=a(this),I.find("li").removeClass("active"),m.addClass("active")}}),d.data("data",{attributes:b[k],num:C}),r=a.extend({},b[k]),c=c.replace(/"/g,'\\"'),n=i.matchCase?new RegExp("(?![^&;]+;)(?!<[^<>]*)("+e.escapeHtml(c)+")(?![^<>]*>)(?![^&;]+;)","g"):new RegExp("(?![^&;]+;)(?!<[^<>]*)("+e.escapeHtml(c)+")(?![^<>]*>)(?![^&;]+;)","gi"),"string"==typeof r[i.selectedItemProp]?(r[i.selectedItemProp]=e.escapeHtml(r[i.selectedItemProp]),i.resultsHighlight&&c.length>0&&(r[i.selectedItemProp]=r[i.selectedItemProp].replace(n,"$1"))):i.resultsHighlight&&c.length>0&&r[i.selectedItemProp].html(r[i.selectedItemProp].html().replace(n,"$1")),d=i.formatList?i.formatList.call(this,r,d):d.html(r[i.selectedItemProp]),I.append(d),h++,i.retrieveLimit&&i.retrieveLimit===h))break;k+=1}J.removeClass("loading"),0>=h&&(q=i.emptyText,"regexp"===a.type(i.emptyTextPlaceholder)&&(q=q.replace(i.emptyTextPlaceholder,c)),I.html('
  • '+q+"
  • ")),I.css({width:J.outerWidth()}),o=h>0||i.showResultListWhenNoMatch,o&&H.show(),a.isFunction(i.afterResultListShow)&&i.afterResultListShow.call(this,o)},A=function(a){var b,c,d;if(H.find(":visible").length){switch(c=H.find("li"),a){case"down":d=c.eq(0);break;default:d=c.filter(":last")}if(b=H.find("li.active:first"),b.length)switch(a){case"down":d=b.next();break;default:d=b.prev()}c.removeClass("active"),d.addClass("active")}},b=function(){j&&(j.abort(),j=null)},s.on({focus:function(){return m=a(this),!i.usePlaceholder&&m.val()===i.startText&&l.isEmpty()?m.val(""):u&&(J.find("li.as-selections-item").removeClass("blur"),""!==m.val()&&(I.css({width:J.outerWidth()}),H.show())),v&&clearInterval(v),v=setInterval(function(){i.showResultList&&(i.selectionLimit&&J.find("li.as-selection-item").length>=i.selectionLimit?(I.html('
  • '+i.limitText+"
  • "),H.show()):x())},i.keyDelay),u=!0,0===i.minChars&&F(m.val()),!0},blur:function(){m=a(this),!i.usePlaceholder&&""===m.val()&&l.isEmpty()&&i.minChars>0?m.val(i.startText):u&&(J.find("li.as-selection-item").addClass("blur").removeClass("selected"),H.hide()),v&&clearInterval(v),e.setPlaceholderEnabled(m,l.isEmpty())},keydown:function(d){var g,h,j,k,m,n;switch(y=d.keyCode,h=!1,d.keyCode){case 38:d.preventDefault(),A("up");break;case 40:d.preventDefault(),a(":visible",H).length>0?A("down"):(K&&clearTimeout(K),K=setTimeout(function(){x()},i.keyDelay));break;case 8:""===s.val()&&(n=l.getAll(),m=null,m=n.length?n[n.length-1]:null,J.children().not(t.prev()).removeClass("selected"),t.prev().hasClass("selected")?(l.remove(m),c.onSelectionRemove(s,t.prev(),i,null,l.getAll())):(c.onSelectionClick(s,t.prev(),i,null,l.getAll()),t.prev().addClass("selected"))),1===s.val().length&&(H.hide(),D="",b()),H.find(":visible").length&&(K&&clearTimeout(K),K=setTimeout(function(){x()},i.keyDelay));break;case 9:case 188:case 13:g=H.find("li.active:visible:first"),i.canGenerateNewSelections?(z=!0,j=s.val().replace(/(,)/g,""),""!==j&&!l.exist(j)&&j.length>=i.minChars&&0===g.length&&(i.neverSubmit||13!==d.keyCode)&&(d.preventDefault(),k={},k[""+i.selectedItemProp]=j,k[""+i.selectedValuesProp]=j,f(k,"00"+(J.find("li").length+1)),s.val(""),b())):s.val(""),g.length&&(z=!1,g.click(),H.hide(),d.preventDefault());break;case 13:z=!1,g=H.find("li.active:first"),g.length&&(g.click(),H.hide()),(i.neverSubmit||g.length)&&d.preventDefault();break;case 27:i.preventPropagationOnEscape&&H.find(":visible").length&&d.stopPropagation();break;case 16:case 20:b(),H.hide()}e.setPlaceholderEnabled(s,l.isEmpty())}})}):void 0},add:function(){var b,c,d,e,f;for(d=1<=arguments.length?i.call(arguments,0):[],b=a(this),e=0,f=d.length;f>e;e++)c=d[e],b.trigger("addSelection",c)},remove:function(){var b,c,d,e,f;for(d=1<=arguments.length?i.call(arguments,0):[],b=a(this),e=0,f=d.length;f>e;e++)c=d[e],b.trigger("removeSelection",c)},defaults:function(b,c){null==c&&(c=!1),c&&(f={}),a.extend(f,b)}},a.fn.autoSuggest=function(a){return g[a]?g[a].apply(this,Array.prototype.slice.call(arguments,1)):g.init.apply(this,arguments)}}.call(this); \ No newline at end of file +!function(){var a,b,c,d,e,f,g,h=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1},i=[].slice;a=jQuery,e=function(){function b(){}return b.prototype._=void 0,b.escapeQuotes=function(a){return a?a.replace(/"/g,'\\"'):void 0},b.escapeHtml=function(b){return a("").text(b).html()},b.setPlaceholderEnabled=function(a,b){var c,d,e;d=["placeholder","disabled-placeholder"],b?(c=d[1],e=d[0]):(c=d[0],e=d[1]),!a.attr(e)&&a.attr(c)&&(a.attr(e,function(){return a.attr(c)}),a.removeAttr(c))},b}(),b=function(){function b(){}return b.prototype._=void 0,b.getExtraParams=function(b){var c,d,e,f,g,h,i;if(f=b.extraParams,a.isFunction(f)&&(f=f(this)),"string"===a.type(f)){for(c={},i=f.split("&"),g=0,h=i.length;h>g;g++)d=i[g],""!==d&&(e=d.split("=",2),e.length&&(c[e[0]]=e[1]));f=c}return f},b}(),d=function(){function b(a,b){this.hiddenField=a,this.items=null!=b?b:[]}return b.prototype._=void 0,b.prototype.hiddenField=null,b.prototype.items=null,b.prototype.syncToHiddenField=function(){var a,b,c,d,e;if(this.hiddenField){for(b="",e=this.items,c=0,d=e.length;d>c;c++)a=e[c],b+=","+a;b&&(b+=","),this.hiddenField.val(b||",")}},b.prototype.add=function(a){this.exist(a)||this.items.push(a),this.syncToHiddenField()},b.prototype.remove=function(b){this.items=a.grep(this.items,function(a){return a!==b}),this.syncToHiddenField()},b.prototype.isEmpty=function(){return 0===this.items.length},b.prototype.exist=function(b){return-1!==a.inArray(b,this.items)},b.prototype.getAll=function(){return this.items.slice(0)},b.prototype.clear=function(){this.items=[],this.syncToHiddenField()},b}(),c=function(){function b(){}return b.onSelectionAdd=function(b,c,d,f,g,h){var i;i=f.onSelectionAdd.call(b,c,d,f),e.setPlaceholderEnabled(b,0===h.length),a.isFunction(f.afterSelectionAdd)&&f.afterSelectionAdd.call(b,i,g,h)},b.onSelectionRemove=function(b,c,d,f,g){a.isFunction(d.onSelectionRemove)&&d.onSelectionRemove.call(b,c,d),e.setPlaceholderEnabled(b,0===g.length),a.isFunction(d.afterSelectionRemove)&&d.afterSelectionRemove.call(b,c,f,g)},b.onSelectionClick=function(b,c,d,f,g){a.isFunction(d.afterSelectionClick)&&d.afterSelectionClick.call(b,c,f,g),e.setPlaceholderEnabled(b,0===g.length)},b.onAjaxRequestDone=function(b,c,d){a.isFunction(d.onAjaxRequestDone)&&c.done(d.onAjaxRequestDone)},b.onAjaxRequestFail=function(b,c,d){a.isFunction(d.onAjaxRequestFail)&&c.fail(d.onAjaxRequestFail)},b.onAjaxRequestAlways=function(b,c,d){a.isFunction(d.onAjaxRequestAlways)&&c.always(d.onAjaxRequestAlways)},b}(),f={asHtmlID:!1,useOriginalInputName:!1,usePlaceholder:!1,preFill:null,startText:"Enter Name Here",emptyText:"No Results Found",emptyTextPlaceholder:/\{\d+\}/,limitText:"No More Selections Are Allowed",selectedItemProp:"value",selectedValuesProp:"value",searchActive:!0,searchObjProps:"value",queryParam:"q",limitParam:"limit",retrieveLimit:null,extraParams:null,matchCase:!1,minChars:1,keyDelay:400,resultsHighlight:!0,selectionLimit:!1,showResultList:!0,showResultListWhenNoMatch:!1,canGenerateNewSelections:!0,start:null,afterSelectionClick:null,afterSelectionAdd:null,afterSelectionRemove:null,onSelectionAdd:function(a,b){return a.before(b),a.prev()},onSelectionRemove:function(a,b){return b.fadeOut?a.fadeOut(b.fadeOut,function(){return a.remove()}):a.remove()},formatList:null,beforeRequest:null,afterRequest:null,onAjaxRequestDone:null,onAjaxRequestFail:null,onAjaxRequestAlways:null,onResultItemClick:null,afterResultListShow:null,neverSubmit:!1,preventPropagationOnEscape:!1,ajaxOptions:{type:"get",dataType:"json"},inputAttrs:{autocomplete:"off"},fadeOut:!1,remoteFilter:!1},g={init:function(g,i){var j,k;return i=a.extend({},f,i),j=null,"auto"===i.remoteFilter&&(i.remoteFilter="string"===a.type(g)),(k=function(){switch(a.type(g)){case"function":return g;case"string":return function(d,e){var f,h,k,l;l={},l[""+i.queryParam]=encodeURIComponent(decodeURIComponent(d)),i.retrieveLimit&&(l[i.limitParam]=encodeURIComponent(i.retrieveLimit)),h=b.getExtraParams(i),"object"===a.type(h)&&a.extend(l,h),f=a.extend({},i.ajaxOptions,{url:g,data:l}),k=function(b){return a.isFunction(i.afterRequest)&&(b=i.afterRequest.apply(this,[b])),e(b,d)},j=a.ajax(f).done(k),c.onAjaxRequestDone(this,j,i),c.onAjaxRequestFail(this,j,i),c.onAjaxRequestAlways(this,j,i)};case"array":case"object":return function(a,b){return b(g,a)}}}())?this.each(function(){var b,f,g,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R;switch(i.inputAttrs=a.extend(i.inputAttrs,{}),u=!1,s=a(this),m=null,n=null,o=null,p=null,q=null,i.asHtmlID?(m=i.asHtmlID,n=m,p="as-values-"+m,i.useOriginalInputName?(q=s.attr("name"),s.attr({name:"old_"+s.attr("name")})):q="as_values_"+m):(m=""+(m||"")+Math.floor(100*Math.random()),n="as-input-"+m,p="as-values-"+m,i.useOriginalInputName?(q=s.attr("name"),s.attr({name:"old_"+s.attr("name")})):q="as_values_"+m),i.inputAttrs.id=n,i.usePlaceholder||(i.inputAttrs.placeholder=i.startText),s.attr(i.inputAttrs),s.addClass("as-input"),i.usePlaceholder||s.val(i.startText),s.wrap('
      ').wrap('
    • '),J=a("#as-selections-"+m),t=a("#as-original-"+m),H=a('
      '),I=a('
        '),o=a(''),l=new d(o),v=null,K=null,D="",z=!1,y=null,C=0,G={add:function(b){var c,d;c=a(J).find("li").length,d=f(b,"u"+c),null!=d&&d.addClass("blur")},remove:function(a){l.remove(a),J.find('li[data-value="'+e.escapeHtml(a)+'"]').remove()}},g=function(){return{add:G.add,remove:G.remove}},s.bind("addSelection",function(a,b){return G.add(b)}),s.bind("removeSelection",function(a,b){return G.remove(b)}),f=function(b,d){var f,g;return l.add(b[i.selectedValuesProp]),g=a('
      • '),g.on({click:function(){m=a(this),c.onSelectionClick(s,m,i,b[i.selectedValuesProp],l.getAll()),J.children().removeClass("selected"),m.addClass("selected")},mousedown:function(){u=!1}}),f=a('×'),f.click(function(){return l.remove(b[i.selectedValuesProp]),c.onSelectionRemove(s,g,i,null,l.getAll()),u=!0,s.focus(),!1}),"string"!=typeof b[i.selectedItemProp]?c.onSelectionAdd(s,t,g.append(b[i.selectedItemProp]).prepend(f),i,b,l.getAll()):c.onSelectionAdd(s,t,g.text(b[i.selectedItemProp]).prepend(f),i,b,l.getAll()),t.prev()},a.isFunction(i.start)&&i.start.call(this,g()),a.type(i.preFill)){case"string":for(Q=i.preFill.split(","),M=0,O=Q.length;O>M;M++)L=Q[M],w={},w[""+i.selectedValuesProp]=L,""!==L&&f(w,"000"+r);break;case"array":if(i.preFill.length)for(a.isFunction(i.afterRequest)&&(i.preFill=i.afterRequest.call(this,i.preFill)),R=i.preFill,r=N=0,P=R.length;P>N;r=++N)w=R[r],B=w[i.selectedValuesProp],"undefined"==typeof B&&(B=""),""!==B&&f(w,"000"+r)}return l.isEmpty()||(s.val(""),J.find("li.as-selection-item").addClass("blur").removeClass("selected"),e.setPlaceholderEnabled(s,!1)),s.after(o),J.on({click:function(){u=!0,s.focus()},mousedown:function(){J.children().removeClass("selected"),u=!1}}),J.after(H),x=function(){var a,b,c;return 46===y||h.call(function(){for(c=[],b=9;31>b;b++)c.push(b);return c}.apply(this),y)>=0?(H.hide(),void 0):(a=s.val().replace(/[\\]+|[\/]+/g,""),""===a||a!==D?(D=a,a.length>=i.minChars||0===i.minChars&&0===a.length?(J.addClass("loading"),F(a)):(J.removeClass("loading"),H.hide())):void 0)},F=function(c){return a.isFunction(i.beforeRequest)&&(c=i.beforeRequest.apply(this,[c,i])),b(),k(c,E)},E=function(b,c){var d,g,h,j,k,n,o,p,q,r,t,v,x,y,A,B,E;for(d=!1,o=c,i.matchCase||(c=c.toLowerCase()),c=c.replace("(","(","g").replace(")",")","g"),j=0,H.hide().html(I.html("")),n=0,i.creationText&&0===a.grep(b,function(a){return a[i.selectedItemProp].toLowerCase()===c}).length&&!l.exist(c)&&(g=a('
      • '),g.on({click:function(){var a;a={},a[""+i.selectedItemProp]=o,a[""+i.selectedValuesProp]=o,s.val("").focus(),D="",f(a,"00"+(J.find("li").length+1)),H.hide()},mousedown:function(){u=!1},mouseover:function(){m=a(this),I.find("li").removeClass("active"),m.addClass("active")}}),g.data("data",{attributes:b[n],num:C}),g=g.html(""+o+""+i.creationText),I.append(g),d=!0),x=0,A=b.length;A>x;x++){if(w=b[x],C++,h=!1,"value"===i.searchObjProps)r=w.value;else for(r="",E=i.searchObjProps.split(","),y=0,B=E.length;B>y;y++)k=E[y],r+=""+w[a.trim(k)]+" ";if(r&&(i.matchCase||(r=r.toLowerCase()),i.searchActive&&(-1===r.indexOf(c)&&!i.remoteFilter||l.exist(w[i.selectedValuesProp]))||(h=!0)),h&&(g=a('
      • '),g.on({click:function(){var c,d;m=a(this),d=m.data("data"),c=d.num,J.find("#as-selection-"+c).length<=0&&!z&&(b=d.attributes,s.val("").focus(),D="",f(b,c),a.isFunction(i.onResultItemClick)&&i.onResultItemClick.call(this,d),H.hide()),z=!1},mousedown:function(){u=!1},mouseover:function(){m=a(this),I.find("li").removeClass("active"),m.addClass("active")}}),g.data("data",{attributes:b[n],num:C}),v=a.extend({},b[n]),c=c.replace(/"/g,'\\"'),p=i.matchCase?new RegExp("(?![^&;]+;)(?!<[^<>]*)("+e.escapeHtml(c)+")(?![^<>]*>)(?![^&;]+;)","g"):new RegExp("(?![^&;]+;)(?!<[^<>]*)("+e.escapeHtml(c)+")(?![^<>]*>)(?![^&;]+;)","gi"),"string"==typeof v[i.selectedItemProp]?(v[i.selectedItemProp]=e.escapeHtml(v[i.selectedItemProp]),i.resultsHighlight&&c.length>0&&(v[i.selectedItemProp]=v[i.selectedItemProp].replace(p,"$1"))):i.resultsHighlight&&c.length>0&&v[i.selectedItemProp].html(v[i.selectedItemProp].html().replace(p,"$1")),g=i.formatList?i.formatList.call(this,v,g):g.html(v[i.selectedItemProp]),I.append(g),j++,i.retrieveLimit&&i.retrieveLimit===j))break;n+=1}J.removeClass("loading"),0>=j&&!d&&(t=i.emptyText,"regexp"===a.type(i.emptyTextPlaceholder)&&(t=t.replace(i.emptyTextPlaceholder,c)),I.html('
      • '+t+"
      • ")),I.css({width:J.outerWidth()}),q=j>0||i.showResultListWhenNoMatch||i.creationText,q&&H.show(),a.isFunction(i.afterResultListShow)&&i.afterResultListShow.call(this,q)},A=function(a){var b,c,d;if(H.find(":visible").length){switch(c=H.find("li"),a){case"down":d=c.eq(0);break;default:d=c.filter(":last")}if(b=H.find("li.active:first"),b.length)switch(a){case"down":d=b.next();break;default:d=b.prev()}c.removeClass("active"),d.addClass("active")}},b=function(){j&&(j.abort(),j=null)},s.on({focus:function(){return m=a(this),!i.usePlaceholder&&m.val()===i.startText&&l.isEmpty()?m.val(""):u&&(J.find("li.as-selections-item").removeClass("blur"),""!==m.val()&&(I.css({width:J.outerWidth()}),H.show())),v&&clearInterval(v),v=setInterval(function(){i.showResultList&&(i.selectionLimit&&J.find("li.as-selection-item").length>=i.selectionLimit?(I.html('
      • '+i.limitText+"
      • "),H.show()):x())},i.keyDelay),u=!0,0===i.minChars&&F(m.val()),!0},blur:function(){m=a(this),!i.usePlaceholder&&""===m.val()&&l.isEmpty()&&i.minChars>0?m.val(i.startText):u&&(J.find("li.as-selection-item").addClass("blur").removeClass("selected"),H.hide()),v&&clearInterval(v),e.setPlaceholderEnabled(m,l.isEmpty())},keydown:function(d){var g,h,j,k,m,n;switch(y=d.keyCode,h=!1,d.keyCode){case 38:d.preventDefault(),A("up");break;case 40:d.preventDefault(),a(":visible",H).length>0?A("down"):(K&&clearTimeout(K),K=setTimeout(function(){x()},i.keyDelay));break;case 8:""===s.val()&&(n=l.getAll(),m=null,m=n.length?n[n.length-1]:null,J.children().not(t.prev()).removeClass("selected"),t.prev().hasClass("selected")?(l.remove(m),c.onSelectionRemove(s,t.prev(),i,null,l.getAll())):(c.onSelectionClick(s,t.prev(),i,null,l.getAll()),t.prev().addClass("selected"))),1===s.val().length&&(H.hide(),D="",b()),H.find(":visible").length&&(K&&clearTimeout(K),K=setTimeout(function(){x()},i.keyDelay));break;case 9:case 188:case 13:g=H.find("li.active:visible:first"),i.canGenerateNewSelections?(z=!0,j=s.val().replace(/(,)/g,""),""!==j&&!l.exist(j)&&j.length>=i.minChars&&0===g.length&&(i.neverSubmit||13!==d.keyCode)&&(d.preventDefault(),k={},k[""+i.selectedItemProp]=j,k[""+i.selectedValuesProp]=j,f(k,"00"+(J.find("li").length+1)),s.val(""),b())):s.val(""),g.length&&(z=!1,g.click(),H.hide(),d.preventDefault());break;case 13:z=!1,g=H.find("li.active:first"),g.length&&(g.click(),H.hide()),(i.neverSubmit||g.length)&&d.preventDefault();break;case 27:i.preventPropagationOnEscape&&H.find(":visible").length&&d.stopPropagation();break;case 16:case 20:b(),H.hide()}e.setPlaceholderEnabled(s,l.isEmpty())}})}):void 0},add:function(){var b,c,d,e,f;for(d=1<=arguments.length?i.call(arguments,0):[],b=a(this),e=0,f=d.length;f>e;e++)c=d[e],b.trigger("addSelection",c)},remove:function(){var b,c,d,e,f;for(d=1<=arguments.length?i.call(arguments,0):[],b=a(this),e=0,f=d.length;f>e;e++)c=d[e],b.trigger("removeSelection",c)},defaults:function(b,c){null==c&&(c=!1),c&&(f={}),a.extend(f,b)}},a.fn.autoSuggest=function(a){return g[a]?g[a].apply(this,Array.prototype.slice.call(arguments,1)):g.init.apply(this,arguments)}}.call(this); \ No newline at end of file diff --git a/src/jquery.autoSuggest.coffee b/src/jquery.autoSuggest.coffee index 3154736..b0bad2b 100644 --- a/src/jquery.autoSuggest.coffee +++ b/src/jquery.autoSuggest.coffee @@ -676,12 +676,40 @@ pluginMethods = fetcher string, processData processData = (data, query) -> + creation_hint = false + original_query = query if !options.matchCase query = query.toLowerCase() query = query.replace('(', '\(', 'g').replace(')', '\)', 'g') matchCount = 0 resultsContainer.hide().html(resultsList.html('')) num = 0 + if options.canGenerateNewSelections && options.creationText && $.grep(data, (item) -> item[options.selectedItemProp].toLowerCase() == query ).length is 0 && !currentSelection.exist(query) + formatted = $("
      • ") + formatted.on + click : -> + n_data = {} + n_data["#{options.selectedItemProp}"] = original_query + n_data["#{options.selectedValuesProp}"] = original_query + input.val('').focus() + prev = '' + addSelection n_data, "00#{selectionsContainer.find('li').length + 1}" + resultsContainer.hide() + return + mousedown : -> + input_focus = false + return + mouseover : -> + element = $(this) + resultsList.find('li').removeClass 'active' + element.addClass 'active' + return + formatted.data 'data', + attributes : data[num] + num : num_count + formatted = formatted.html '' + original_query + '' + options.creationText + resultsList.append formatted + creation_hint = true for item in data num_count++ forward = false @@ -749,13 +777,13 @@ pluginMethods = break num += 1 selectionsContainer.removeClass 'loading' - if matchCount <= 0 + if matchCount <= 0 && !creation_hint text = options.emptyText if $.type(options.emptyTextPlaceholder) is 'regexp' text = text.replace options.emptyTextPlaceholder, query resultsList.html "
      • #{text}
      • " resultsList.css width : selectionsContainer.outerWidth() - resultsContainerVisible = matchCount > 0 || options.showResultListWhenNoMatch + resultsContainerVisible = matchCount > 0 || options.showResultListWhenNoMatch || options.creationText if resultsContainerVisible resultsContainer.show() if $.isFunction(options.afterResultListShow) then options.afterResultListShow.call this, resultsContainerVisible diff --git a/test/jquery.autoSuggest_test.js b/test/jquery.autoSuggest_test.js index 8d9f2d3..b357208 100644 --- a/test/jquery.autoSuggest_test.js +++ b/test/jquery.autoSuggest_test.js @@ -501,6 +501,52 @@ remove(); }); + module('Configuration: "options.creationText"', { + teardown : function () { + remove(); + } + }); + + asyncTest('Type Bobby and see the creation message next to it in the list', 4, function () { + el = create(null, $.extend({}, options, { + creationText : ' - Add this keyword' + })); + $.simulate2.triggerKeyEventsForString(el, 'Bobby', 0, true); + + setTimeout(function () { + // Here goes three suggestions + res = results(); + equal(res.length, 1, "Should suggest 1 names"); + equal($(res[0]).text(), "Bobby - Add this keyword", "Should be Bobby - Add this keyword"); + + // Select Bobby + $(res[0]).simulate("click"); + sel = selections(); + equal(sel.length, 1, "Should have one name"); + equal($(sel[0]).text(), "×Bobby", "Should be Bobby"); + + start(); + remove(); + }, 500); + }); + + asyncTest('Type mick jagger and see that the creation bubble is not displayed', 2, function () { + el = create(null, $.extend({}, options, { + creationText : ' - Add this keyword' + })); + $.simulate2.triggerKeyEventsForString(el, 'mick jagger', 0, true); + + setTimeout(function () { + // Here goes three suggestions + res = results(); + equal(res.length, 1, "Should suggest 1 names"); + equal($(res[0]).text(), "Mick Jagger", "Should be Mick Jagger"); + + start(); + remove(); + }, 500); + }); + module('Configuration: "onAjaxRequestAlways"', { teardown : function () { remove();