mirror of
https://github.com/bodyrep/DemoApp.git
synced 2026-01-26 07:01:38 +00:00
little man
This commit is contained in:
404
public/javascripts/filter.js
Normal file
404
public/javascripts/filter.js
Normal file
@@ -0,0 +1,404 @@
|
||||
/*
|
||||
* Filter.js
|
||||
* version: 1.3.2 (4/11/2012)
|
||||
*
|
||||
* Licensed under the MIT:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* Copyright 2011 Jiren Patel[ joshsoftware.com ]
|
||||
*
|
||||
* Dependency:
|
||||
* jQuery(v1.6 >=)
|
||||
*/
|
||||
|
||||
(function(window) {
|
||||
|
||||
var _filterJS = function(dataModel, parentNode, view, settings) {
|
||||
this.dataModel = dataModel;
|
||||
this.view = view;
|
||||
this.parentNode = parentNode;
|
||||
this.settings = settings || {};
|
||||
//this.last_result = null;
|
||||
|
||||
if (this.dataModel.constructor == Object){
|
||||
this.dataModel = [this.dataModel];
|
||||
}
|
||||
|
||||
for (name in this.dataModel[0]) {
|
||||
this.settings.root = name;
|
||||
}
|
||||
|
||||
this.render();
|
||||
this.buildCategoryMap();
|
||||
this.bindEvents();
|
||||
|
||||
if(this.settings.exec_callbacks_on_init && this.settings.callbacks){
|
||||
this.execCallBacks(this.settings.all_objects);
|
||||
}
|
||||
|
||||
if(!this.settings.filter_types){
|
||||
this.settings.filter_types = {};
|
||||
}
|
||||
|
||||
if(!this.settings.filter_types['range']){
|
||||
this.settings.filter_types['range'] = this.rangeFilter;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var FilterJS = function(dataModel, parentNode, view, settings) {
|
||||
return new _filterJS(dataModel, parentNode, view, settings);
|
||||
};
|
||||
|
||||
FilterJS.VERSION = '1.3.2';
|
||||
|
||||
//Register new html tag
|
||||
FilterJS.registerHtmlElement = function(tag_name){
|
||||
_filterJS.prototype[tag_name] = function(attrs, content){
|
||||
return _filterJS.prototype.content_tag(tag_name, attrs, content);
|
||||
};
|
||||
};
|
||||
|
||||
_filterJS.prototype = {
|
||||
/**
|
||||
* Tag to make html elements.
|
||||
* i.e this.content_tag('span', {class: 'logo_text'}, "Logo Text")
|
||||
* First argument is tag name
|
||||
* Second argument is attributes class,title,id etc.
|
||||
* Last argument is array of html elements or text.
|
||||
**/
|
||||
content_tag: function(tag, attrs, content) {
|
||||
var el = document.createElement(tag);
|
||||
|
||||
if (attrs) $(el).attr(attrs);
|
||||
if (content) {
|
||||
if (content.constructor == Array) {
|
||||
content.forEach(function(c) {
|
||||
if (c) $(el).append(c.constructor == String ? c : $(c));
|
||||
});
|
||||
}
|
||||
else {
|
||||
$(el).html(content);
|
||||
}
|
||||
}
|
||||
return el;
|
||||
},
|
||||
|
||||
/**
|
||||
* Link Tag:
|
||||
* i.e. this.link('/test/1' ,{'title': 'title'}, 'link text')
|
||||
**/
|
||||
link: function(url, attrs, content) {
|
||||
attrs = attrs || {};
|
||||
attrs['href'] = url;
|
||||
return this.content_tag('a', attrs, content)
|
||||
},
|
||||
|
||||
/**
|
||||
* Image Tag:
|
||||
* i.e. this.image('/test.png', {class: 'image'})
|
||||
**/
|
||||
image: function(url, attrs) {
|
||||
attrs = attrs || {};
|
||||
attrs['src'] = url;
|
||||
return this.content_tag('img', attrs)
|
||||
},
|
||||
|
||||
//Render Html using JSON data
|
||||
render: function(parentNode) {
|
||||
var base = this;
|
||||
var node = $(this.parentNode);
|
||||
|
||||
if (!this.parentNode || !this.view) return;
|
||||
|
||||
this.dataModel.forEach(function(dm) {
|
||||
dm = dm[base.settings.root];
|
||||
var el = $(base.view(dm));
|
||||
el.attr({'id': base.settings.root + '_' + dm.id, 'data-fjs': true});
|
||||
node.append(el);
|
||||
});
|
||||
},
|
||||
|
||||
//Bind Events to filter html elements
|
||||
bindEvents: function() {
|
||||
var base = this;
|
||||
base.settings.selector.forEach(function(selector, index) {
|
||||
$(selector.element).live(selector.events, function(e) {
|
||||
base.filter();
|
||||
});
|
||||
})
|
||||
|
||||
if(base.settings.search){
|
||||
$(base.settings.search.input).live('keyup', function(e){
|
||||
//var search_result = base.search(this, base.last_result || base.settings.all_objects);
|
||||
//base.hideShow(search_result);
|
||||
base.filter();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
//Unbind fileter events
|
||||
unbindEvents: function() {
|
||||
var base = this;
|
||||
base.settings.selector.forEach(function(selector, index) {
|
||||
$(selector.element).die(selector.events);
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
//Find elements accroding to selection criteria.
|
||||
filter: function() {
|
||||
var base = this;
|
||||
var filter_out = base.settings.all_objects.slice();
|
||||
var selected_count = 0;
|
||||
var select_none = false; //Zero Selection for any category
|
||||
|
||||
base.settings.selector.forEach(function(s) {
|
||||
var out = $(s.element).filter(s.select).map(function() {
|
||||
return $(this).val();
|
||||
});
|
||||
selected_count += out.length;
|
||||
|
||||
if (out.length) {
|
||||
filter_out = base.grep(filter_out, base.findObjects(s.name, out, s.type));
|
||||
}
|
||||
else{
|
||||
select_none = true;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if(select_none && base.settings.and_filter_on) filter_out = [];
|
||||
|
||||
//Search
|
||||
if(base.settings.search){
|
||||
filter_out = base.search(base.settings.search, filter_out);
|
||||
}
|
||||
base.hideShow(filter_out);
|
||||
|
||||
//Callbacks
|
||||
base.execCallBacks(filter_out);
|
||||
|
||||
//base.last_result = filter_out;
|
||||
},
|
||||
|
||||
//Compare and collect objects
|
||||
findObjects: function(filter_name, categories, filter_type) {
|
||||
var base = this;
|
||||
var out = [];
|
||||
var category_map = base.settings.object_map[filter_name];
|
||||
var filter_type_function = base.settings.filter_types[filter_type];
|
||||
|
||||
$.each(categories, function(index, category_value) {
|
||||
var cat;
|
||||
|
||||
if(filter_type){
|
||||
cat = $.map(category_map, function(n,v){
|
||||
if(filter_type_function(category_value, v)){
|
||||
return category_map[v];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cat = category_map[category_value];
|
||||
}
|
||||
|
||||
if(cat) {
|
||||
out = out.concat(cat);
|
||||
}
|
||||
});
|
||||
|
||||
return out;
|
||||
},
|
||||
|
||||
rangeFilter: function(category_value, v){
|
||||
var range = category_value.split('-');
|
||||
if(range.length == 2){
|
||||
if (range[0] == 'below') range[0] = -Infinity;
|
||||
if (range[1] == 'above') range[1] = Infinity;
|
||||
if (Number(v) >= range[0] && Number(v) <= range[1]){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
//Find objects in array
|
||||
grep: function(filter_out, value) {
|
||||
return jQuery.grep(filter_out,
|
||||
function(p, i) {
|
||||
return (jQuery.inArray(p, value) != -1);
|
||||
});
|
||||
},
|
||||
|
||||
//Make eval expresssion to collect object from the json data.
|
||||
makeEvalString: function(field_map, root) {
|
||||
var fields = field_map.split('.ARRAY.');
|
||||
var eval_out_str = root + '.' + fields[0];
|
||||
|
||||
for (i = 1; i < fields.length; i++) {
|
||||
eval_out_str += ".filter_collect('" + fields[i] + "')";
|
||||
}
|
||||
|
||||
return eval_out_str;
|
||||
},
|
||||
|
||||
//Create map accroding to selection criteria.
|
||||
buildObjectMap: function() {
|
||||
var base = this;
|
||||
var filter_criteria = this.settings.filter_criteria;
|
||||
var object_map = {};
|
||||
base.settings.selector = [];
|
||||
|
||||
for (name in filter_criteria) {
|
||||
var selector = {};
|
||||
|
||||
selector.element = filter_criteria[name][0].split(/.EVENT.|.SELECT.|.TYPE./)[0];
|
||||
selector.events = (filter_criteria[name][0].match(/.EVENT.(\S*)/) || [])[1];
|
||||
selector.select = (filter_criteria[name][0].match(/.SELECT.(\S*)/) || [])[1]
|
||||
selector.type = (filter_criteria[name][0].match(/.TYPE.(\S*)/) || [])[1];
|
||||
selector.name = name;
|
||||
|
||||
base.settings.selector.push(selector);
|
||||
|
||||
filter_criteria[name].push(base.makeEvalString(filter_criteria[name][1], base.settings.root));
|
||||
object_map[name] = {};
|
||||
}
|
||||
|
||||
return object_map;
|
||||
},
|
||||
|
||||
buildCategoryMap: function() {
|
||||
var filter_criteria = this.settings.filter_criteria;
|
||||
var object_map = this.buildObjectMap();
|
||||
var settings = this.settings;
|
||||
settings.all_objects = [];
|
||||
|
||||
this.dataModel.forEach(function(dm) {
|
||||
settings.all_objects.push(dm[settings.root].id);
|
||||
for (name in filter_criteria) {
|
||||
var eval_out = eval('dm.' + filter_criteria[name][2]);
|
||||
var obj = object_map[name];
|
||||
|
||||
if (eval_out && eval_out.constructor == Array) {
|
||||
eval_out.forEach(function(x) {
|
||||
if (obj[x]) {
|
||||
obj[x].push(dm[settings.root].id);
|
||||
} else {
|
||||
obj[x] = [dm[settings.root].id];
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (obj[eval_out]) {
|
||||
obj[eval_out].push(dm[settings.root].id);
|
||||
} else {
|
||||
obj[eval_out] = [dm[settings.root].id];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
settings.object_map = object_map;
|
||||
|
||||
return object_map;
|
||||
},
|
||||
|
||||
hideShow: function(id_arr) {
|
||||
var id_str = "#" + this.settings.root + '_';
|
||||
$(this.parentNode + " > *[data-fjs]").hide();
|
||||
|
||||
id_arr.forEach(function(id) {
|
||||
$(id_str + id).show();
|
||||
});
|
||||
},
|
||||
|
||||
search: function(search_config, filter_result){
|
||||
var val = $.trim($(search_config.input).val());
|
||||
|
||||
if(!val.length) return filter_result;
|
||||
|
||||
var base = this;
|
||||
var id_str = "#" + base.settings.root + '_';
|
||||
|
||||
return $.map(filter_result, function(id){
|
||||
var $item = $(id_str + id);
|
||||
if(search_config.field_selector){
|
||||
$item = $item.find(search_config.field_selector)
|
||||
}
|
||||
|
||||
if($item.text().toUpperCase().indexOf(val.toUpperCase()) >= 0){
|
||||
return id;
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
execCallBacks: function(result){
|
||||
var base = this;
|
||||
if(!base.settings.callbacks) return;
|
||||
|
||||
filtered_objects = [];
|
||||
$.each(base.dataModel, function(i, v){
|
||||
if(v && result.indexOf(v[base.settings.root].id) != -1){
|
||||
filtered_objects.push(v[base.settings.root]);
|
||||
}
|
||||
});
|
||||
|
||||
$.each(base.settings.callbacks, function(name, callback){
|
||||
callback.call(base, filtered_objects);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
window.FilterJS = FilterJS;
|
||||
|
||||
//Register html tags
|
||||
FilterJS.registerHtmlElement('div');
|
||||
FilterJS.registerHtmlElement('span');
|
||||
FilterJS.registerHtmlElement('li');
|
||||
FilterJS.registerHtmlElement('ul');
|
||||
FilterJS.registerHtmlElement('p');
|
||||
|
||||
})(this);
|
||||
|
||||
/**
|
||||
* Recursive method to collect object from json object.
|
||||
* i.e. test = [ {"deal": {"id": 1 }}, {"deal": {"id": 2}}]
|
||||
* - to collect id from the json data
|
||||
* test.filter_collect('deal').filter_collect('id')
|
||||
* this will return [1,2]
|
||||
*/
|
||||
Array.prototype.filter_collect = function(field, out_arr) {
|
||||
var out_arr = out_arr || [];
|
||||
this.forEach(function(obj) {
|
||||
if (obj.constructor == Array) {
|
||||
obj.filter_collect(field, out_arr);
|
||||
}
|
||||
else {
|
||||
out_arr.push(obj[field]);
|
||||
}
|
||||
});
|
||||
return out_arr;
|
||||
};
|
||||
|
||||
//In IE forEach mathod not define so added manually if not define.
|
||||
if(!Array.prototype.forEach) {
|
||||
Array.prototype.forEach = function(action, that) {
|
||||
for (var i = 0, n = this.length; i < n; i++)
|
||||
if (i in this) action.call(that, this[i], i, this);
|
||||
};
|
||||
}
|
||||
|
||||
//In IE indexOf method not define.
|
||||
if (!Array.prototype.indexOf) {
|
||||
Array.prototype.indexOf = function(obj, start) {
|
||||
for (var i = (start || 0), j = this.length; i < j; i++) {
|
||||
if (this[i] === obj) { return i; }
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user