├── .jscs.json ├── .jshintrc ├── Gruntfile.js ├── LICENSE ├── README.md ├── README.ru.md ├── bower.json ├── dist ├── jquery.lookingfor.js ├── jquery.lookingfor.min.js └── jquery.lookingfor.min.map ├── html ├── data │ └── countries.csv ├── highlight.html └── simple.html ├── package.json ├── screenshots └── highlight.png └── src └── jquery.lookingfor.js /.jscs.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "requireCurlyBraces": ["for", "while", "do", "if", "else"], 4 | "requireSpaceAfterKeywords": ["if", "for", "while", "do", "switch", "return"], 5 | "disallowSpacesInsideArrayBrackets": true, 6 | "requireSpacesInsideObjectBrackets": "all", 7 | "disallowQuotedKeysInObjects": true, 8 | "disallowSpaceAfterObjectKeys": true, 9 | "disallowLeftStickedOperators": ["?", "+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="], 10 | "requireRightStickedOperators": ["!"], 11 | "disallowRightStickedOperators": ["?", "+", "/", "*", ":", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="], 12 | "requireLeftStickedOperators": [","], 13 | "disallowKeywords": ["with", "eval"], 14 | "validateJSDoc": { 15 | "checkParamNames": true, 16 | "checkRedundantParams": true, 17 | "requireParamTypes": true 18 | } 19 | } -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "bitwise": true, 4 | "browser": true, 5 | "eqeqeq": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "debug": true, 9 | "forin": true, 10 | "freeze": true, 11 | "immed": true, 12 | "latedef": true, 13 | "maxdepth": 3, 14 | "maxparams": 3, 15 | "newcap": true, 16 | "noarg": true, 17 | "noempty": true, 18 | "nonbsp": true, 19 | "quotmark": "single", 20 | "undef": true, 21 | "unused": true, 22 | "predef": [ 23 | "define", 24 | "jQuery" 25 | ] 26 | } -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 'use strict'; 3 | 4 | require('matchdep') 5 | .filterDev('grunt-*') 6 | .forEach(grunt.loadNpmTasks); 7 | 8 | grunt.initConfig({ 9 | jsSource: 'src/*.js', 10 | jsDist: 'dist/', 11 | banner: 12 | '/**\n' + 13 | ' * jquery.lookingfor — fast search as you type\n' + 14 | ' * @author Alexander Burtsev, http://burtsev.me, 2014—<%= grunt.template.today("yyyy") %>\n' + 15 | ' * @license MIT\n' + 16 | ' */\n', 17 | 18 | jshint: { 19 | options: { 20 | jshintrc: '.jshintrc' 21 | }, 22 | app: ['<%= jsSource %>'] 23 | }, 24 | 25 | jscs: { 26 | options: { 27 | config: '.jscs.json' 28 | }, 29 | app: ['<%= jsSource %>'] 30 | }, 31 | 32 | copy: { 33 | options: { 34 | process: function (content, srcpath) { 35 | return grunt.config.get('banner') + content; 36 | } 37 | }, 38 | source: { 39 | files: [{ 40 | expand: true, 41 | cwd: 'src/', 42 | src: ['**'], 43 | dest: 'dist/' 44 | }] 45 | } 46 | }, 47 | 48 | uglify: { 49 | options: { 50 | banner: '<%= banner %>', 51 | sourceMap: true 52 | }, 53 | lookingfor: { 54 | files: { 55 | '<%= jsDist %>jquery.lookingfor.min.js': ['<%= jsSource %>'] 56 | } 57 | } 58 | }, 59 | 60 | watch: { 61 | lookingfor: { 62 | files: ['<%= jsSource %>'], 63 | tasks: ['jshint', 'jscs', 'uglify'] 64 | } 65 | } 66 | }); 67 | 68 | grunt.registerTask('default', ['jshint', 'jscs', 'copy', 'uglify', 'watch']); 69 | }; 70 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Alexander Burtsev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | jquery.lookingfor 2 | ================= 3 | 4 | ![Screenshot](https://rawgithub.com/albburtsev/jquery.lookingfor/master/screenshots/highlight.png) 5 | 6 | Fast search as you type jQuery plugin. 7 | 8 | It's very small (minified — 2.5kb, gzipped — 1.2kb), very fast and supports old browsers (IE6+). 9 | 10 | __jquery.lookingfor__ plugin searches text in list items (```
  • ```) and hides unmatched items. 11 | It works not only for `
  • `s, but for any HTML element on a page. 12 | Any input field (```input, textarea```) can be transformed to search filter with __jquery.lookingfor__. 13 | 14 | [Live demo](http://albburtsev.github.io/jquery.lookingfor/) 15 | 16 | ## Install 17 | 18 | Download latest [release](https://github.com/albburtsev/jquery.lookingfor/releases). 19 | Use [minified](https://github.com/albburtsev/jquery.lookingfor/blob/master/jquery.lookingfor.min.js) 20 | or [development](https://github.com/albburtsev/jquery.lookingfor/blob/master/jquery.lookingfor.js) version. 21 | 22 | Or use [bower](http://bower.io/) for install: 23 | 24 | ``` 25 | bower install jquery.lookingfor --save 26 | ``` 27 | 28 | ## Usage 29 | 30 | Include [jQuery](http://jquery.com) and __jquery.lookingfor__ on your page: 31 | 32 | ```html 33 | 34 | 35 | ``` 36 | 37 | Prepare list of items for following search and an input field (optional): 38 | 39 | ```html 40 | 41 | 47 | ``` 48 | 49 | Call ```lookingfor()``` method with necessary options: 50 | 51 | ```js 52 | jQuery(function($) { 53 | $('#numerals').lookingfor({ 54 | input: $('input[name="query"]'), 55 | items: 'li' 56 | }); 57 | }); 58 | ``` 59 | 60 | ### Options 61 | 62 | All options are optional. 63 | 64 | * __input__ — input field's selector; 65 | * __items__ — item's selector, default – ```'li'```; 66 | * __highlight__ — set ```true``` to highlight matched text, default — ```false```; 67 | * __highlightColor__ — ```#RRGGBB``` background color for matched text, default – ```#FFDE00```; 68 | * __onFound {Function(HTMLElement item, String query)}__ — callback, will be called when text is found. 69 | -------------------------------------------------------------------------------- /README.ru.md: -------------------------------------------------------------------------------- 1 | jquery.lookingfor 2 | ================= 3 | 4 | ![Screenshot](https://rawgithub.com/albburtsev/jquery.lookingfor/master/screenshots/highlight.png) 5 | 6 | Быстрый поиск набираемого текста. 7 | 8 | Плагин очень маленький (минифицированный — 2.5kb, сжатый — 1.2kb), очень быстрый и даже поддерживает старые браузеры (IE6+). 9 | 10 | Плагин __jquery.lookingfor__ ищет текст в элементах списков (```
  • ```) и скрывает те элементы, для которых не найдено совпадений. 11 | Он работает не только со списками, но и с любыми другими элементами на странице, содержащими текст. 12 | Любое текстовое поле (```input, textarea```) можно сделать поисковым фильтром с помощью __jquery.lookingfor__. 13 | 14 | [Демо](http://albburtsev.github.io/jquery.lookingfor/) 15 | 16 | ## Установка 17 | 18 | Скачайте последний [релиз](https://github.com/albburtsev/jquery.lookingfor/releases) 19 | и подключите на страницу [минифицированную](https://github.com/albburtsev/jquery.lookingfor/blob/master/jquery.lookingfor.min.js) 20 | или [полную](https://github.com/albburtsev/jquery.lookingfor/blob/master/jquery.lookingfor.js) версию плагина. 21 | 22 | Или установите с помощью [bower](http://bower.io/) 23 | 24 | ``` 25 | bower install jquery.lookingfor --save 26 | ``` 27 | 28 | ## Быстрый старт 29 | 30 | Подключите [jQuery](http://jquery.com) и __jquery.lookingfor__ на свою страницу: 31 | 32 | ```html 33 | 34 | 35 | ``` 36 | 37 | Приготовьте список элементов, содержащих текст, и поле ввода (при необходимости): 38 | 39 | ```html 40 | 41 | 47 | ``` 48 | 49 | Вызовите метод ```lookingfor()``` с необходимыми опциями для списка: 50 | 51 | ```js 52 | jQuery(function($) { 53 | $('#numerals').lookingfor({ 54 | input: $('input[name="query"]'), 55 | items: 'li' 56 | }); 57 | }); 58 | ``` 59 | 60 | ### Опции 61 | 62 | Все опции являются необязательными. 63 | 64 | * __input__ — селектор для поля ввода; 65 | * __items__ — селектор для элементов списка, по умолчанию – ```'li'```; 66 | * __highlight__ — переключите в ```true``` для подсветки найденного текста, по умолчанию — ```false```; 67 | * __highlightColor__ — ```#RRGGBB``` цвет фона для подсветки найденного текста, по умолчанию – ```#FFDE00```; 68 | * __onFound {Function(HTMLElement item, String query)}__ — колбек, вызывается при найденном совпадении. 69 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery.lookingfor", 3 | "version": "0.0.8", 4 | "main": ["jquery.lookingfor.js"], 5 | "ignore": [ 6 | "Gruntfile.js", 7 | "package.json", 8 | ".jscs.json", 9 | ".jshintrc", 10 | "screenshots", 11 | "html" 12 | ], 13 | "dependencies": { 14 | "jquery": ">=1.7" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dist/jquery.lookingfor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jquery.lookingfor — fast search as you type 3 | * @author Alexander Burtsev, http://burtsev.me, 2014—2015 4 | * @license MIT 5 | */ 6 | (function(factory) { 7 | if ( typeof define === 'function' && define.amd ) { 8 | define(['jquery'], factory); 9 | } else { 10 | factory(jQuery); 11 | } 12 | }(function($) { 13 | 'use strict'; 14 | 15 | $.fn.lookingfor = function(opts) { 16 | return this.each(function() { 17 | new Lookingfor(this, opts); 18 | }); 19 | }; 20 | 21 | /** 22 | * @class 23 | * @param {HTMLElement} container 24 | * @param {Object} opts 25 | * @param {String} [opts.input] Selector for input field 26 | * @param {String} [opts.items='li'] Selector for nested items 27 | * @param {Number} [opts.queryCharLimit = 1] 28 | * @param {Number} [opts.queryDelay = 100] ms 29 | * @param {Boolean} [opts.highlight=false] Highlight matched text 30 | * @param {Boolean} [opts.highlightColor='#ffde00'] Background color for matched text 31 | * @param {Function(HTMLElement item, String query)} [opts.onFound] Callback, calls when text found in element 32 | * 33 | * @todo: nested items 34 | * @todo: show/hide animation 35 | */ 36 | function Lookingfor(container, opts) { 37 | $.extend(this, { 38 | _input: null, 39 | _items: null, 40 | _container: $(container), 41 | 42 | items: 'li', 43 | value: '', 44 | cache: [], 45 | queryCharLimit: 1, 46 | queryTimer: null, 47 | queryDelay: 100, // ms 48 | 49 | highlight: false, 50 | highlightClass: 'lfitem_match', 51 | highlightColor: '#ffde00', 52 | 53 | hiddenListClass: 'lflist_hidden', 54 | hiddenItemAttr: 'data-lfhidden', 55 | hiddenCount: 0, 56 | 57 | onFound: null 58 | }, opts || {}); 59 | 60 | this._items = $(this.items, container); 61 | this._input = $(this.input); 62 | 63 | if ( !this._items.length ) { 64 | return; 65 | } 66 | 67 | if ( this._input.length ) { 68 | this._input.on('keyup change', this._debounce(function() { 69 | var value = (this._input.val() || '').toLowerCase(); 70 | value = $.trim(value); 71 | 72 | if ( value === this.value ) { 73 | return; 74 | } 75 | 76 | this.value = value; 77 | if ( value.length >= this.queryCharLimit ) { 78 | this.query(); 79 | } else { 80 | this.showAll(); 81 | } 82 | }, this.queryDelay, this)); 83 | } 84 | 85 | this.addStyles(); 86 | this.indexing(); 87 | } 88 | 89 | Lookingfor.prototype = 90 | /** @lends Lookingfor */ 91 | { 92 | /** 93 | * Generates and adds styles for hiding and highlighting items 94 | */ 95 | addStyles: function() { 96 | var _head = $('head'), 97 | style = $(' 41 | 42 | 43 |
    44 |

    Countries ()

    45 | 46 |
    47 |
    48 |
    49 | 50 |
    $('ul').lookingfor({
    51 | 	input: $('input'),
    52 | 	items: 'li',
    53 | 	highlight: true
    54 | });
    55 | 
    56 | 57 | 58 |
    59 |
    60 |
    61 | 62 | 63 |
    64 | 65 | 66 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /html/simple.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | jQuery.lookingfor demo page 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 31 | 37 | 38 | 39 |
    40 |

    Countries ()

    41 | 42 |
    43 |
    44 |
    45 | 46 |
    $('ul').lookingfor({ input: 'input' });
    47 | 
    48 | 49 | 50 |
    51 |
    52 |
    53 | 54 | 55 |
    56 | 57 | 58 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery.lookingfor", 3 | "version": "0.0.8", 4 | "description": "Fast search as you type jQuery-plugin", 5 | "repository": { 6 | "type": "git", 7 | "url": "git://github.com/albburtsev/jquery.lookingfor.git" 8 | }, 9 | "keywords": [ 10 | "jquery", 11 | "plugin", 12 | "search", 13 | "highlight", 14 | "client search", 15 | "page search" 16 | ], 17 | "author": { 18 | "name": "Alexander Burtsev", 19 | "url": "https://github.com/albburtsev" 20 | }, 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/albburtsev/jquery.lookingfor/issues" 24 | }, 25 | "homepage": "https://github.com/albburtsev/jquery.lookingfor", 26 | "devDependencies": { 27 | "grunt": "^0.4.4", 28 | "grunt-contrib-copy": "^0.8.0", 29 | "grunt-contrib-jshint": "^0.10.0", 30 | "grunt-contrib-uglify": "^0.4.0", 31 | "grunt-contrib-watch": "^0.6.1", 32 | "grunt-jscs-checker": "^0.4.1", 33 | "matchdep": "^0.3.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /screenshots/highlight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/albburtsev/jquery.lookingfor/61ce3ba46ba4f0a614d7d29b18abd232eaaaead1/screenshots/highlight.png -------------------------------------------------------------------------------- /src/jquery.lookingfor.js: -------------------------------------------------------------------------------- 1 | (function(factory) { 2 | if ( typeof define === 'function' && define.amd ) { 3 | define(['jquery'], factory); 4 | } else { 5 | factory(jQuery); 6 | } 7 | }(function($) { 8 | 'use strict'; 9 | 10 | $.fn.lookingfor = function(opts) { 11 | return this.each(function() { 12 | new Lookingfor(this, opts); 13 | }); 14 | }; 15 | 16 | /** 17 | * @class 18 | * @param {HTMLElement} container 19 | * @param {Object} opts 20 | * @param {String} [opts.input] Selector for input field 21 | * @param {String} [opts.items='li'] Selector for nested items 22 | * @param {Number} [opts.queryCharLimit = 1] 23 | * @param {Number} [opts.queryDelay = 100] ms 24 | * @param {Boolean} [opts.highlight=false] Highlight matched text 25 | * @param {Boolean} [opts.highlightColor='#ffde00'] Background color for matched text 26 | * @param {Function(HTMLElement item, String query)} [opts.onFound] Callback, calls when text found in element 27 | * 28 | * @todo: nested items 29 | * @todo: show/hide animation 30 | */ 31 | function Lookingfor(container, opts) { 32 | $.extend(this, { 33 | _input: null, 34 | _items: null, 35 | _container: $(container), 36 | 37 | items: 'li', 38 | value: '', 39 | cache: [], 40 | queryCharLimit: 1, 41 | queryTimer: null, 42 | queryDelay: 100, // ms 43 | 44 | highlight: false, 45 | highlightClass: 'lfitem_match', 46 | highlightColor: '#ffde00', 47 | 48 | hiddenListClass: 'lflist_hidden', 49 | hiddenItemAttr: 'data-lfhidden', 50 | hiddenCount: 0, 51 | 52 | onFound: null 53 | }, opts || {}); 54 | 55 | this._items = $(this.items, container); 56 | this._input = $(this.input); 57 | 58 | if ( !this._items.length ) { 59 | return; 60 | } 61 | 62 | if ( this._input.length ) { 63 | this._input.on('keyup change', this._debounce(function() { 64 | var value = (this._input.val() || '').toLowerCase(); 65 | value = $.trim(value); 66 | 67 | if ( value === this.value ) { 68 | return; 69 | } 70 | 71 | this.value = value; 72 | if ( value.length >= this.queryCharLimit ) { 73 | this.query(); 74 | } else { 75 | this.showAll(); 76 | } 77 | }, this.queryDelay, this)); 78 | } 79 | 80 | this.addStyles(); 81 | this.indexing(); 82 | } 83 | 84 | Lookingfor.prototype = 85 | /** @lends Lookingfor */ 86 | { 87 | /** 88 | * Generates and adds styles for hiding and highlighting items 89 | */ 90 | addStyles: function() { 91 | var _head = $('head'), 92 | style = $('