├── VERSION ├── .gitignore ├── .jshintrc ├── bower.json ├── jquery-searcher.jquery.json ├── LICENSE ├── package.json ├── dist ├── jquery.searcher.min.js └── jquery.searcher.js ├── Gruntfile.js ├── examples ├── styles.css ├── list.html ├── table.html └── card.html ├── tests ├── tests.html └── tests.js ├── README.md └── src └── jquery.searcher.js /VERSION: -------------------------------------------------------------------------------- 1 | 0.3.0 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "strict": true, 3 | "smarttabs": true, 4 | "undef": true, 5 | "unused": true, 6 | "lastsemic": true, 7 | "maxlen": 120, 8 | "jquery": true, 9 | "browser": true, 10 | "noarg": true, 11 | "noempty": true, 12 | "quotmark": "double", 13 | "predef": ["jQuery", "module", "define"] 14 | } -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-searcher", 3 | "title": "jQuery Searcher Plugin", 4 | "version": "0.3.0", 5 | "description": "Connects any list-like data with an input for searching.", 6 | "license": "MIT", 7 | 8 | "keywords": [ 9 | "searcher", 10 | "search", 11 | "filter", 12 | "table", 13 | "list", 14 | "connect" 15 | ], 16 | 17 | "dependencies": { 18 | "jquery": ">=1.4.3" 19 | }, 20 | "devDependencies": { 21 | "qunitjs": "~1.14.0", 22 | "blanket": "~1.1.6" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /jquery-searcher.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-searcher", 3 | "title": "jQuery Searcher Plugin", 4 | "version": "0.3.0", 5 | "description": "Connects any list-like data with an input for searching.", 6 | 7 | "licenses": [ 8 | { 9 | "type": "MIT", 10 | "url": "https://github.com/lloiser/jquery-searcher/blob/master/LICENSE" 11 | } 12 | ], 13 | 14 | "homepage": "https://github.com/lloiser/jquery-searcher/", 15 | "bugs": "https://github.com/lloiser/jquery-searcher/issues/", 16 | "demo": "http://lloiser.github.io/jquery-searcher/", 17 | "download": "https://github.com/lloiser/jquery-searcher/dist/jquery.searcher.min.js", 18 | 19 | "author": { 20 | "name": "Lukas Beranek", 21 | "email": "lukasberanek@gmx.net" 22 | }, 23 | 24 | "dependencies": { 25 | "jquery": ">=1.4.3" 26 | }, 27 | 28 | "keywords": [ 29 | "searcher", 30 | "search", 31 | "filter", 32 | "table", 33 | "list", 34 | "connect" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Lukas Beranek 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-searcher", 3 | "title": "jQuery Searcher Plugin", 4 | "version": "0.3.0", 5 | "description": "Connects any list-like data with an input for searching.", 6 | "license": "MIT", 7 | 8 | "homepage": "https://github.com/lloiser/jquery-searcher/", 9 | "bugs": "https://github.com/lloiser/jquery-searcher/issues", 10 | "author": { 11 | "name": "Lukas Beranek", 12 | "email": "lukasberanek@gmx.net" 13 | }, 14 | 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/lloiser/jquery-searcher/" 18 | }, 19 | 20 | "dependencies": { 21 | "jquery": ">=1.4.3" 22 | }, 23 | 24 | "devDependencies": { 25 | "grunt": "~0.4.2", 26 | "grunt-cli": "^0.1.13", 27 | "grunt-contrib-jshint": "~0.6.3", 28 | "grunt-contrib-uglify": "~0.2.2", 29 | "grunt-contrib-concat": "~0.1.3", 30 | "grunt-contrib-connect": "0.5.x", 31 | "grunt-contrib-qunit": "~0.3.0", 32 | "qunitjs": "~1.14.0", 33 | "blanket": "~1.1.6" 34 | }, 35 | 36 | "scripts": { 37 | "default": "grunt default", 38 | "build": "grunt build", 39 | "test": "grunt test" 40 | }, 41 | 42 | "keywords": [ 43 | "searcher", 44 | "search", 45 | "filter", 46 | "table", 47 | "list", 48 | "connect" 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /dist/jquery.searcher.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Searcher Plugin - v0.3.0 - 2016-01-29 2 | * https://github.com/lloiser/jquery-searcher/ 3 | * Copyright (c) 2016 Lukas Beranek; Licensed MIT 4 | */ 5 | (function(){"use strict";function a(a){function b(b,c){this.element=b,this.options=a.extend({},f,c),this._create()}function c(a){return a.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")}var d="searcher",e="plugin_"+d,f={itemSelector:"tbody > tr",textSelector:"td",inputSelector:"",caseSensitive:!1,toggle:function(b,c){a(b).toggle(c)}};b.prototype={dispose:function(){this._$input.unbind("."+d);var a=this.options,b=a.toggle||f.toggle;this._$element.find(a.itemSelector).each(function(){b(this,!0)})},filter:function(b){this._lastValue=b;var d=this.options,e=d.textSelector,g=d.toggle||f.toggle,h="gm"+(d.caseSensitive?"":"i"),i=new RegExp("("+c(b)+")",h);this._$element.find(d.itemSelector).each(function(){var b=a(this),c=e?b.find(e):b,d=!1;c=c.each(function(){return d=d||!!a(this).text().match(i),!d}),g(this,d)})},_create:function(){var b=this.options;this._$element=a(this.element),this._fn=a.proxy(this._onValueChange,this);var c="input."+d+" change."+d+" keyup."+d;this._$input=a(b.inputSelector).bind(c,this._fn),this._lastValue=null;var e=b.toggle||f.toggle;this._$element.find(b.itemSelector).each(function(){e(this,!0)})},_onValueChange:function(){var a=this._$input.val();a!==this._lastValue&&this.filter(a)}},a.fn[d]=function(c){var d=Array.prototype.slice.call(arguments,1);return this.each(function(){var f=a.data(this,e),g=typeof c;"string"===g&&f?(f[c].apply(f,d),"dispose"===c&&a.removeData(this,e)):"object"===g&&(f?a.extend(f.options,c):a.data(this,e,new b(this,c)))})}}"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a:a(jQuery)}).call(this); -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | "use strict"; 4 | 5 | module.exports = function(grunt) { 6 | 7 | // Project configuration. 8 | grunt.initConfig({ 9 | pkg: grunt.file.readJSON("package.json"), 10 | 11 | // some variables 12 | filename: "<%= pkg.name.replace('-', '.') %>", 13 | banner: "/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - " + 14 | "<%= grunt.template.today('yyyy-mm-dd') %>\n" + 15 | " * <%= pkg.homepage %>\n" + 16 | " * Copyright (c) <%= grunt.template.today('yyyy') %> <%= pkg.author.name %>;" + 17 | " Licensed <%= pkg.license %> \n*/\n", 18 | 19 | // run jshint with the existing jshintrc file on all js files in "src" folder 20 | jshint: { 21 | options: { 22 | jshintrc: ".jshintrc" 23 | }, 24 | all: ["src/*.js", "tests/tests.js"] 25 | }, 26 | 27 | // concat the source file(s) and the banner and copy it to the "dist" folder 28 | concat: { 29 | options: { 30 | banner: "<%= banner %>" 31 | }, 32 | dist: { 33 | src: "src/<%= filename %>.js", 34 | dest: "dist/<%= filename %>.js" 35 | }, 36 | }, 37 | 38 | // create the minified js and copy it to the "dist" folder 39 | uglify: { 40 | options: { 41 | preserveComments: "some" 42 | }, 43 | build: { 44 | src: "<%= concat.dist.dest %>", 45 | dest: "dist/<%= filename %>.min.js" 46 | } 47 | }, 48 | 49 | // tests 50 | qunit: { 51 | all: ['tests/**/*.html'] 52 | } 53 | }); 54 | 55 | // Load all tasks 56 | grunt.loadNpmTasks("grunt-contrib-concat"); 57 | grunt.loadNpmTasks("grunt-contrib-uglify"); 58 | grunt.loadNpmTasks("grunt-contrib-jshint"); 59 | grunt.loadNpmTasks("grunt-contrib-qunit"); 60 | 61 | // Default task(s). 62 | grunt.registerTask("default", ["build", "test"]); 63 | grunt.registerTask("build", ["jshint", "concat", "uglify"]); 64 | grunt.registerTask("test", ["qunit"]); 65 | 66 | }; 67 | 68 | }).call(this); -------------------------------------------------------------------------------- /examples/styles.css: -------------------------------------------------------------------------------- 1 | body 2 | { 3 | font: 14px/1.4 Arial, sans-serif; 4 | overflow-y: scroll; 5 | } 6 | 7 | p, ul, ol, table, pre, dl 8 | { 9 | margin: 0 0 20px; 10 | } 11 | 12 | table 13 | { 14 | width: 100%; 15 | border-collapse: collapse; 16 | } 17 | 18 | th, td 19 | { 20 | text-align: left; 21 | padding: 5px 10px; 22 | border-top: 1px solid #aaa; 23 | } 24 | 25 | th 26 | { 27 | border-top: 0; 28 | } 29 | 30 | label 31 | { 32 | font-weight: bold; 33 | } 34 | 35 | #tabledata .nr { width: 8%; } 36 | #tabledata .title { width: 43%; } 37 | #tabledata .artist { width: 40%; } 38 | #tabledata .date { width: 9%; } 39 | .list-header { display: block; padding: 0 0 0 20px; } 40 | #carddata > * 41 | { 42 | display: inline-block; 43 | position: relative; 44 | width: 265px; 45 | margin: 15px; 46 | border: 1px solid #aaa; 47 | -webkit-border-radius: 15px; 48 | -moz-border-radius: 15px; 49 | -ms-border-radius: 15px; 50 | -o-border-radius: 15px; 51 | border-radius: 15px; 52 | -webkit-box-shadow: rgba(0, 0, 0, 0.2) 2px 2px 2px; 53 | -moz-box-shadow: rgba(0, 0, 0, 0.2) 2px 2px 2px; 54 | box-shadow: rgba(0, 0, 0, 0.2) 3px 3px 8px; 55 | } 56 | #carddata:after 57 | { 58 | content: " "; 59 | clear: both; 60 | display: table; 61 | } 62 | #carddata .nr, #carddata .title, #carddata .artist, #carddata .date 63 | { 64 | color: #888; 65 | text-align: center; 66 | font-size: 11px; 67 | } 68 | #carddata .nr, #carddata .date 69 | { 70 | display: inline-block; 71 | margin: 5px; 72 | padding: 2px 5px; 73 | width: auto; 74 | background: #777; 75 | color: white; 76 | -webkit-border-radius: 10px; 77 | -moz-border-radius: 10px; 78 | -ms-border-radius: 10px; 79 | -o-border-radius: 10px; 80 | border-radius: 10px; 81 | } 82 | #carddata .date 83 | { 84 | float: right; 85 | } 86 | #carddata .title 87 | { 88 | font-size: 14px; 89 | color: inherit; 90 | } 91 | 92 | .highlight 93 | { 94 | background-color: #fd0; 95 | } -------------------------------------------------------------------------------- /tests/tests.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQuery Searcher Tests 6 | 7 | 8 | 9 | 10 | 11 | 19 | 20 | 21 |
22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
1Like a Rolling StoneBob Dylan1965
2(I Can't Get No) SatisfactionThe Rolling Stones1965
3ImagineJohn Lennon1971
4What's Going OnMarvin Gaye1971
5RespectAretha Franklin1967
35 | 36 | 43 | 44 |
45 |
46 | 1 47 | Like a Rolling Stone 48 |
Bob Dylan
49 |

1965

50 |
51 |
52 | 2 53 | (I Can't Get No) Satisfaction 54 |
The Rolling Stones
55 |

1965

56 |
57 |
58 | 3 59 | Imagine 60 |
John Lennon
61 |

1971

62 |
63 |
64 | 4 65 | What's Going On 66 |
Marvin Gaye
67 |

1971

68 |
69 |
70 | 5 71 | Respect 72 |
Aretha Franklin
73 |

1967

74 |
75 |
76 |
77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jQuery Searcher Plugin 2 | 3 | The jQuery Searcher Plugin connects any list-like data with an input for searching. 4 | 5 | ## Installation 6 | 7 | Download the latest [release](https://github.com/lloiser/jquery-searcher/releases/) of this plugin on GitHub. 8 | 9 | Include the jquery.searcher.js script after the jQuery library (unless you are packaging scripts somehow else): 10 | ```html 11 | 12 | ``` 13 | 14 | ## Usage 15 | 16 | ```js 17 | $("...").searcher({ 18 | itemSelector: "...", // jQuery selector for the data item element 19 | textSelector: "...", // jQuery selector for the element which contains the text 20 | inputSelector: "..." // jQuery selector for the input element 21 | }); 22 | ``` 23 | 24 | ## Example 25 | 26 | See the live version of the following example on the [GitHub page](http://lloiser.github.io/jquery-searcher/). 27 | 28 | Given the following HTML markup: 29 | ```html 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | ... 46 | 47 |
#1Like a Rolling StoneBob Dylan1965
#2(I Can't Get No) SatisfactionThe Rolling Stones1965
48 | ``` 49 | And executing the following script connects the input with the table: 50 | ```js 51 | $("#tabledata").searcher({ 52 | inputSelector: "#tablesearchinput" 53 | // itemSelector (tbody > tr) and textSelector (td) already have proper default values 54 | }); 55 | ``` 56 | 57 | ## Documentation 58 | 59 | The following table contains all possible options which can be passed to the plugin. 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 77 | 78 | 79 | 80 | 81 | 86 | 87 | 88 | 89 | 90 | 94 | 95 | 96 | 97 | 98 | 102 | 103 | 104 | 105 | 106 | 111 | 112 | 113 |
NameTypeDescription
itemSelectorstring 74 | jQuery selector for the data item element (e.g. tr, li).
75 | Default: "tbody > tr" 76 |
textSelectorstring 82 | jQuery selector for the element which contains the text within the item element.
83 | If not specified the data item element is used instead.
84 | Default: "td" 85 |
inputSelectorstring 91 | jQuery selector for the input element which is used to filter the data.
92 | Default: "" 93 |
caseSensitivebool 99 | Determines whether the search should be case sensitive or not.
100 | Default: false 101 |
togglefunction 107 | this function is called for each data item element when the text in the input changes.
108 | it is called with the data item element and a boolean value indicating whether the item contains the text or not.
109 | Default: function(item, containsText) { $(item).toggle(containsText); } 110 |
114 | 115 | ## License 116 | 117 | Copyright (c) 2014 Lukas Beranek Licensed under the MIT license. -------------------------------------------------------------------------------- /src/jquery.searcher.js: -------------------------------------------------------------------------------- 1 | (function IIFE() { 2 | 3 | "use strict"; 4 | 5 | function factory($) 6 | { 7 | var pluginName = "searcher", 8 | dataKey = "plugin_" + pluginName, 9 | defaults = { 10 | // selector for the item element 11 | itemSelector: "tbody > tr", 12 | // selector for the text elements 13 | textSelector: "td", 14 | // selector for the input 15 | inputSelector: "", 16 | // determines whether the search is case sensitive or not 17 | caseSensitive: false, 18 | // function to toggle the visibility of the item 19 | toggle: function(item, containsText) 20 | { 21 | $(item).toggle(containsText); 22 | } 23 | }; 24 | 25 | function Searcher(element, options) 26 | { 27 | this.element = element; 28 | 29 | this.options = $.extend({ }, defaults, options); 30 | 31 | this._create(); 32 | } 33 | 34 | Searcher.prototype = { 35 | dispose: function() 36 | { 37 | // unbind all events 38 | this._$input.unbind("." + pluginName); 39 | // toggle all elements with true 40 | var options = this.options, 41 | toggle = options.toggle || defaults.toggle; 42 | this._$element.find(options.itemSelector).each(function() { toggle(this, true); }); 43 | }, 44 | filter: function(value) 45 | { 46 | this._lastValue = value; 47 | 48 | var options = this.options, 49 | textSelector = options.textSelector, 50 | toggle = options.toggle || defaults.toggle; 51 | 52 | // build the regular expression for searching 53 | var flags = "gm" + (!options.caseSensitive ? "i" : ""); 54 | var regex = new RegExp("(" + escapeRegExp(value) + ")", flags); 55 | 56 | this._$element 57 | .find(options.itemSelector) 58 | .each(function eachItem() { 59 | var $item = $(this), 60 | $textElements = textSelector ? $item.find(textSelector) : $item, 61 | itemContainsText = false; 62 | 63 | $textElements = $textElements.each(function eachTextElement() { 64 | itemContainsText = itemContainsText || !!$(this).text().match(regex); 65 | return !itemContainsText; // stop if at least one text element contains the text 66 | }); 67 | 68 | toggle(this, itemContainsText); 69 | }); 70 | }, 71 | _create: function() 72 | { 73 | var options = this.options; 74 | 75 | this._$element = $(this.element); 76 | 77 | // find the input and bind to various events 78 | this._fn = $.proxy(this._onValueChange, this); 79 | var eventNames = "input." + pluginName + " change." + pluginName + " keyup." + pluginName; 80 | this._$input = $(options.inputSelector).bind(eventNames, this._fn); 81 | 82 | // remember the last entered value 83 | this._lastValue = null; 84 | 85 | // call the toggle with true for all items on startup 86 | var toggle = options.toggle || defaults.toggle; 87 | this._$element.find(options.itemSelector).each(function() { toggle(this, true); }); 88 | }, 89 | _onValueChange: function() 90 | { 91 | var value = this._$input.val(); 92 | if (value === this._lastValue) 93 | return; // nothing has changed 94 | 95 | this.filter(value); 96 | } 97 | }; 98 | 99 | function escapeRegExp(text) 100 | { 101 | // see https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions 102 | return text.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); 103 | } 104 | 105 | $.fn[pluginName] = function pluginHandler(options) { 106 | var args = Array.prototype.slice.call(arguments, 1); 107 | return this.each(function() { 108 | var searcher = $.data(this, dataKey); 109 | var t = typeof(options); 110 | if (t === "string" && searcher) 111 | { 112 | searcher[options].apply(searcher, args); 113 | if (options === "dispose") 114 | $.removeData(this, dataKey); 115 | } 116 | else if (t === "object") 117 | { 118 | if (!searcher) 119 | // create a new searcher 120 | $.data(this, dataKey, new Searcher(this, options)); 121 | else 122 | // update the options of the existing 123 | $.extend(searcher.options, options); 124 | } 125 | }); 126 | }; 127 | 128 | } 129 | 130 | // AMD style (register as an anonymous module) 131 | if (typeof(define) === "function" && define.amd) 132 | define(["jquery"], factory); 133 | // node/CommonJS style (for Browserify) 134 | else if (typeof(exports) === "object") 135 | module.exports = factory; 136 | // browser 137 | else 138 | factory(jQuery); 139 | 140 | }).call(this); 141 | -------------------------------------------------------------------------------- /dist/jquery.searcher.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Searcher Plugin - v0.3.0 - 2016-01-29 2 | * https://github.com/lloiser/jquery-searcher/ 3 | * Copyright (c) 2016 Lukas Beranek; Licensed MIT 4 | */ 5 | (function IIFE() { 6 | 7 | "use strict"; 8 | 9 | function factory($) 10 | { 11 | var pluginName = "searcher", 12 | dataKey = "plugin_" + pluginName, 13 | defaults = { 14 | // selector for the item element 15 | itemSelector: "tbody > tr", 16 | // selector for the text elements 17 | textSelector: "td", 18 | // selector for the input 19 | inputSelector: "", 20 | // determines whether the search is case sensitive or not 21 | caseSensitive: false, 22 | // function to toggle the visibility of the item 23 | toggle: function(item, containsText) 24 | { 25 | $(item).toggle(containsText); 26 | } 27 | }; 28 | 29 | function Searcher(element, options) 30 | { 31 | this.element = element; 32 | 33 | this.options = $.extend({ }, defaults, options); 34 | 35 | this._create(); 36 | } 37 | 38 | Searcher.prototype = { 39 | dispose: function() 40 | { 41 | // unbind all events 42 | this._$input.unbind("." + pluginName); 43 | // toggle all elements with true 44 | var options = this.options, 45 | toggle = options.toggle || defaults.toggle; 46 | this._$element.find(options.itemSelector).each(function() { toggle(this, true); }); 47 | }, 48 | filter: function(value) 49 | { 50 | this._lastValue = value; 51 | 52 | var options = this.options, 53 | textSelector = options.textSelector, 54 | toggle = options.toggle || defaults.toggle; 55 | 56 | // build the regular expression for searching 57 | var flags = "gm" + (!options.caseSensitive ? "i" : ""); 58 | var regex = new RegExp("(" + escapeRegExp(value) + ")", flags); 59 | 60 | this._$element 61 | .find(options.itemSelector) 62 | .each(function eachItem() { 63 | var $item = $(this), 64 | $textElements = textSelector ? $item.find(textSelector) : $item, 65 | itemContainsText = false; 66 | 67 | $textElements = $textElements.each(function eachTextElement() { 68 | itemContainsText = itemContainsText || !!$(this).text().match(regex); 69 | return !itemContainsText; // stop if at least one text element contains the text 70 | }); 71 | 72 | toggle(this, itemContainsText); 73 | }); 74 | }, 75 | _create: function() 76 | { 77 | var options = this.options; 78 | 79 | this._$element = $(this.element); 80 | 81 | // find the input and bind to various events 82 | this._fn = $.proxy(this._onValueChange, this); 83 | var eventNames = "input." + pluginName + " change." + pluginName + " keyup." + pluginName; 84 | this._$input = $(options.inputSelector).bind(eventNames, this._fn); 85 | 86 | // remember the last entered value 87 | this._lastValue = null; 88 | 89 | // call the toggle with true for all items on startup 90 | var toggle = options.toggle || defaults.toggle; 91 | this._$element.find(options.itemSelector).each(function() { toggle(this, true); }); 92 | }, 93 | _onValueChange: function() 94 | { 95 | var value = this._$input.val(); 96 | if (value === this._lastValue) 97 | return; // nothing has changed 98 | 99 | this.filter(value); 100 | } 101 | }; 102 | 103 | function escapeRegExp(text) 104 | { 105 | // see https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions 106 | return text.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); 107 | } 108 | 109 | $.fn[pluginName] = function pluginHandler(options) { 110 | var args = Array.prototype.slice.call(arguments, 1); 111 | return this.each(function() { 112 | var searcher = $.data(this, dataKey); 113 | var t = typeof(options); 114 | if (t === "string" && searcher) 115 | { 116 | searcher[options].apply(searcher, args); 117 | if (options === "dispose") 118 | $.removeData(this, dataKey); 119 | } 120 | else if (t === "object") 121 | { 122 | if (!searcher) 123 | // create a new searcher 124 | $.data(this, dataKey, new Searcher(this, options)); 125 | else 126 | // update the options of the existing 127 | $.extend(searcher.options, options); 128 | } 129 | }); 130 | }; 131 | 132 | } 133 | 134 | // AMD style (register as an anonymous module) 135 | if (typeof(define) === "function" && define.amd) 136 | define(["jquery"], factory); 137 | // node/CommonJS style (for Browserify) 138 | else if (typeof(exports) === "object") 139 | module.exports = factory; 140 | // browser 141 | else 142 | factory(jQuery); 143 | 144 | }).call(this); 145 | -------------------------------------------------------------------------------- /examples/list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | List example 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | #. Title - Artist (Year) 18 |
    19 |
  1. Like a Rolling Stone - Bob Dylan (1965)
  2. 20 |
  3. (I Can't Get No) Satisfaction - The Rolling Stones (1965)
  4. 21 |
  5. Imagine - John Lennon (1971)
  6. 22 |
  7. What's Going On - Marvin Gaye (1971)
  8. 23 |
  9. Respect - Aretha Franklin (1967)
  10. 24 |
  11. Good Vibrations - The Beach Boys (1966)
  12. 25 |
  13. Johnny B. Goode - Chuck Berry (1958)
  14. 26 |
  15. Hey Jude - The Beatles (1968)
  16. 27 |
  17. Smells Like Teen Spirit - Nirvana (1991)
  18. 28 |
  19. What'd I Say - Ray Charles (1959)
  20. 29 |
  21. My Generation - The Who (1965)
  22. 30 |
  23. A Change Is Gonna Come - Sam Cooke (1964)
  24. 31 |
  25. Yesterday - The Beatles (1965)
  26. 32 |
  27. Blowin' in the Wind - Bob Dylan (1963)
  28. 33 |
  29. London Calling - The Clash (1980)
  30. 34 |
  31. I Want to Hold Your Hand - The Beatles (1963)
  32. 35 |
  33. Purple Haze - Jimi Hendrix (1967)
  34. 36 |
  35. Maybellene - Chuck Berry (1955)
  36. 37 |
  37. Hound Dog - Elvis Presley (1956)
  38. 38 |
  39. Let It Be - The Beatles (1970)
  40. 39 |
  41. Born to Run - Bruce Springsteen (1975)
  42. 40 |
  43. Be My Baby - The Ronettes (1963)
  44. 41 |
  45. In My Life - The Beatles (1965)
  46. 42 |
  47. People Get Ready - The Impressions (1965)
  48. 43 |
  49. God Only Knows - The Beach Boys (1966)
  50. 44 |
  51. A Day in the Life - The Beatles (1967)
  52. 45 |
  53. Layla - Derek and the Dominos (1970)
  54. 46 |
  55. (Sittin' on) the Dock of the Bay - Otis Redding (1968)
  56. 47 |
  57. Help! - The Beatles (1965)
  58. 48 |
  59. I Walk the Line - Johnny Cash (1956)
  60. 49 |
  61. Stairway to Heaven - Led Zeppelin (1971)
  62. 50 |
  63. Sympathy for the Devil - The Rolling Stones (1968)
  64. 51 |
  65. River Deep, Mountain High - Tina Turner (1966)
  66. 52 |
  67. You've Lost That Lovin' Feeling - Righteous Brothers (1964)
  68. 53 |
  69. Light My Fire - The Doors (1967)
  70. 54 |
  71. One - U2 (1991)
  72. 55 |
  73. No Woman, No Cry - Bob Marley (1975)
  74. 56 |
  75. Gimme Shelter - The Rolling Stones (1969)
  76. 57 |
  77. That'll Be the Day - Buddy Holly (1957)
  78. 58 |
  79. Dancin' in the Streets - Martha and the Vandellas (1964)
  80. 59 |
  81. The Weight - The Band (1968)
  82. 60 |
  83. Waterloo Sunset - The Kinks (1968)
  84. 61 |
  85. Tutti Frutti - Little Richard (1956)
  86. 62 |
  87. Georgia on My Mind - Ray Charles (1960)
  88. 63 |
  89. Heartbreak Hotel - Elvis Presley (1956)
  90. 64 |
  91. Heroes - David Bowie (1977)
  92. 65 |
  93. Bridge Over Troubled Water - Simon & Garfunkel (1970)
  94. 66 |
  95. All Along the Watchtower - Jimi Hendrix (1968)
  96. 67 |
  97. Hotel California - The Eagles (1976)
  98. 68 |
  99. The Tracks of My Tears - Smokey Robinson (1965)
  100. 69 |
  101. The Message - Grandmaster Flash (1982)
  102. 70 |
  103. When Doves Cry - Prince (1984)
  104. 71 |
  105. Anarchy in the U.K. - The Sex Pistols (1977)
  106. 72 |
  107. When a Man Loves a Woman - Percy Sledge (1966)
  108. 73 |
  109. Louie Louie - The Kingsmen (1963)
  110. 74 |
  111. Long Tall Sally - Little Richard (1956)
  112. 75 |
  113. A Whiter Shade of Pale - Procol Harum (1967)
  114. 76 |
  115. Billie Jean - Michael Jackson (1983)
  116. 77 |
  117. The Times They Are A-Changin' - Bob Dylan (1964)
  118. 78 |
  119. Let's Stay Together - Al Green (1971)
  120. 79 |
  121. Whole Lotta Shakin' Going On - Jerry Lee Lewis (1957)
  122. 80 |
  123. Bo Diddley - Bo Diddley (1955)
  124. 81 |
  125. For What It's Worth - Buffalo Springfield (1967)
  126. 82 |
  127. She Loves You - The Beatles (1963)
  128. 83 |
  129. Sunshine of Your Love - Cream (1968)
  130. 84 |
  131. Redemption Song - Bob Marley (1980)
  132. 85 |
  133. Jailhouse Rock - Elvis Presley (1957)
  134. 86 |
  135. Tangled Up in Blue - Bob Dylan (1975)
  136. 87 |
  137. Crying - Roy Orbison (1961)
  138. 88 |
  139. Walk On By - Dionne Warwick (1964)
  140. 89 |
  141. California Girls - The Beach Boys (1965)
  142. 90 |
  143. Papa's Got a Brand New Bag - James Brown (1966)
  144. 91 |
  145. Summertime Blues - Eddie Cochran (1958)
  146. 92 |
  147. Superstition - Stevie Wonder (1972)
  148. 93 |
  149. Whole Lotta Love - Led Zeppelin (1969)
  150. 94 |
  151. Strawberry Fields Forever - The Beatles (1967)
  152. 95 |
  153. Mystery Train - Elvis Presley (1955)
  154. 96 |
  155. I Got You (I Feel Good) - James Brown (1965)
  156. 97 |
  157. Mr. Tambourine Man - The Byrds (1965)
  158. 98 |
  159. I Heard It Through the Grapevine - Marvin Gaye (1968)
  160. 99 |
  161. Blueberry Hill - Fats Domino (1956)
  162. 100 |
  163. You Really Got Me - The Kinks (1964)
  164. 101 |
  165. Norwegian Wood (This Bird Has Flown) - The Beatles (1965)
  166. 102 |
  167. Every Breath You Take - The Police (1983)
  168. 103 |
  169. Crazy - Patsy Cline (1961)
  170. 104 |
  171. Thunder Road - Bruce Springsteen (1975)
  172. 105 |
  173. Ring of Fire - Johnny Cash (1963)
  174. 106 |
  175. My Girl - The Temptations (1965)
  176. 107 |
  177. California Dreamin' - The Mamas & The Papas (1965)
  178. 108 |
  179. In the Still of the Night - The Five Satins (1956)
  180. 109 |
  181. Suspicious Minds - Elvis Presley (1969)
  182. 110 |
  183. Blitzkrieg Bop - The Ramones (1976)
  184. 111 |
  185. I Still Haven't Found What I'm Looking For - U2 (1987)
  186. 112 |
  187. Good Golly, Miss Molly - Little Richard (1958)
  188. 113 |
  189. Blue Suede Shoes - Carl Perkins (1956)
  190. 114 |
  191. Great Balls of Fire - Jerry Lee Lewis (1957)
  192. 115 |
  193. Roll Over Beethoven - Chuck Berry (1956)
  194. 116 |
  195. Love and Happiness - Al Green (1972)
  196. 117 |
  197. Fortunate Son - Creedence Clearwater Revival (1969)
  198. 118 |
  199. You Can't Always Get What You Want - Rolling Stones (1969)
  200. 119 |
120 | 127 | 128 | -------------------------------------------------------------------------------- /examples/table.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Table example 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 |
#TitleArtistDate
1Like a Rolling StoneBob Dylan1965
2(I Can't Get No) SatisfactionThe Rolling Stones1965
3ImagineJohn Lennon1971
4What's Going OnMarvin Gaye1971
5RespectAretha Franklin1967
6Good VibrationsThe Beach Boys1966
7Johnny B. GoodeChuck Berry1958
8Hey JudeThe Beatles1968
9Smells Like Teen SpiritNirvana1991
10What'd I SayRay Charles1959
11My GenerationThe Who1965
12A Change Is Gonna ComeSam Cooke1964
13YesterdayThe Beatles1965
14Blowin' in the WindBob Dylan1963
15London CallingThe Clash1980
16I Want to Hold Your HandThe Beatles1963
17Purple HazeJimi Hendrix1967
18MaybelleneChuck Berry1955
19Hound DogElvis Presley1956
20Let It BeThe Beatles1970
21Born to RunBruce Springsteen1975
22Be My BabyThe Ronettes1963
23In My LifeThe Beatles1965
24People Get ReadyThe Impressions1965
25God Only KnowsThe Beach Boys1966
26A Day in the LifeThe Beatles1967
27LaylaDerek and the Dominos1970
28(Sittin' on) the Dock of the BayOtis Redding1968
29Help!The Beatles1965
30I Walk the LineJohnny Cash1956
31Stairway to HeavenLed Zeppelin1971
32Sympathy for the DevilThe Rolling Stones1968
33River Deep, Mountain HighTina Turner1966
34You've Lost That Lovin' FeelingRighteous Brothers1964
35Light My FireThe Doors1967
36OneU21991
37No Woman, No CryBob Marley1975
38Gimme ShelterThe Rolling Stones1969
39That'll Be the DayBuddy Holly1957
40Dancin' in the StreetsMartha and the Vandellas1964
41The WeightThe Band1968
42Waterloo SunsetThe Kinks1968
43Tutti FruttiLittle Richard1956
44Georgia on My MindRay Charles1960
45Heartbreak HotelElvis Presley1956
46HeroesDavid Bowie1977
47Bridge Over Troubled WaterSimon & Garfunkel1970
48All Along the WatchtowerJimi Hendrix1968
49Hotel CaliforniaThe Eagles1976
50The Tracks of My TearsSmokey Robinson1965
51The MessageGrandmaster Flash1982
52When Doves CryPrince1984
53Anarchy in the U.K.The Sex Pistols1977
54When a Man Loves a WomanPercy Sledge1966
55Louie LouieThe Kingsmen1963
56Long Tall SallyLittle Richard1956
57A Whiter Shade of PaleProcol Harum1967
58Billie JeanMichael Jackson1983
59The Times They Are A-Changin'Bob Dylan1964
60Let's Stay TogetherAl Green1971
61Whole Lotta Shakin' Going OnJerry Lee Lewis1957
62Bo DiddleyBo Diddley1955
63For What It's WorthBuffalo Springfield1967
64She Loves YouThe Beatles1963
65Sunshine of Your LoveCream1968
66Redemption SongBob Marley1980
67Jailhouse RockElvis Presley1957
68Tangled Up in BlueBob Dylan1975
69CryingRoy Orbison1961
70Walk On ByDionne Warwick1964
71California GirlsThe Beach Boys1965
72Papa's Got a Brand New BagJames Brown1966
73Summertime BluesEddie Cochran1958
74SuperstitionStevie Wonder1972
75Whole Lotta LoveLed Zeppelin1969
76Strawberry Fields ForeverThe Beatles1967
77Mystery TrainElvis Presley1955
78I Got You (I Feel Good)James Brown1965
79Mr. Tambourine ManThe Byrds1965
80I Heard It Through the GrapevineMarvin Gaye1968
81Blueberry HillFats Domino1956
82You Really Got MeThe Kinks1964
83Norwegian Wood (This Bird Has Flown)The Beatles1965
84Every Breath You TakeThe Police1983
85CrazyPatsy Cline1961
86Thunder RoadBruce Springsteen1975
87Ring of FireJohnny Cash1963
88My GirlThe Temptations1965
89California Dreamin'The Mamas & The Papas1965
90In the Still of the NightThe Five Satins1956
91Suspicious MindsElvis Presley1969
92Blitzkrieg BopThe Ramones1976
93I Still Haven't Found What I'm Looking ForU21987
94Good Golly, Miss MollyLittle Richard1958
95Blue Suede ShoesCarl Perkins1956
96Great Balls of FireJerry Lee Lewis1957
97Roll Over BeethovenChuck Berry1956
98Love and HappinessAl Green1972
99Fortunate SonCreedence Clearwater Revival1969
100You Can't Always Get What You WantRolling Stones1969
129 | 134 | 135 | -------------------------------------------------------------------------------- /tests/tests.js: -------------------------------------------------------------------------------- 1 | /*global module, test, ok, equal, deepEqual */ 2 | 3 | (function() { 4 | 5 | "use strict"; 6 | 7 | module("jQuery Searcher Tests", { 8 | teardown: function() 9 | { 10 | $table.searcher("dispose"); 11 | $list.searcher("dispose"); 12 | $any.searcher("dispose"); 13 | } 14 | }); 15 | 16 | var inputSelector = "#testinput"; 17 | var $input = $(inputSelector); 18 | var $table = $("#testtable"); 19 | var $list = $("#testlist"); 20 | var $any = $("#testany"); 21 | 22 | var testData = { 23 | "dylan": ["1", "Like a Rolling Stone", "Bob Dylan", "1965"], 24 | "stones": ["2", "(I Can't Get No) Satisfaction", "The Rolling Stones", "1965"], 25 | "lennon": ["3", "Imagine", "John Lennon", "1971"], 26 | "gaye": ["4", "What's Going On", "Marvin Gaye", "1971"], 27 | "franklin": ["5", "Respect", "Aretha Franklin", "1967"] 28 | }; 29 | 30 | /* 31 | * BASIC TESTS 32 | */ 33 | 34 | test("plugin exists", function() { 35 | // on any jQuery wrapped element 36 | ok($table.searcher); 37 | ok($list.searcher); 38 | ok($any.searcher); 39 | }); 40 | 41 | test("basic table", function() { 42 | // GIVEN: a table and an input 43 | // WHEN: I connect the table and the input 44 | $table.searcher({ 45 | inputSelector: inputSelector 46 | }); 47 | 48 | // AND: run some basic tests 49 | var $items = $table.find("tr"); 50 | basicTests($items); 51 | }); 52 | 53 | test("basic list", function() { 54 | // GIVEN: a list and an input 55 | // WHEN: I connect the list and an input 56 | $list.searcher({ 57 | inputSelector: inputSelector, 58 | itemSelector: "li", 59 | textSelector: "" 60 | }); 61 | 62 | // AND: run some basic tests 63 | var $items = $list.find("li"); 64 | basicTests($items); 65 | }); 66 | 67 | test("basic any", function() { 68 | // GIVEN: a list like structure and an input 69 | // WHEN: I connect the list like structure and the input 70 | $any.searcher({ 71 | inputSelector: inputSelector, 72 | itemSelector: ".item", 73 | textSelector: "> *" 74 | }); 75 | 76 | // AND: run some basic tests 77 | var $items = $any.find(".item"); 78 | basicTests($items); 79 | }); 80 | 81 | function basicTests($items) 82 | { 83 | // THEN: nothing should have changed for the items (all 5 are visible) 84 | assertItems($items.filter(":visible"), ["dylan", "stones", "lennon", "gaye", "franklin"]); 85 | 86 | // WHEN: I change the text in the input to "a" 87 | write("a"); 88 | // THEN: all items are visible because everyone contains an "a" 89 | assertItems($items.filter(":visible"), ["dylan", "stones", "lennon", "gaye", "franklin"]); 90 | 91 | // WHEN: I change the text in the input to "rolling" 92 | write("rolling"); 93 | // THEN: "Bob Dylan" (title contains "Rolling") and "The Rolling Stones" are visible 94 | assertItems($items.filter(":visible"), ["dylan", "stones"]); 95 | 96 | // WHEN: I change the text in the input to "john" 97 | write("john"); 98 | // THEN: only "John Lennon" is visible 99 | assertItems($items.filter(":visible"), ["lennon"]); 100 | 101 | // WHEN: I change the text in the input to "1971" 102 | write("1971"); 103 | // THEN: "John Lennon" and "Aretha Franklin" are visible (date is "1971") 104 | assertItems($items.filter(":visible"), ["lennon", "gaye"]); 105 | 106 | // WHEN: I clear the text in the input 107 | write(""); 108 | // THEN: all items should be visible again 109 | assertItems($items.filter(":visible"), ["dylan", "stones", "lennon", "gaye", "franklin"]); 110 | } 111 | 112 | /* 113 | * OPTION caseSensitive 114 | */ 115 | 116 | test("caseSensitive table", function() { 117 | // GIVEN: a connected table and input 118 | $table.searcher({ 119 | inputSelector: inputSelector, 120 | // AND: case sensitive search is activated 121 | caseSensitive: true 122 | }); 123 | 124 | // WHEN: I run some tests 125 | var $items = $table.find("tr"); 126 | caseSensitiveTests($items); 127 | 128 | // wHEN: I change the caseSensitive option to false 129 | $table.searcher({ 130 | caseSensitive: false 131 | }); 132 | 133 | // THEN: all basic tests should work 134 | basicTests($items); 135 | }); 136 | 137 | test("caseSensitive list", function() { 138 | // GIVEN: a connected list and input 139 | $list.searcher({ 140 | inputSelector: inputSelector, 141 | itemSelector: "li", 142 | textSelector: "", 143 | // AND: case sensitive search is activated 144 | caseSensitive: true 145 | }); 146 | 147 | // WHEN: I run some tests 148 | var $items = $list.find("li"); 149 | caseSensitiveTests($items); 150 | 151 | // wHEN: I change the caseSensitive option to false 152 | $list.searcher({ 153 | caseSensitive: false 154 | }); 155 | 156 | // THEN: all basic tests should work 157 | basicTests($items); 158 | }); 159 | 160 | test("caseSensitive any", function() { 161 | // GIVEN: a connected list-like structure and input 162 | $any.searcher({ 163 | inputSelector: inputSelector, 164 | itemSelector: ".item", 165 | textSelector: "> *", 166 | // AND: case sensitive search is activated 167 | caseSensitive: true 168 | }); 169 | 170 | // WHEN: I run some tests 171 | var $items = $any.find(".item"); 172 | caseSensitiveTests($items); 173 | 174 | // wHEN: I change the caseSensitive option to false 175 | $any.searcher({ 176 | caseSensitive: false 177 | }); 178 | 179 | // THEN: all basic tests should work 180 | basicTests($items); 181 | }); 182 | 183 | function caseSensitiveTests($items) 184 | { 185 | // THEN: nothing should have changed for the items (all 5 are visible) 186 | assertItems($items.filter(":visible"), ["dylan", "stones", "lennon", "gaye", "franklin"]); 187 | 188 | // WHEN: I change the text in the input to "l" 189 | write("l"); 190 | // THEN: "Bob Dylan", "The Rolling Stones" and "Aretha Franklin" are visible 191 | assertItems($items.filter(":visible"), ["dylan", "stones", "franklin"]); 192 | 193 | // WHEN: I change the text in the input to "L" 194 | write("L"); 195 | // THEN: "Bob Dylan" (title contains "L") and "John Lennon" are visible 196 | assertItems($items.filter(":visible"), ["dylan", "lennon"]); 197 | 198 | // WHEN: I change the text in the input to "rolling" 199 | write("rolling"); 200 | // THEN: no item is visible because non of the items contains "rolling" 201 | assertItems($items.filter(":visible"), []); 202 | 203 | // WHEN: I change the text in the input to "Rolling" 204 | write("Rolling"); 205 | // THEN: "Bob Dylan" (title contains "Rolling") and "The Rolling Stones" are visible 206 | assertItems($items.filter(":visible"), ["dylan", "stones"]); 207 | 208 | // WHEN: I change the text in the input to "1971" 209 | write("1971"); 210 | // THEN: "John Lennon" and "Aretha Franklin" are visible (date is "1971") 211 | assertItems($items.filter(":visible"), ["lennon", "gaye"]); 212 | 213 | // WHEN: I clear the text in the input 214 | write(""); 215 | // THEN: all items should be visible again 216 | assertItems($items.filter(":visible"), ["dylan", "stones", "lennon", "gaye", "franklin"]); 217 | } 218 | 219 | /* 220 | * OPTION toggle 221 | */ 222 | 223 | test("toggle table", function() { 224 | // GIVEN: a connected table and input 225 | $table.searcher({ 226 | inputSelector: inputSelector, 227 | // AND: a custom toggle function 228 | toggle: function(item, containsText) 229 | { 230 | $(item).toggleClass("containsText", containsText); 231 | } 232 | }); 233 | 234 | // WHEN: I run some tests 235 | var $items = $table.find("tr"); 236 | toggleTests($items); 237 | 238 | // wHEN: I change the toggle function back to it's default 239 | $table.searcher({ 240 | toggle: null 241 | }); 242 | 243 | // THEN: all basic tests should work 244 | basicTests($items); 245 | }); 246 | 247 | test("toggle list", function() { 248 | // GIVEN: a connected list and input 249 | $list.searcher({ 250 | inputSelector: inputSelector, 251 | itemSelector: "li", 252 | textSelector: "", 253 | // AND: a custom toggle function 254 | toggle: function(item, containsText) 255 | { 256 | $(item).toggleClass("containsText", containsText); 257 | } 258 | }); 259 | 260 | // WHEN: I run some tests 261 | var $items = $list.find("li"); 262 | toggleTests($items); 263 | 264 | // wHEN: I change the toggle function back to it's default 265 | $list.searcher({ 266 | toggle: null 267 | }); 268 | 269 | // THEN: all basic tests should work 270 | basicTests($items); 271 | }); 272 | 273 | test("toggle any", function() { 274 | // GIVEN: a connected list-like structure and input 275 | $any.searcher({ 276 | inputSelector: inputSelector, 277 | itemSelector: ".item", 278 | textSelector: "> *", 279 | // AND: a custom toggle function 280 | toggle: function(item, containsText) 281 | { 282 | $(item).toggleClass("containsText", containsText); 283 | } 284 | }); 285 | 286 | // WHEN: I run some tests 287 | var $items = $any.find(".item"); 288 | toggleTests($items); 289 | 290 | // wHEN: I change the toggle function back to it's default 291 | $any.searcher({ 292 | toggle: null 293 | }); 294 | 295 | // THEN: all basic tests should work 296 | basicTests($items); 297 | }); 298 | 299 | function toggleTests($items) 300 | { 301 | // THEN: nothing has changed for the items (all 5 are visible) 302 | assertItems($items.filter(".containsText"), ["dylan", "stones", "lennon", "gaye", "franklin"]); 303 | 304 | // WHEN: I change the text in the input to "a" 305 | write("a"); 306 | // THEN: all items have the "containsText" class because everyone contains an "a" 307 | assertItems($items.filter(".containsText"), ["dylan", "stones", "lennon", "gaye", "franklin"]); 308 | 309 | // WHEN: I change the text in the input to "rolling" 310 | write("rolling"); 311 | // THEN: "Bob Dylan" (title contains "Rolling") and "The Rolling Stones" have the "containsText" class 312 | assertItems($items.filter(".containsText"), ["dylan", "stones"]); 313 | 314 | // WHEN: I change the text in the input to "john" 315 | write("john"); 316 | // THEN: only "John Lennon" has the "containsText" class 317 | assertItems($items.filter(".containsText"), ["lennon"]); 318 | 319 | // WHEN: I change the text in the input to "1971" 320 | write("1971"); 321 | // THEN: "John Lennon" and "Aretha Franklin" have the "containsText" class (date is "1971") 322 | assertItems($items.filter(".containsText"), ["lennon", "gaye"]); 323 | 324 | // WHEN: I clear the text in the input 325 | write(""); 326 | // THEN: all items have the "containsText" class 327 | assertItems($items.filter(".containsText"), ["dylan", "stones", "lennon", "gaye", "franklin"]); 328 | } 329 | 330 | /* 331 | * public function "filter" 332 | */ 333 | 334 | test("filter function", function() { 335 | // GIVEN: a connected table and input 336 | $table.searcher({ 337 | inputSelector: inputSelector 338 | }); 339 | 340 | // WHEN: I run some tests 341 | var $items = $table.find("tr"); 342 | 343 | // WHEN: I filter the items with "a" 344 | $table.searcher("filter", "a"); 345 | // THEN: all items are visible because everyone contains an "a" 346 | assertItems($items.filter(":visible"), ["dylan", "stones", "lennon", "gaye", "franklin"]); 347 | 348 | // WHEN: I filter the items with "rolling" 349 | $table.searcher("filter", "rolling"); 350 | // THEN: "Bob Dylan" (title contains "Rolling") and "The Rolling Stones" are visible 351 | assertItems($items.filter(":visible"), ["dylan", "stones"]); 352 | 353 | // WHEN: I filter the items with "john" 354 | $table.searcher("filter", "john"); 355 | // THEN: only "John Lennon" is visible 356 | assertItems($items.filter(":visible"), ["lennon"]); 357 | 358 | // WHEN: I filter the items with "1971" 359 | $table.searcher("filter", "1971"); 360 | // THEN: "John Lennon" and "Aretha Franklin" are visible (date is "1971") 361 | assertItems($items.filter(":visible"), ["lennon", "gaye"]); 362 | 363 | // WHEN: I filter the items with "" 364 | $table.searcher("filter", ""); 365 | // THEN: all items should be visible again 366 | assertItems($items.filter(":visible"), ["dylan", "stones", "lennon", "gaye", "franklin"]); 367 | }); 368 | 369 | /* 370 | * HELPERS 371 | */ 372 | 373 | function write(text) 374 | { 375 | $input.val(text).change(); 376 | // info for debugging purposes - could be removed 377 | ok(true, "changed text to '" + text + "'"); 378 | } 379 | 380 | function assertItems($elements, expectedData) 381 | { 382 | var expected = expectedData.length; 383 | equal($elements.length, expected, expected + " item(s) should be visible"); 384 | $elements.each(function(i) { 385 | assertItem($(this), testData[expectedData[i]]); 386 | }); 387 | } 388 | 389 | function assertItem($item, expectedData) 390 | { 391 | var actualData = []; 392 | $item.children().each(function() { 393 | actualData.push($(this).text()); 394 | }); 395 | deepEqual(actualData, expectedData); 396 | } 397 | 398 | }).call(this); 399 | -------------------------------------------------------------------------------- /examples/card.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Card example 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
#1
Like a Rolling Stone
Bob Dylan
1965
19 |
#2
(I Can't Get No) Satisfaction
The Rolling Stones
1965
20 |
#3
Imagine
John Lennon
1971
21 |
#4
What's Going On
Marvin Gaye
1971
22 |
#5
Respect
Aretha Franklin
1967
23 |
#6
Good Vibrations
The Beach Boys
1966
24 |
#7
Johnny B. Goode
Chuck Berry
1958
25 |
#8
Hey Jude
The Beatles
1968
26 |
#9
Smells Like Teen Spirit
Nirvana
1991
27 |
#10
What'd I Say
Ray Charles
1959
28 |
#11
My Generation
The Who
1965
29 |
#12
A Change Is Gonna Come
Sam Cooke
1964
30 |
#13
Yesterday
The Beatles
1965
31 |
#14
Blowin' in the Wind
Bob Dylan
1963
32 |
#15
London Calling
The Clash
1980
33 |
#16
I Want to Hold Your Hand
The Beatles
1963
34 |
#17
Purple Haze
Jimi Hendrix
1967
35 |
#18
Maybellene
Chuck Berry
1955
36 |
#19
Hound Dog
Elvis Presley
1956
37 |
#20
Let It Be
The Beatles
1970
38 |
#21
Born to Run
Bruce Springsteen
1975
39 |
#22
Be My Baby
The Ronettes
1963
40 |
#23
In My Life
The Beatles
1965
41 |
#24
People Get Ready
The Impressions
1965
42 |
#25
God Only Knows
The Beach Boys
1966
43 |
#26
A Day in the Life
The Beatles
1967
44 |
#27
Layla
Derek and the Dominos
1970
45 |
#28
(Sittin' on) the Dock of the Bay
Otis Redding
1968
46 |
#29
Help!
The Beatles
1965
47 |
#30
I Walk the Line
Johnny Cash
1956
48 |
#31
Stairway to Heaven
Led Zeppelin
1971
49 |
#32
Sympathy for the Devil
The Rolling Stones
1968
50 |
#33
River Deep, Mountain High
Tina Turner
1966
51 |
#34
You've Lost That Lovin' Feeling
Righteous Brothers
1964
52 |
#35
Light My Fire
The Doors
1967
53 |
#36
One
U2
1991
54 |
#37
No Woman, No Cry
Bob Marley
1975
55 |
#38
Gimme Shelter
The Rolling Stones
1969
56 |
#39
That'll Be the Day
Buddy Holly
1957
57 |
#40
Dancin' in the Streets
Martha and the Vandellas
1964
58 |
#41
The Weight
The Band
1968
59 |
#42
Waterloo Sunset
The Kinks
1968
60 |
#43
Tutti Frutti
Little Richard
1956
61 |
#44
Georgia on My Mind
Ray Charles
1960
62 |
#45
Heartbreak Hotel
Elvis Presley
1956
63 |
#46
Heroes
David Bowie
1977
64 |
#47
Bridge Over Troubled Water
Simon & Garfunkel
1970
65 |
#48
All Along the Watchtower
Jimi Hendrix
1968
66 |
#49
Hotel California
The Eagles
1976
67 |
#50
The Tracks of My Tears
Smokey Robinson
1965
68 |
#51
The Message
Grandmaster Flash
1982
69 |
#52
When Doves Cry
Prince
1984
70 |
#53
Anarchy in the U.K.
The Sex Pistols
1977
71 |
#54
When a Man Loves a Woman
Percy Sledge
1966
72 |
#55
Louie Louie
The Kingsmen
1963
73 |
#56
Long Tall Sally
Little Richard
1956
74 |
#57
A Whiter Shade of Pale
Procol Harum
1967
75 |
#58
Billie Jean
Michael Jackson
1983
76 |
#59
The Times They Are A-Changin'
Bob Dylan
1964
77 |
#60
Let's Stay Together
Al Green
1971
78 |
#61
Whole Lotta Shakin' Going On
Jerry Lee Lewis
1957
79 |
#62
Bo Diddley
Bo Diddley
1955
80 |
#63
For What It's Worth
Buffalo Springfield
1967
81 |
#64
She Loves You
The Beatles
1963
82 |
#65
Sunshine of Your Love
Cream
1968
83 |
#66
Redemption Song
Bob Marley
1980
84 |
#67
Jailhouse Rock
Elvis Presley
1957
85 |
#68
Tangled Up in Blue
Bob Dylan
1975
86 |
#69
Crying
Roy Orbison
1961
87 |
#70
Walk On By
Dionne Warwick
1964
88 |
#71
California Girls
The Beach Boys
1965
89 |
#72
Papa's Got a Brand New Bag
James Brown
1966
90 |
#73
Summertime Blues
Eddie Cochran
1958
91 |
#74
Superstition
Stevie Wonder
1972
92 |
#75
Whole Lotta Love
Led Zeppelin
1969
93 |
#76
Strawberry Fields Forever
The Beatles
1967
94 |
#77
Mystery Train
Elvis Presley
1955
95 |
#78
I Got You (I Feel Good)
James Brown
1965
96 |
#79
Mr. Tambourine Man
The Byrds
1965
97 |
#80
I Heard It Through the Grapevine
Marvin Gaye
1968
98 |
#81
Blueberry Hill
Fats Domino
1956
99 |
#82
You Really Got Me
The Kinks
1964
100 |
#83
Norwegian Wood (This Bird Has Flown)
The Beatles
1965
101 |
#84
Every Breath You Take
The Police
1983
102 |
#85
Crazy
Patsy Cline
1961
103 |
#86
Thunder Road
Bruce Springsteen
1975
104 |
#87
Ring of Fire
Johnny Cash
1963
105 |
#88
My Girl
The Temptations
1965
106 |
#89
California Dreamin'
The Mamas & The Papas
1965
107 |
#90
In the Still of the Night
The Five Satins
1956
108 |
#91
Suspicious Minds
Elvis Presley
1969
109 |
#92
Blitzkrieg Bop
The Ramones
1976
110 |
#93
I Still Haven't Found What I'm Looking For
U2
1987
111 |
#94
Good Golly, Miss Molly
Little Richard
1958
112 |
#95
Blue Suede Shoes
Carl Perkins
1956
113 |
#96
Great Balls of Fire
Jerry Lee Lewis
1957
114 |
#97
Roll Over Beethoven
Chuck Berry
1956
115 |
#98
Love and Happiness
Al Green
1972
116 |
#99
Fortunate Son
Creedence Clearwater Revival
1969
117 |
#100
You Can't Always Get What You Want
Rolling Stones
1969
118 |
119 | 133 | 134 | --------------------------------------------------------------------------------