|
76 | 76 | onFinish: null,
|
77 | 77 | matchStringConverter: null,
|
78 | 78 | beforeUseConverter: null,
|
79 |
| - autoWidth: 'min-width' |
| 79 | + autoWidth: 'min-width', |
| 80 | + useDelimiter: false, |
| 81 | + delimiterChar: ',', |
| 82 | + delimiterKeyCode: 188 |
80 | 83 | };
|
81 | 84 |
|
82 | 85 | /**
|
|
322 | 325 | self.lastKeyPressed_ = e.keyCode;
|
323 | 326 | switch(self.lastKeyPressed_) {
|
324 | 327 |
|
| 328 | + case self.options.delimiterKeyCode: // comma = 188 |
| 329 | + if (self.options.useDelimiter && self.active_) { |
| 330 | + self.selectCurrent(); |
| 331 | + } |
| 332 | + break; |
| 333 | + |
| 334 | + // ignore navigational & special keys |
| 335 | + case 35: // end |
| 336 | + case 36: // home |
| 337 | + case 16: // shift |
| 338 | + case 17: // ctrl |
| 339 | + case 18: // alt |
| 340 | + case 37: // left |
| 341 | + case 39: // right |
| 342 | + break; |
| 343 | + |
325 | 344 | case 38: // up
|
326 | 345 | e.preventDefault();
|
327 | 346 | if (self.active_) {
|
|
710 | 729 | * @param b
|
711 | 730 | */
|
712 | 731 | $.Autocompleter.prototype.beforeUseConverter = function(s, a, b) {
|
| 732 | + s = this.getValue(); |
713 | 733 | var converter = this.options.beforeUseConverter;
|
714 | 734 | if ($.isFunction(converter)) {
|
715 | 735 | s = converter(s, a, b);
|
|
813 | 833 | valueLength = value.length;
|
814 | 834 | filterLength = filter.length;
|
815 | 835 | if (lcValue.substr(0, filterLength) === lcFilter) {
|
816 |
| - this.dom.$elem.val(value); |
817 |
| - this.selectRange(filterLength, valueLength); |
| 836 | + var d = this.getDelimiterOffsets(); |
| 837 | + if ( d.start == 0 ) { |
| 838 | + this.setValue(value); |
| 839 | + this.selectRange(filterLength + d.start, valueLength + d.start); |
| 840 | + } else { |
| 841 | + this.setValue(' ' + value); |
| 842 | + this.selectRange(filterLength + d.start + 1, valueLength + d.start + 1); |
| 843 | + } |
818 | 844 | return true;
|
819 | 845 | }
|
820 | 846 | }
|
|
879 | 905 | var processedDisplayValue = this.beforeUseConverter(displayValue);
|
880 | 906 | this.lastProcessedValue_ = processedDisplayValue;
|
881 | 907 | this.lastSelectedValue_ = processedDisplayValue;
|
882 |
| - this.dom.$elem.val(displayValue).focus(); |
883 |
| - this.setCaret(displayValue.length); |
| 908 | + var d = this.getDelimiterOffsets(); |
| 909 | + var delimiter = this.options.delimiterChar; |
| 910 | + var elem = this.dom.$elem; |
| 911 | + var extraCaretPos = 0; |
| 912 | + if ( this.options.useDelimiter ) { |
| 913 | + // if there is a preceding delimiter, add a space after the delimiter |
| 914 | + if ( elem.val().substring(d.start-1, d.start) == delimiter ) { |
| 915 | + displayValue = ' ' + displayValue; |
| 916 | + } |
| 917 | + // if there is not already a delimiter trailing this value, add it |
| 918 | + if ( elem.val().substring(d.end, d.end+1) != delimiter && this.lastKeyPressed_ != this.options.delimiterKeyCode ) { |
| 919 | + displayValue = displayValue + delimiter; |
| 920 | + } else { |
| 921 | + // move the cursor after the existing trailing delimiter |
| 922 | + extraCaretPos = 1; |
| 923 | + } |
| 924 | + } |
| 925 | + this.setValue(displayValue); |
| 926 | + elem.focus(); |
| 927 | + this.setCaret(d.start + displayValue.length + extraCaretPos); |
884 | 928 | this.callHook('onItemSelect', { value: value, data: data });
|
885 |
| - this.deactivate(false); |
| 929 | + this.deactivate(true); |
886 | 930 | };
|
887 | 931 |
|
888 | 932 | $.Autocompleter.prototype.displayValue = function(value, data) {
|
|
906 | 950 | if (finish) {
|
907 | 951 | if (this.lastProcessedValue_ !== this.lastSelectedValue_) {
|
908 | 952 | if (this.options.mustMatch) {
|
909 |
| - this.dom.$elem.val(''); |
| 953 | + this.setValue(''); |
910 | 954 | }
|
911 | 955 | this.callHook('onNoMatch');
|
912 | 956 | }
|
|
943 | 987 | this.selectRange(pos, pos);
|
944 | 988 | };
|
945 | 989 |
|
| 990 | + /** |
| 991 | + * Get caret position |
| 992 | + */ |
| 993 | + $.Autocompleter.prototype.getCaret = function() { |
| 994 | + var elem = this.dom.$elem; |
| 995 | + if ($.browser.msie) { |
| 996 | + // ie |
| 997 | + var selection = document.selection; |
| 998 | + if (elem[0].tagName.toLowerCase() != 'textarea') { |
| 999 | + var val = elem.val(); |
| 1000 | + var range = selection.createRange().duplicate(); |
| 1001 | + range.moveEnd('character', val.length); |
| 1002 | + var s = ( range.text == '' ? val.length : val.lastIndexOf(range.text) ); |
| 1003 | + range = selection.createRange().duplicate(); |
| 1004 | + range.moveStart('character', -val.length); |
| 1005 | + var e = range.text.length; |
| 1006 | + } else { |
| 1007 | + var range = selection.createRange(); |
| 1008 | + var stored_range = range.duplicate(); |
| 1009 | + stored_range.moveToElementText(elem[0]); |
| 1010 | + stored_range.setEndPoint('EndToEnd', range); |
| 1011 | + var s = stored_range.text.length - range.text.length; |
| 1012 | + var e = s + range.text.length; |
| 1013 | + } |
| 1014 | + } else { |
| 1015 | + // ff, chrome, safari |
| 1016 | + var s = elem[0].selectionStart; |
| 1017 | + var e = elem[0].selectionEnd; |
| 1018 | + } |
| 1019 | + return { |
| 1020 | + start: s, |
| 1021 | + end: e |
| 1022 | + }; |
| 1023 | + }; |
| 1024 | + |
| 1025 | + /** |
| 1026 | + * Set the value that is currently being autocompleted |
| 1027 | + * @param {String} value |
| 1028 | + */ |
| 1029 | + $.Autocompleter.prototype.setValue = function(value) { |
| 1030 | + if ( this.options.useDelimiter ) { |
| 1031 | + // set the substring between the current delimiters |
| 1032 | + var val = this.dom.$elem.val(); |
| 1033 | + var d = this.getDelimiterOffsets(); |
| 1034 | + var preVal = val.substring(0, d.start); |
| 1035 | + var postVal = val.substring(d.end); |
| 1036 | + value = preVal + value + postVal; |
| 1037 | + } |
| 1038 | + this.dom.$elem.val(value); |
| 1039 | + }; |
| 1040 | + |
| 1041 | + /** |
| 1042 | + * Get the value currently being autocompleted |
| 1043 | + * @param {String} value |
| 1044 | + */ |
| 1045 | + $.Autocompleter.prototype.getValue = function() { |
| 1046 | + var val = this.dom.$elem.val(); |
| 1047 | + if ( this.options.useDelimiter ) { |
| 1048 | + var d = this.getDelimiterOffsets(); |
| 1049 | + return val.substring(d.start, d.end).trim(); |
| 1050 | + } else { |
| 1051 | + return val; |
| 1052 | + } |
| 1053 | + }; |
| 1054 | + |
| 1055 | + /** |
| 1056 | + * Get the offsets of the value currently being autocompleted |
| 1057 | + */ |
| 1058 | + $.Autocompleter.prototype.getDelimiterOffsets = function() { |
| 1059 | + var val = this.dom.$elem.val(); |
| 1060 | + if ( this.options.useDelimiter ) { |
| 1061 | + var preCaretVal = val.substring(0, this.getCaret().start); |
| 1062 | + var start = preCaretVal.lastIndexOf(this.options.delimiterChar) + 1; |
| 1063 | + var postCaretVal = val.substring(this.getCaret().start); |
| 1064 | + var end = postCaretVal.indexOf(this.options.delimiterChar); |
| 1065 | + if ( end == -1 ) end = val.length; |
| 1066 | + end += this.getCaret().start; |
| 1067 | + } else { |
| 1068 | + start = 0; |
| 1069 | + end = val.length; |
| 1070 | + } |
| 1071 | + return { |
| 1072 | + start: start, |
| 1073 | + end: end |
| 1074 | + }; |
| 1075 | + }; |
| 1076 | + |
946 | 1077 | })(jQuery);
|
0 commit comments