├── .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 | [](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 | 
47 |
48 | # Usage
49 | ```html
50 |
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 |
16 |
17 |
Cancel Button Example
18 |
19 |
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 |
16 |
17 |
Custom Item Example
18 |
19 |
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 |
24 |
25 |
Dynamic Search Example
26 |
27 |
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 |
16 |
17 |
Search on Multiple Field
18 |
19 |
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 |
16 |
17 |
Static Example
18 |
19 |
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 |
112 | complete mobile responsive
113 | dynamic list generation
114 | support preloaded list
115 | custom html and node item
116 | custom data format
117 | filter by sub elements
118 | search text in case sensitive
119 | search text in initial position or full
120 |
121 |
122 |
123 |
Settings
124 |
125 | delay: millisecond before apply filter
126 | minLength: min string lentgh searched
127 | initial: search only initial text (default: true)
128 | eventKey: event digit (default: 'keyup')
129 | resetOnBlur: auto reset selection
130 | sourceData: function generate data source(receive: text, callback)
131 | sourceTmpl: html template contains {title} placeholder
132 | sourceNode: function builder DOM html fragment (default: sourceTmpl)
133 | emptyNode: function builder for empty result
134 | itemEl: item selector (default: .list-group-item)*
135 | itemChild: sub item selector (default: .list-group-item)*
136 | itemFilter: function for filter results(receive: text, item)
137 |
138 |
139 |
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 |
112 | complete mobile responsive
113 | dynamic list generation
114 | support preloaded list
115 | custom html and node item
116 | custom data format
117 | filter by sub elements
118 | search text in case sensitive
119 | search text in initial position or full
120 |
121 |
122 |
123 |
Settings
124 |
125 | delay: millisecond before apply filter
126 | minLength: min string lentgh searched
127 | initial: search only initial text (default: true)
128 | eventKey: event digit (default: 'keyup')
129 | resetOnBlur: auto reset selection
130 | sourceData: function generate data source(receive: text, callback)
131 | sourceTmpl: html template contains {title} placeholder
132 | sourceNode: function builder DOM html fragment (default: sourceTmpl)
133 | emptyNode: function builder for empty result
134 | itemEl: item selector (default: .list-group-item)*
135 | itemChild: sub item selector (default: .list-group-item)*
136 | itemFilter: function for filter results(receive: text, item)
137 |
138 |
139 |
159 |
160 |
Examples
161 |
162 | <% _.forEach(examples, function(file) { %>
163 | <%- file%>
164 | <% }); %>
165 |
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 |
--------------------------------------------------------------------------------