From f7b0d012523af9945097570a1d47f52cd40928a4 Mon Sep 17 00:00:00 2001 From: Sergio Dinis Lopes Date: Mon, 13 Feb 2017 00:49:02 +0000 Subject: [PATCH] added search by word option minor fixes requestMethod is now 'get' by default --- jquery.flexdatalist.css | 18 +++-- jquery.flexdatalist.js | 142 +++++++++++++++++++++++------------- jquery.flexdatalist.min.css | 2 +- jquery.flexdatalist.min.js | 2 +- 4 files changed, 103 insertions(+), 61 deletions(-) diff --git a/jquery.flexdatalist.css b/jquery.flexdatalist.css index 221220a..e4eb68e 100644 --- a/jquery.flexdatalist.css +++ b/jquery.flexdatalist.css @@ -63,7 +63,7 @@ .flexdatalist-multiple { width: 100%; margin: 0; - padding: 0 0 0 10px; + padding: 0; list-style: none; text-align: left; cursor: text; @@ -80,7 +80,7 @@ .flexdatalist-multiple li { display: inline-block; position: relative; - margin: 5px 5px 5px 0; + margin: 5px; float: left; } .flexdatalist-multiple li.input-container, @@ -88,14 +88,16 @@ border: none; width: 280px; height: auto; - padding: 0; - line-height: 25px; + padding: 0 0 0 4px; + line-height: 24px; } .flexdatalist-multiple li.value { display: inline-block; - padding: 2px 25px 2px 5px; - background: #efefef; + padding: 2px 25px 2px 7px; + background: #eee; border-radius: 3px; + color: #777; + line-height: 20px; } .flexdatalist-multiple li.toggle { cursor: pointer; @@ -108,9 +110,9 @@ .flexdatalist-multiple li.value span.fdl-remove { font-weight: 700; - padding: 0 5px; + padding: 2px 5px; font-size: 20px; - line-height: 25px; + line-height: 20px; cursor: pointer; position: absolute; top: 0; diff --git a/jquery.flexdatalist.js b/jquery.flexdatalist.js index 998dece..5e068fd 100644 --- a/jquery.flexdatalist.js +++ b/jquery.flexdatalist.js @@ -62,7 +62,7 @@ jQuery.fn.flexdatalist = function (options, value) { searchIn: ['label'], searchContain: false, searchEqual: false, - searchByWord: true, + searchByWord: false, searchDisabled: false, normalizeString: null, multiple: $this.attr('multiple'), @@ -70,7 +70,7 @@ jQuery.fn.flexdatalist = function (options, value) { noResultsText: 'No results found for "{keyword}"', toggleSelected: false, allowDuplicateValues: false, - requestType: 'post', + requestType: 'get', limitOfValues: 0, _values: [] }, @@ -108,7 +108,8 @@ jQuery.fn.flexdatalist = function (options, value) { 'border-color': $this.css('border-left-color'), 'border-width': $this.css('border-left-width'), 'border-style': $this.css('border-left-style'), - 'border-radius': $this.css('border-top-left-radius') + 'border-radius': $this.css('border-top-left-radius'), + 'background-color': $this.css('background-color') }) .insertAfter($this).click(function () { $(this).find('input').focus(); @@ -127,11 +128,15 @@ jQuery.fn.flexdatalist = function (options, value) { } // Listen to parent input key presses and state events. - $_this.on('input keydown', function (event) { + $_this + // Keydown + .on('input keydown', function (event) { var val = $this._keyword(); // Comma separated values if ((_this._keyNum(event) === 188 || _this._keyNum(event) === 13) - && !_options.selectionRequired && _options.multiple) { + && !_options.selectionRequired + && _options.multiple + && !$this._resultSelected()) { event.preventDefault(); $this._value(val); $this._removeResults(); @@ -142,23 +147,26 @@ jQuery.fn.flexdatalist = function (options, value) { } else if (val.length === 0 && _options.multiple && _this._keyNum(event) === 8) { $_this.data('_remove', $_this.parents('li:eq(0)').prev()); } + + // Keyup }).on('input keyup', function (event) { if ($this._changed() && _this._keyNum(event) !== 13) { var keyword = $this._keyword(); - if (keyword.length >= _options.minLength) { - $this._search(function (matches) { - $this._showResults(matches); - }); - } else { - $this._removeResults(); - } if (!_options.multiple) { + _options._values = []; if (!_options.selectionRequired) { $this._value(keyword); } else { $this._value(''); } } + if (keyword.length >= _options.minLength) { + $this._search(function (matches) { + $this._showResults(matches); + }); + } else { + $this._removeResults(); + } } // Remove previous value on backspace key var $remove = $_this.data('_remove'); @@ -167,6 +175,8 @@ jQuery.fn.flexdatalist = function (options, value) { $_this.data('_remove', null); } _previousText = $this._keyword(); + + // Focus }).on('focus', function () { var val = $this._keyword(); if (_options.minLength === 0) { @@ -181,9 +191,11 @@ jQuery.fn.flexdatalist = function (options, value) { $this._showResults(matches); }); } + + // Blur }).on('blur', function () { // Set value user leaves string in field onblur - if (_options.multiple && !_options.selectionRequired) { + if (!$this._resultSelected() && _options.multiple && !_options.selectionRequired) { $this._value($this._keyword()); } }) @@ -195,6 +207,13 @@ jQuery.fn.flexdatalist = function (options, value) { $this.addClass('flexdatalist flexdatalist-set').attr('type', 'hidden'); } + /** + * Check search result is selected. + */ + $this._resultSelected = function () { + return $('ul.flexdatalist-results').find('li.item.active').length > 0; + } + /** * Check if field's text has changed. */ @@ -498,21 +517,10 @@ jQuery.fn.flexdatalist = function (options, value) { if (!_this._isDefined(keywords)) { keywords = $this._keyword(); } - if (typeof keywords === 'string') { - keywords = [keywords]; - } - - if (_options.searchByWord) { - for (var index = 0; index < keywords.length; index++) { - var keyword = keywords[index]; - if (keyword.indexOf(' ') > 0) { - var words = keyword.split(' '); - $.merge(keywords, words); - } - } - } $this.trigger('before:flexdatalist.search', [keywords, data]); + //console.log(keywords); + keywords = $this._split(keywords); for (var index = 0; index < data.length; index++) { var item = $this._matches(data[index], keywords); if (item) { @@ -531,27 +539,34 @@ jQuery.fn.flexdatalist = function (options, value) { var hasMatches = false, _item = $.extend({}, item), _options = $this._options(), + found = [], searchIn = _options.searchIn; - for (var index = 0; index < searchIn.length; index++) { - var searchProperty = searchIn[index]; - if (!_this._isDefined(item, searchProperty) || !item[searchProperty]) { - continue; - } - var text = item[searchProperty].toString(); - var highlight = text; - for (var kwindex = 0; kwindex < keywords.length; kwindex++) { - var keyword = keywords[kwindex]; - if ($this._find(keyword, text)) { - highlight = $this._highlight(keyword, highlight); - hasMatches = true; + if (keywords.length > 0) { + for (var index = 0; index < searchIn.length; index++) { + var searchProperty = searchIn[index]; + if (!_this._isDefined(item, searchProperty) || !item[searchProperty]) { + continue; + } + var text = item[searchProperty].toString(), + highlight = text, + strings = $this._split(text); + for (var kwindex = 0; kwindex < keywords.length; kwindex++) { + var keyword = keywords[kwindex]; + if ($this._find(keyword, strings)) { + found.push(keyword); + highlight = $this._highlight(keyword, highlight); + } + } + if (highlight !== text) { + _item[searchProperty + '_highlight'] = highlight; } } - if (highlight !== text) { - _item[searchProperty + '_highlight'] = highlight; - } + } + if (found.length == 0 || (_options.searchByWord && found.length < (keywords.length - 1))) { + return false; } - return hasMatches ? _item : null; + return _item; } /** @@ -565,16 +580,42 @@ jQuery.fn.flexdatalist = function (options, value) { } /** - * Search for keyword in string. + * Search for keyword(s) in string. + */ + $this._find = function (keyword, strings) { + var _options = $this._options(); + for (var index = 0; index < strings.length; index++) { + var text = strings[index]; + text = $this._normalizeString(text), + keyword = $this._normalizeString(keyword); + if (_options.searchEqual && text == keyword) { + return true; + } + if ((_options.searchContain ? (text.indexOf(keyword) >= 0) : (text.indexOf(keyword) === 0))) { + return true; + } + } + return false; + } + + /** + * Split string by words if needed. */ - $this._find = function (keyword, text) { + $this._split = function (keywords) { + if (typeof keywords === 'string') { + keywords = [keywords]; + } var _options = $this._options(); - text = $this._normalizeString(text), - keyword = $this._normalizeString(keyword); - if (_options.searchEqual) { - return text == keyword; + if (_options.searchByWord) { + for (var index = 0; index < keywords.length; index++) { + var keyword = $.trim(keywords[index]); + if (keyword.indexOf(' ') > 0) { + var words = keyword.split(' '); + $.merge(keywords, words); + } + } } - return (_options.searchContain ? (text.indexOf(keyword) >= 0) : (text.indexOf(keyword) === 0)); + return keywords; } /** @@ -1051,8 +1092,7 @@ jQuery.fn.flexdatalist = function (options, value) { $('ul.flexdatalist-results').css({ 'width': $target.outerWidth() + 'px', 'top': (($target.offset().top + $target.outerHeight())) + 'px', - 'left': $target.offset().left + 'px', - 'z-index': ($target.css('z-index') + 1) + 'left': $target.offset().left + 'px' }); } // Initialize diff --git a/jquery.flexdatalist.min.css b/jquery.flexdatalist.min.css index ed63cac..4f23d2b 100644 --- a/jquery.flexdatalist.min.css +++ b/jquery.flexdatalist.min.css @@ -1 +1 @@ -.flexdatalist-results{position:absolute;top:0;left:0;border:1px solid #444;border-top:none;background:#fff;z-index:100000;max-height:300px;overflow-y:auto;box-shadow:0 4px 5px rgba(0,0,0,.15);color:#333;list-style:none;margin:0;padding:0}.flexdatalist-results li{border-bottom:1px solid #ccc;padding:0 15px;font-size:14px;line-height:35px}.flexdatalist-results li span.highlight{font-weight:700;text-decoration:underline}.flexdatalist-results li.active{background:#2B82C9;color:#fff;cursor:pointer}.flexdatalist-results li.no-results{font-style:italic;color:#888}.flexdatalist-results li.group{background:#F3F3F4;color:#666;padding:0 8px}.flexdatalist-results li .group-name{font-weight:700}.flexdatalist-results li .group-item-count{font-size:85%;color:#777;display:inline-block;padding-left:10px}.flexdatalist-multiple:after,.flexdatalist-multiple:before{content:'';display:block;clear:both}.flexdatalist-multiple{width:100%;margin:0;padding:0 0 0 10px;list-style:none;text-align:left;cursor:text}.flexdatalist-multiple.disabled{background-color:#eee;cursor:default}.flexdatalist-multiple li{display:inline-block;position:relative;margin:5px 5px 5px 0;float:left}.flexdatalist-multiple li.input-container,.flexdatalist-multiple li.input-container input{border:none;width:280px;height:auto;padding:0;line-height:25px}.flexdatalist-multiple li.value{display:inline-block;padding:2px 25px 2px 5px;background:#efefef;border-radius:3px}.flexdatalist-multiple li.toggle{cursor:pointer;transition:opacity ease-in-out .3s}.flexdatalist-multiple li.toggle.disabled{text-decoration:line-through;opacity:.8}.flexdatalist-multiple li.value span.fdl-remove{font-weight:700;padding:0 5px;font-size:20px;line-height:25px;cursor:pointer;position:absolute;top:0;right:0;opacity:.7}.flexdatalist-multiple li.value span.fdl-remove:hover{opacity:1} \ No newline at end of file +.flexdatalist-results{position:absolute;top:0;left:0;border:1px solid #444;border-top:none;background:#fff;z-index:100000;max-height:300px;overflow-y:auto;box-shadow:0 4px 5px rgba(0,0,0,.15);color:#333;list-style:none;margin:0;padding:0}.flexdatalist-results li{border-bottom:1px solid #ccc;padding:0 15px;font-size:14px;line-height:35px}.flexdatalist-results li span.highlight{font-weight:700;text-decoration:underline}.flexdatalist-results li.active{background:#2B82C9;color:#fff;cursor:pointer}.flexdatalist-results li.no-results{font-style:italic;color:#888}.flexdatalist-results li.group{background:#F3F3F4;color:#666;padding:0 8px}.flexdatalist-results li .group-name{font-weight:700}.flexdatalist-results li .group-item-count{font-size:85%;color:#777;display:inline-block;padding-left:10px}.flexdatalist-multiple:after,.flexdatalist-multiple:before{content:'';display:block;clear:both}.flexdatalist-multiple{width:100%;margin:0;padding:0;list-style:none;text-align:left;cursor:text}.flexdatalist-multiple.disabled{background-color:#eee;cursor:default}.flexdatalist-multiple li{display:inline-block;position:relative;margin:5px;float:left}.flexdatalist-multiple li.input-container,.flexdatalist-multiple li.input-container input{border:none;width:280px;height:auto;padding:0 0 0 4px;line-height:24px}.flexdatalist-multiple li.value{display:inline-block;padding:2px 25px 2px 5px;background:#eee;border-radius:3px;color:#777;line-height:20px}.flexdatalist-multiple li.toggle{cursor:pointer;transition:opacity ease-in-out .3s}.flexdatalist-multiple li.toggle.disabled{text-decoration:line-through;opacity:.8}.flexdatalist-multiple li.value span.fdl-remove{font-weight:700;padding:2px 5px;font-size:20px;line-height:20px;cursor:pointer;position:absolute;top:0;right:0;opacity:.7}.flexdatalist-multiple li.value span.fdl-remove:hover{opacity:1} \ No newline at end of file diff --git a/jquery.flexdatalist.min.js b/jquery.flexdatalist.min.js index 34a2042..bf4d891 100644 --- a/jquery.flexdatalist.min.js +++ b/jquery.flexdatalist.min.js @@ -1 +1 @@ -jQuery.fn.flexdatalist=function(e,t){"use strict";var i,a=$(document),s=$(this),l=this;if(i=function(){var t,i,a=$(this),s={},n="",r=null;a.attr("name");a.hasClass("flexdatalist-set")&&l._destroy(a),l._options(a,$.extend({url:null,data:[],params:{},relatives:null,chainedRelatives:!1,cache:!0,minLength:2,groupBy:!1,selectionRequired:!1,focusFirstResult:!1,textProperty:null,valueProperty:null,visibleProperties:[],searchIn:["label"],searchContain:!1,searchEqual:!1,searchDisabled:!1,normalizeString:null,multiple:a.attr("multiple"),maxShownResults:100,noResultsText:'No results found for "{keyword}"',toggleSelected:!1,allowDuplicateValues:!1,requestType:"post",limitOfValues:0,_values:[]},a.data(),"object"==typeof e?e:{})),a._options=function(e,t){return l._options(a,e,t)},a._init=function(){var e=a._options();t=a.clone(!1).attr({list:null,name:null,id:a.attr("id")?a.attr("id")+"-flexdatalist":null}).addClass("flexdatalist-alias").removeClass("flexdatalist"),a._options("multiple")?(i=$("