├── .gitignore ├── CONTRIBUTING.md ├── Gruntfile.js ├── LICENSE ├── README.md ├── bootstrap-list-filter.min.js ├── bootstrap-list-filter.src.js ├── examples ├── cancel-button.html ├── cities.json ├── custom-list-item.html ├── dynamic-list-search.html ├── multiple-field.html ├── restaurants.geojson.js ├── search.php └── static.html ├── images ├── bootstrap-list-filter.png └── loader.gif ├── index.html ├── index.tmpl.html ├── package.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | bower_components/ 3 | packages/ 4 | npm-debug.log 5 | node_modules 6 | components 7 | smart.lock 8 | .versions 9 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | might be useful to include event management. 2 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(grunt) { 4 | 5 | grunt.initConfig({ 6 | pkg: grunt.file.readJSON('package.json'), 7 | meta: { 8 | banner: 9 | '/* \n'+ 10 | ' * <%= pkg.name %> v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %> \n'+ 11 | ' * \n'+ 12 | ' * Copyright <%= grunt.template.today("yyyy") %> <%= pkg.author.name %> \n'+ 13 | ' * <%= pkg.author.email %> \n'+ 14 | ' * <%= pkg.author.url %> \n'+ 15 | ' * \n'+ 16 | ' * Licensed under the <%= pkg.license %> license. \n'+ 17 | ' * \n'+ 18 | ' * Demos: \n'+ 19 | ' * <%= pkg.homepage %> \n'+ 20 | ' * \n'+ 21 | ' * Source: \n'+ 22 | ' * <%= pkg.repository.url %> \n'+ 23 | ' * \n'+ 24 | ' */\n' 25 | }, 26 | clean: { 27 | dist: { 28 | src: ['index.html','bootstrap-list-filter.min.js'] 29 | } 30 | }, 31 | jshint: { 32 | options: { 33 | globals: { 34 | console: true, 35 | module: true 36 | }, 37 | "-W099": true, //ignora tabs e space warning 38 | "-W033": true, 39 | "-W044": true //ignore regexp 40 | }, 41 | files: ['bootstrap-list-filter.src.js'] 42 | }, 43 | uglify: { 44 | options: { 45 | banner: '<%= meta.banner %>' 46 | }, 47 | dist: { 48 | files: { 49 | 'bootstrap-list-filter.min.js': ['bootstrap-list-filter.src.js'] 50 | } 51 | } 52 | }, 53 | markdown: { 54 | readme: { 55 | files: { 56 | 'index.html': ['README.md'] 57 | }, 58 | options: { 59 | template: 'index.tmpl.html', 60 | templateContext: function() { 61 | var cfg = grunt.config(); 62 | cfg.title = cfg.pkg.name.replace(/-/g,' '); 63 | cfg.ribbonurl = 'http://ghbtns.com/github-btn.html?user=stefanocudini&repo='+cfg.pkg.name+'&type=watch&count=true'; 64 | cfg.giturl = 'https://github.com/stefanocudini/'+cfg.pkg.name; 65 | cfg.biturl = 'https://bitbucket.org/zakis_/'+cfg.pkg.name; 66 | cfg.npmurl = 'https://npmjs.org/package/'+cfg.pkg.name; 67 | cfg.atmurl = 'http://atmospherejs.com/package/'+cfg.pkg.name; 68 | cfg.examples = grunt.file.expand('examples/*.html'); 69 | cfg.image = grunt.file.expand('images/'+cfg.pkg.name+'.png'); 70 | //console.log(cfg); 71 | return cfg; 72 | }, 73 | markdownOptions: { 74 | gfm: true, 75 | highlight: 'manual', 76 | codeLines: { 77 | before: '
', 78 | after: '
' 79 | } 80 | } 81 | } 82 | } 83 | } 84 | }); 85 | 86 | grunt.registerTask('default', [ 87 | 'clean', 88 | 'jshint', 89 | 'uglify', 90 | 'markdown' 91 | ]); 92 | 93 | grunt.loadNpmTasks('grunt-contrib-clean'); 94 | grunt.loadNpmTasks('grunt-contrib-jshint'); 95 | grunt.loadNpmTasks('grunt-contrib-uglify'); 96 | grunt.loadNpmTasks('grunt-markdown'); 97 | }; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Duy Anh Nguyen 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. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Bootstrap List Filter 2 | ============ 3 | 4 | [![npm version](https://badge.fury.io/js/bootstrap-list-filter.svg)](https://badge.fury.io/js/bootstrap-list-filter) 5 | 6 | Search widget to filter Bootstrap lists 7 | 8 | **Compatible with Bootstrap 3.3.7!** 9 | 10 | Author: Stefano Cudini [opengeo.tech](https://opengeo.tech/) 11 | 12 | **Demo online:** 13 | * [Homepage](https://opengeo.tech/bootstrap-list-filter/) 14 | * [Static example](https://opengeo.tech/bootstrap-list-filter/examples/static.html) 15 | * [Ajax example](https://opengeo.tech/bootstrap-list-filter/examples/dynamic-list-search.html) 16 | * [Custom items example](https://opengeo.tech/bootstrap-list-filter/examples/custom-list-item.html) 17 | 18 | **Features:** 19 | * complete mobile responsive 20 | * support preloaded list 21 | * custom html or node html item 22 | * custom data format 23 | * prevent parallel requests 24 | * filter by sub elements 25 | * search text in case sensitive 26 | 27 | 28 | # Options: 29 | * **delay:** millisecond before apply filter 30 | * **minLength:** min string lentgh searched 31 | * **initial:** search only initial text (default: true) 32 | * **eventKey:** event digit (default: 'keyup') 33 | * **resetOnBlur:** auto reset selection 34 | * **sourceData:** function generate data source(receive: text, callback) 35 | * **sourceTmpl:** html template contains {title} placeholder 36 | * **sourceNode:** function builder DOM html fragment (default: sourceTmpl) 37 | * **emptyNode:** function builder for empty result 38 | * **itemEl:** item selector (default: .list-group-item) 39 | * **itemChild:** sub item selector (default: .list-group-item) 40 | * **itemFilter:** function for filter results(receive: text, item) 41 | 42 | # Source 43 | * [Github](https://github.com/stefanocudini/bootstrap-list-filter) 44 | * [NPM](https://npmjs.org/package/bootstrap-list-filter) 45 | 46 | ![Image](https://raw.githubusercontent.com/stefanocudini/bootstrap-list-filter/master/images/bootstrap-list-filter.png) 47 | 48 | # Usage 49 | ```html 50 |
51 |
52 | 53 |
54 |
55 | blue 56 | ... 57 |
58 |
59 | 62 | ``` 63 | -------------------------------------------------------------------------------- /bootstrap-list-filter.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-list-filter v0.3.2 - 2016-10-26 3 | * 4 | * Copyright 2016 Stefano Cudini 5 | * stefano.cudini@gmail.com 6 | * https://opengeo.tech/ 7 | * 8 | * Licensed under the MIT license. 9 | * 10 | * Demos: 11 | * https://opengeo.tech/bootstrap-list-filter/ 12 | * 13 | * Source: 14 | * git@github.com:stefanocudini/bootstrap-list-filter.git 15 | * 16 | */ 17 | !function(a){a.fn.btsListFilter=function(b,c){"use strict";function d(a,b){return a.replace(/\{ *([\w_]+) *\}/g,function(a,c){return b[c]||""})}function e(b,d){d=d&&d.replace(new RegExp("[({[^.$*+?\\]})]","g"),"");var e=a(b).text(),f=c.initial?"^":"",g=new RegExp(f+d,c.casesensitive?"":"i");return g.test(e)}function f(a,b){var c;return b=b||300,function(){var d=this,e=arguments;clearTimeout(c),c=setTimeout(function(){a.apply(d,Array.prototype.slice.call(e))},b)}}var g,h,i=this,j=a(this),k=a(b),l=j;return c=a.extend({delay:300,minLength:1,initial:!0,casesensitive:!1,eventKey:"keyup",resetOnBlur:!0,sourceData:null,sourceTmpl:'{title}',sourceNode:function(a){return d(c.sourceTmpl,a)},emptyNode:function(a){return'No Results'},cancelNode:function(){return''},loadingClass:"bts-loading-list",itemClassTmp:"bts-dynamic-item",itemEl:".list-group-item",itemChild:null,itemFilter:e},c),i.reset=function(){k.val("").trigger(c.eventKey)},a.isFunction(c.cancelNode)&&(g=a(c.cancelNode.call(i)).hide(),k.after(g),k.parents(".form-group").addClass("has-feedback"),k.prev().is(".control-label")||g.css({top:0}),g.css({"pointer-events":"auto"}),g.on("click",i.reset)),k.on(c.eventKey,f(function(b){var d=a(this).val();c.itemEl&&(l=j.find(c.itemEl)),c.itemChild&&(l=l.find(c.itemChild));var e=l.filter(function(){return c.itemFilter.call(i,this,d)}),f=l.not(e);c.itemChild&&(e=e.parents(c.itemEl),f=f.parents(c.itemEl).hide()),""!==d&&d.length>=c.minLength?(e.show(),f.hide(),g.show(),"function"===a.type(c.sourceData)?(e.hide(),f.hide(),h&&(a.isFunction(h.abort)?h.abort():a.isFunction(h.stop)&&h.stop()),j.addClass(c.loadingClass),h=c.sourceData.call(i,d,function(b){if(h=null,e.hide(),f.hide(),j.find("."+c.itemClassTmp).remove(),b&&0!==b.length)for(var g in b)a(c.sourceNode.call(i,b[g])).addClass(c.itemClassTmp).appendTo(j);else a(c.emptyNode.call(i,d)).addClass(c.itemClassTmp).appendTo(j);j.removeClass(c.loadingClass)})):(j.find("."+c.itemClassTmp).remove(),0===e.length&&a(c.emptyNode.call(i,d)).addClass(c.itemClassTmp).appendTo(j))):(e.show(),f.show(),g.hide(),j.find("."+c.itemClassTmp).remove())},c.delay)),c.resetOnBlur&&k.on("blur",function(a){i.reset()}),j}}(jQuery); -------------------------------------------------------------------------------- /bootstrap-list-filter.src.js: -------------------------------------------------------------------------------- 1 | /* 2 | * OPTIONS 3 | * 4 | * delay *millisecond before apply filter* 5 | * minLength *min string lentgh searched* 6 | * initial *search only initial text (default: true)* 7 | * eventKey *event digit (default: 'keyup')* 8 | * resetOnBlur *auto reset selection* 9 | * sourceData *function generate data source(receive: text, callback)* 10 | * sourceTmpl *html template contains {title} placeholder* 11 | * sourceNode *function builder DOM html fragment (default: sourceTmpl)* 12 | * emptyNode *function builder for empty result* 13 | * itemEl *item selector (default: .list-group-item)*, 14 | * itemChild *sub item selector (default: .list-group-item)*, 15 | * itemFilter *function for filter results(receive: text, item)* 16 | */ 17 | (function($) { 18 | $.fn.btsListFilter = function(inputEl, opts) { 19 | 20 | 'use strict'; 21 | 22 | var self = this, 23 | searchlist$ = $(this), 24 | inputEl$ = $(inputEl), 25 | cancelEl$, 26 | items$ = searchlist$, 27 | callData, 28 | callReq; //last callData execution 29 | 30 | function tmpl(str, data) { 31 | return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) { 32 | return data[key] || ''; 33 | }); 34 | } 35 | 36 | function defaultItemFilter(item, val) { 37 | val = val && val.replace(new RegExp("[({[^.$*+?\\\]})]","g"),''); 38 | //sanitize regexp 39 | 40 | var text = $(item).text(), 41 | i = opts.initial ? '^' : '', 42 | regSearch = new RegExp(i + val, opts.casesensitive ? '' : 'i'); 43 | 44 | return regSearch.test( text ); 45 | } 46 | 47 | opts = $.extend({ 48 | delay: 300, 49 | minLength: 1, 50 | initial: true, 51 | casesensitive: false, 52 | eventKey: 'keyup', 53 | resetOnBlur: true, 54 | sourceData: null, 55 | sourceTmpl: '{title}', 56 | sourceNode: function(data) { 57 | return tmpl(opts.sourceTmpl, data); 58 | }, 59 | emptyNode: function(data) { 60 | return 'No Results'; 61 | }, 62 | cancelNode: function() { 63 | return ''; 64 | }, 65 | loadingClass: 'bts-loading-list', 66 | itemClassTmp: 'bts-dynamic-item', 67 | itemEl: '.list-group-item', 68 | itemChild: null, 69 | itemFilter: defaultItemFilter 70 | }, opts); 71 | 72 | function debouncer(func, timeout) { 73 | var timeoutID; 74 | timeout = timeout || 300; 75 | return function () { 76 | var scope = this , args = arguments; 77 | clearTimeout( timeoutID ); 78 | timeoutID = setTimeout( function () { 79 | func.apply( scope , Array.prototype.slice.call( args ) ); 80 | }, timeout); 81 | }; 82 | } 83 | 84 | self.reset = function() { 85 | inputEl$.val('').trigger(opts.eventKey); 86 | }; 87 | 88 | if($.isFunction(opts.cancelNode)) { 89 | 90 | cancelEl$ = $(opts.cancelNode.call(self)).hide(); 91 | 92 | inputEl$.after( cancelEl$ ); 93 | inputEl$.parents('.form-group').addClass('has-feedback'); 94 | 95 | if(!inputEl$.prev().is('.control-label')) 96 | cancelEl$.css({top: 0}); 97 | 98 | cancelEl$.css({'pointer-events': 'auto'}); 99 | 100 | cancelEl$.on('click', self.reset); 101 | } 102 | 103 | inputEl$.on(opts.eventKey, debouncer(function(e) { 104 | 105 | var val = $(this).val(); 106 | 107 | if(opts.itemEl) 108 | items$ = searchlist$.find(opts.itemEl); 109 | 110 | if(opts.itemChild) 111 | items$ = items$.find(opts.itemChild); 112 | 113 | var contains = items$.filter(function(){ 114 | return opts.itemFilter.call(self, this, val); 115 | }), 116 | containsNot = items$.not(contains); 117 | 118 | if (opts.itemChild){ 119 | contains = contains.parents(opts.itemEl); 120 | containsNot = containsNot.parents(opts.itemEl).hide(); 121 | } 122 | 123 | if(val!=='' && val.length >= opts.minLength) 124 | { 125 | contains.show(); 126 | containsNot.hide(); 127 | cancelEl$.show(); 128 | 129 | if($.type(opts.sourceData)==='function') 130 | { 131 | contains.hide(); 132 | containsNot.hide(); 133 | 134 | if(callReq) 135 | { 136 | if($.isFunction(callReq.abort)) 137 | callReq.abort(); 138 | else if($.isFunction(callReq.stop)) 139 | callReq.stop(); 140 | } 141 | 142 | searchlist$.addClass(opts.loadingClass); 143 | callReq = opts.sourceData.call(self, val, function(data) { 144 | callReq = null; 145 | contains.hide(); 146 | containsNot.hide(); 147 | searchlist$.find('.'+opts.itemClassTmp).remove(); 148 | 149 | if(!data || data.length===0) 150 | $( opts.emptyNode.call(self, val) ).addClass(opts.itemClassTmp).appendTo(searchlist$); 151 | else 152 | for(var i in data) 153 | $( opts.sourceNode.call(self, data[i]) ).addClass(opts.itemClassTmp).appendTo(searchlist$); 154 | 155 | searchlist$.removeClass(opts.loadingClass); 156 | }); 157 | } 158 | else { 159 | searchlist$.find('.'+opts.itemClassTmp).remove(); 160 | 161 | if(contains.length===0) 162 | $( opts.emptyNode.call(self, val) ).addClass(opts.itemClassTmp).appendTo(searchlist$); 163 | } 164 | 165 | } 166 | else 167 | { 168 | contains.show(); 169 | containsNot.show(); 170 | cancelEl$.hide(); 171 | searchlist$.find('.'+opts.itemClassTmp).remove(); 172 | } 173 | }, opts.delay)); 174 | 175 | if(opts.resetOnBlur) 176 | inputEl$.on('blur', function(e) { 177 | self.reset(); 178 | }); 179 | 180 | return searchlist$; 181 | }; 182 | 183 | })(jQuery); 184 | -------------------------------------------------------------------------------- /examples/cancel-button.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | example 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |

Bootstrap List Filter

16 | 17 |

Cancel Button Example

18 | 19 |
20 |
21 | 22 |
23 |
24 | aquamarine 25 | black 26 | blue 27 | chocolate 28 | coral 29 | cyan 30 | darkblue 31 | Darkred 32 | Darkgray 33 | dodgerblue 34 | gray 35 | green 36 | greenyellow 37 | red 38 | rosybrown 39 | royalblue 40 | salmon 41 | seagreen 42 | silver 43 | skyblue 44 | yellow 45 |
46 |
47 |
48 | 49 | 50 | 51 | 52 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /examples/cities.json: -------------------------------------------------------------------------------- 1 | [{"title":"Abovyan","lat":40.26741,"lon":44.62656}, 2 | {"title":"Ararat","lat":39.83166,"lon":44.70489}, 3 | {"title":"Armavir","lat":40.15446,"lon":44.03815}, 4 | {"title":"Artashat","lat":39.96144,"lon":44.54447}, 5 | {"title":"Ashtarak","lat":40.2991,"lon":44.36204}, 6 | {"title":"Avellaneda","lat":-29.11761,"lon":-59.65834}, 7 | {"title":"Azul","lat":-36.77698,"lon":-59.85854}, 8 | {"title":"Balkh","lat":36.75635,"lon":66.8972}, 9 | {"title":"Barranqueras","lat":-27.48299,"lon":-58.93579}, 10 | {"title":"Benguela","lat":-12.57626,"lon":13.40547}, 11 | {"title":"Berat","lat":40.70583,"lon":19.95222}, 12 | {"title":"Burrel","lat":41.61028,"lon":20.00889}, 13 | {"title":"Cabinda","lat":-5.55,"lon":12.2}, 14 | {"title":"Caluquembe","lat":-13.78333,"lon":14.68333}, 15 | {"title":"Camacupa","lat":-12.01667,"lon":17.48333}, 16 | {"title":"Campana","lat":-34.16874,"lon":-58.95914}, 17 | {"title":"Catabola","lat":-12.15,"lon":17.28333}, 18 | {"title":"Catumbela","lat":-12.43139,"lon":13.54722}, 19 | {"title":"Caxito","lat":-8.57848,"lon":13.66425}, 20 | {"title":"Charikar","lat":35.01361,"lon":69.17139}, 21 | {"title":"Colegiales","lat":-34.57365,"lon":-58.44924}, 22 | {"title":"Concordia","lat":-31.39296,"lon":-58.02089}, 23 | {"title":"Corrientes","lat":-27.4806,"lon":-58.8341}, 24 | {"title":"Dolores","lat":-36.31322,"lon":-57.67918}, 25 | {"title":"Dubai","lat":25.25817,"lon":55.30472}, 26 | {"title":"Ejmiatsin","lat":40.16557,"lon":44.29462}, 27 | {"title":"Elbasan","lat":41.1125,"lon":20.08222}, 28 | {"title":"Esquina","lat":-30.01444,"lon":-59.52719}, 29 | {"title":"Fayzabad","lat":37.11664,"lon":70.58002}, 30 | {"title":"Federal","lat":-30.95465,"lon":-58.78326}, 31 | {"title":"Fier","lat":40.72389,"lon":19.55611}, 32 | {"title":"Fontana","lat":-27.41813,"lon":-59.02392}, 33 | {"title":"Formosa","lat":-26.17753,"lon":-58.17814}, 34 | {"title":"Gavarr","lat":40.35398,"lon":45.12386}, 35 | {"title":"Gereshk","lat":31.82089,"lon":64.57005}, 36 | {"title":"Ghazni","lat":33.55356,"lon":68.42689}, 37 | {"title":"Ghormach","lat":35.73062,"lon":63.78264}, 38 | {"title":"Goris","lat":39.51288,"lon":46.33816}, 39 | {"title":"Goya","lat":-29.14003,"lon":-59.26256}, 40 | {"title":"Gualeguay","lat":-33.14156,"lon":-59.30966}, 41 | {"title":"Gyumri","lat":40.7942,"lon":43.84528}, 42 | {"title":"Hrazdan","lat":40.49748,"lon":44.7662}, 43 | {"title":"Huambo","lat":-12.77611,"lon":15.73917}, 44 | {"title":"Kabul","lat":34.52813,"lon":69.17233}, 45 | {"title":"Kapan","lat":39.20754,"lon":46.40576}, 46 | {"title":"Karukh","lat":34.48108,"lon":62.5863}, 47 | {"title":"Khanabad","lat":36.6825,"lon":69.11556}, 48 | {"title":"Khulm","lat":36.69736,"lon":67.69826}, 49 | {"title":"Kuito","lat":-12.38333,"lon":16.93333}, 50 | {"title":"Kunduz","lat":36.72896,"lon":68.857}, 51 | {"title":"Kushk","lat":33.29565,"lon":61.95221}, 52 | {"title":"Lobito","lat":-12.34806,"lon":13.54556}, 53 | {"title":"Longonjo","lat":-12.90667,"lon":15.25333}, 54 | {"title":"Luanda","lat":-8.83682,"lon":13.23432}, 55 | {"title":"Luau","lat":-10.70727,"lon":22.22466}, 56 | {"title":"Lubango","lat":-14.91717,"lon":13.4925}, 57 | {"title":"Lucapa","lat":-8.41915,"lon":20.74466}, 58 | {"title":"Luena","lat":-11.78333,"lon":19.91667}, 59 | {"title":"Malanje","lat":-9.54015,"lon":16.34096}, 60 | {"title":"Masis","lat":40.06762,"lon":44.43591}, 61 | {"title":"Maymana","lat":35.92139,"lon":64.78361}, 62 | {"title":"Menongue","lat":-14.6585,"lon":17.69099}, 63 | {"title":"Mercedes","lat":-29.18186,"lon":-58.07895}, 64 | {"title":"Mercedes","lat":-34.65146,"lon":-59.43068}, 65 | {"title":"Montecarlo","lat":-26.5662,"lon":-54.757}, 66 | {"title":"Namibe","lat":-15.19611,"lon":12.15222}, 67 | {"title":"Necochea","lat":-38.54726,"lon":-58.73675}, 68 | {"title":"Nzeto","lat":-7.23116,"lon":12.8666}, 69 | {"title":"Pergamino","lat":-33.88995,"lon":-60.57357}, 70 | {"title":"Plottier","lat":-38.96667,"lon":-68.23333}, 71 | {"title":"Pocito","lat":-31.68333,"lon":-68.58333}, 72 | {"title":"Pontevedra","lat":-34.74974,"lon":-58.68696}, 73 | {"title":"Posadas","lat":-27.36708,"lon":-55.89608}, 74 | {"title":"Quilmes","lat":-34.72418,"lon":-58.25265}, 75 | {"title":"Quitilipi","lat":-26.86913,"lon":-60.21683}, 76 | {"title":"Rafaela","lat":-31.25033,"lon":-61.4867}, 77 | {"title":"Rawson","lat":-43.30016,"lon":-65.10228}, 78 | {"title":"Reconquista","lat":-29.15,"lon":-59.65}, 79 | {"title":"Resistencia","lat":-27.46056,"lon":-58.98389}, 80 | {"title":"Retiro","lat":-34.58333,"lon":-58.38333}, 81 | {"title":"Rosario","lat":-32.94682,"lon":-60.63932}, 82 | {"title":"Rufino","lat":-34.26827,"lon":-62.71262}, 83 | {"title":"Saladas","lat":-28.25384,"lon":-58.62591}, 84 | {"title":"Salta","lat":-24.7859,"lon":-65.41166}, 85 | {"title":"Saurimo","lat":-9.66078,"lon":20.39155}, 86 | {"title":"Sevan","lat":40.5484,"lon":44.94868}, 87 | {"title":"Shahrak","lat":34.10738,"lon":64.3052}, 88 | {"title":"Sharjah","lat":25.35731,"lon":55.4033}, 89 | {"title":"Soio","lat":-6.1349,"lon":12.36894}, 90 | {"title":"Spitak","lat":40.8322,"lon":44.2673}, 91 | {"title":"Sumbe","lat":-11.20605,"lon":13.84371}, 92 | {"title":"Sunchales","lat":-30.94404,"lon":-61.56148}, 93 | {"title":"Taloqan","lat":36.73605,"lon":69.53451}, 94 | {"title":"Tandil","lat":-37.32167,"lon":-59.13316}, 95 | {"title":"Tartagal","lat":-22.51636,"lon":-63.80131}, 96 | {"title":"Tigre","lat":-34.42603,"lon":-58.57962}, 97 | {"title":"Tirana","lat":41.3275,"lon":19.81889}, 98 | {"title":"Trelew","lat":-43.24895,"lon":-65.30505}, 99 | {"title":"Unquillo","lat":-31.23073,"lon":-64.31615}, 100 | {"title":"Ushuaia","lat":-54.8,"lon":-68.3}, 101 | {"title":"Vanadzor","lat":40.80456,"lon":44.4939}, 102 | {"title":"Vera","lat":-29.4593,"lon":-60.21261}, 103 | {"title":"Victoria","lat":-32.61841,"lon":-60.15478}, 104 | {"title":"Viedma","lat":-40.81345,"lon":-62.99668}, 105 | {"title":"Villaguay","lat":-31.8653,"lon":-59.02689}, 106 | {"title":"Yerevan","lat":40.18111,"lon":44.51361}, 107 | {"title":"Zapala","lat":-38.89916,"lon":-70.05442}] -------------------------------------------------------------------------------- /examples/custom-list-item.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | example 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |

Bootstrap List Filter

16 | 17 |

Custom Item Example

18 | 19 |
20 |
21 | 22 |
23 |
24 | 25 |
26 |
27 |
28 | 29 | 30 | 31 | 32 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /examples/dynamic-list-search.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | example 5 | 6 | 7 | 8 | 9 | 17 | 18 | 19 | 20 | 21 |
22 | 23 |

Bootstrap List Filter

24 | 25 |

Dynamic Search Example

26 | 27 |
28 |
29 | 30 |
31 |
32 | Avellaneda 33 | Azul 34 | Berat 35 | Burrel 36 | Cabinda 37 | Caluquembe 38 | 39 |
40 |
41 |
42 | 43 | 44 | 45 | 46 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /examples/multiple-field.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | example 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |

Bootstrap List Filter

16 | 17 |

Search on Multiple Field

18 | 19 |
20 |
21 | 22 |
23 |
24 | 25 |
26 |
27 |
28 | 29 | 30 | 31 | 32 | 33 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /examples/search.php: -------------------------------------------------------------------------------- 1 | 0, 'errmsg'=>'specify q parameter') ) ); 7 | 8 | $data = json_decode( file_get_contents(DATAFILE), true); 9 | 10 | function searchInit($text) //search initial text in titles 11 | { 12 | $reg = "/^".$_GET['q']."/i"; //initial case insensitive searching 13 | return (bool)@preg_match($reg, $text['title']); 14 | } 15 | $fdata = array_filter($data, 'searchInit'); //filter data 16 | $fdata = array_values($fdata); //reset $fdata indexs 17 | 18 | $JSON = json_encode($fdata,true); 19 | 20 | sleep(1); 21 | //simulate connection latency for localhost tests 22 | @header("Content-type: application/json; charset=utf-8"); 23 | 24 | if(isset($_GET['callback']) and !empty($_GET['callback'])) //support for JSONP request 25 | echo $_GET['callback']."($JSON)"; 26 | else 27 | echo $JSON; //AJAX request 28 | 29 | ?> 30 | -------------------------------------------------------------------------------- /examples/static.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | example 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |

Bootstrap List Filter

16 | 17 |

Static Example

18 | 19 |
20 |
21 | 22 |
23 |
24 | aquamarine  25 | black  26 | blue  27 | chocolate  28 | coral  29 | cyan  30 | darkblue"  31 | Darkred  32 | Darkgray  33 | dodgerblue  34 | gray  35 | green"  36 | greenyellow  37 | red  38 | rosybrown  39 | royalblue  40 | salmon  41 | seagreen  42 | silver  43 | skyblue  44 | yellow  45 |
46 |
47 |
48 | 49 | 50 | 51 | 52 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /images/bootstrap-list-filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefanocudini/bootstrap-list-filter/b814ba08dd38e5be20c023deef2568ccc0a3782e/images/bootstrap-list-filter.png -------------------------------------------------------------------------------- /images/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefanocudini/bootstrap-list-filter/b814ba08dd38e5be20c023deef2568ccc0a3782e/images/loader.gif -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bootstrap list filter 5 | 6 | 95 | 96 | 97 | 98 | 99 |

bootstrap list filter

100 | 101 |
102 | Search elements in Bootstrap lists 103 |
104 | 105 |
106 |
107 | 108 |
109 |
110 |

Features

111 | 121 |
122 |
123 |

Settings

124 | 138 |
139 |
140 |

Code repositories

141 | Github.com 142 |
143 | Bitbucket.org 144 |
145 | Node Packaged Module 146 |
147 | Atmosphere MeteorJS 148 |
149 | 150 |

Homepage

151 | https://opengeo.tech/bootstrap-list-filter/ 152 |
153 | 154 |

Download

155 | 158 |
159 |
160 |

Examples

161 | 174 |
175 | 176 |
177 | 178 |
179 | 180 | 181 | Github 182 | 183 |
184 | For questions and bugs I recommend you to create New Issue on Github repository.
185 |
186 | This is a micro discussion area for methods of implementation.
187 |
188 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /index.tmpl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%=title%> 5 | 6 | 95 | 96 | 97 | 98 | 99 |

<%=title%>

100 | 101 |
102 | <%=pkg.description%> 103 |
104 | 105 |
106 |
107 | 108 |
109 |
110 |

Features

111 | 121 |
122 |
123 |

Settings

124 | 138 |
139 |
140 |

Code repositories

141 | Github.com 142 |
143 | Bitbucket.org 144 |
145 | Node Packaged Module 146 |
147 | Atmosphere MeteorJS 148 |
149 | 150 |

Homepage

151 | <%=pkg.homepage%> 152 |
153 | 154 |

Download

155 | 158 |
159 |
160 |

Examples

161 | 166 |
167 | 168 |
169 | 170 |
171 | 172 | 173 | Github 174 | 175 |
176 | For questions and bugs I recommend you to create New Issue on Github repository.
177 |
178 | This is a micro discussion area for methods of implementation.
179 |
180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | version: "0.3.2", 3 | name: "stefcud:bootstrap-list-filter", 4 | summary: "bootstrap-list-filter", 5 | git: "https://github.com/stefanocudini/bootstrap-list-filter.git" 6 | }); 7 | 8 | Package.on_use(function (api, where) { 9 | api.use('twbs:bootstrap@3.3.6', 'client'); 10 | api.addFiles('bootstrap-list-filter.min.js', 'client'); 11 | }); 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap-list-filter", 3 | "version": "0.3.4", 4 | "description": "Search elements in Bootstrap lists", 5 | "main": "bootstrap-list-filter.src.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git@github.com:stefanocudini/bootstrap-list-filter.git" 9 | }, 10 | "homepage": "https://opengeo.tech/bootstrap-list-filter/", 11 | "author": { 12 | "name": "Stefano Cudini", 13 | "email": "stefano.cudini@gmail.com", 14 | "url": "https://opengeo.tech/" 15 | }, 16 | "license": "MIT", 17 | "keywords": [ 18 | "bootstrap", 19 | "jquery", 20 | "javascript" 21 | ], 22 | "dependencies": { 23 | "jquery": "*", 24 | "bootstrap": "*" 25 | }, 26 | "devDependencies": { 27 | "grunt": "^0.4.5", 28 | "grunt-cli": "^0.1.13", 29 | "grunt-contrib-clean": "^0.5.0", 30 | "grunt-contrib-jshint": "^0.10.0", 31 | "grunt-contrib-uglify": "^0.5.0", 32 | "grunt-markdown": "^0.6.1" 33 | } 34 | } 35 | --------------------------------------------------------------------------------