Untitled diff

Created Diff never expires
/**
/**
* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* JA Megafilter Component
* JA Megafilter Component
* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* Copyright (C) 2004-2016 J.O.O.M Solutions Co., Ltd. All Rights Reserved.
* Copyright (C) 2004-2016 J.O.O.M Solutions Co., Ltd. All Rights Reserved.
* @license - GNU/GPL, http://www.gnu.org/licenses/gpl.html
* @license - GNU/GPL, http://www.gnu.org/licenses/gpl.html
* Author: J.O.O.M Solutions Co., Ltd
* Author: J.O.O.M Solutions Co., Ltd
* Websites: http://www.joomlart.com - http://www.joomlancers.com
* Websites: http://www.joomlart.com - http://www.joomlancers.com
* This file may not be redistributed in whole or significant part.
* This file may not be redistributed in whole or significant part.
* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
*/
*/
var LNBase = Class.extend(function(){
var LNBase = Class.extend(function(){
// private variable
// private variable
var self = this,
var self = this,
$ = jQuery;
$ = jQuery;


self.type = 'LNBase';
self.type = 'LNBase';


self.options = null;
self.options = null;
self.defaultOptions = {
self.defaultOptions = {
rerenderWhenUpdate: false
rerenderWhenUpdate: false
};
};


self.state = {
self.state = {
};
};


self.items = {};
self.items = {};
self.$item = null;
self.$item = null;


self.data = {};
self.data = {};


self.ids = [];
self.ids = [];
self.matchedIds = [];
self.matchedIds = [];
self.shownIds = [];
self.shownIds = [];
self.showingIds = [];
self.showingIds = [];


self.startIdx = 1;
self.startIdx = 1;
self.endIdx = 0;
self.endIdx = 0;
self.page = 1;
self.page = 1;
self.itemPerPage = 12;
self.itemPerPage = 12;


self.rendered = false;
self.rendered = false;


self.sortField = 'position';
self.sortField = 'position';
self.sortDir = 'desc';
self.sortDir = 'desc';


self.qs = {};
self.qs = {};


self.timeout = [];
self.timeout = [];


self.constructor = function (options) {
self.constructor = function (options) {
self.options = $.extend({}, self.defaultOptions, options);
self.options = $.extend({}, self.defaultOptions, options);
}
}




self.render = function (callback) {
self.render = function (callback) {
self.beforeRender();
self.beforeRender();


var e = $.Event('beforeRender');
var e = $.Event('beforeRender');
e.lntype = self.type;
e.lntype = self.type;
e.lntarget = self;
e.lntarget = self;
$(document).trigger(e);
$(document).trigger(e);


dust.render(self.options.template, self, function(err, out) {
dust.render(self.options.template, self, function(err, out) {
var $el = $(out);
var $el = $(out);
if ($el.length != 1) $el = $('<div>').html(out);
if ($el.length != 1) $el = $('<div>').html(out);
$el.addClass('ln-element').addClass(self.options.class).data('lnid', self.getId());
$el.addClass('ln-element').addClass(self.options.class).data('lnid', self.getId());


if (self.$item) {
if (self.$item) {
self.$item.remove();
self.$item.remove();
self.$item = null;
self.$item = null;
}
}


if (callback) {
if (callback) {
self.$item = callback($el);
self.$item = callback($el);
} else {
} else {
self.$item = $el.appendTo($(self.options.container).empty());
self.$item = $el.appendTo($(self.options.container).empty());
}
}
if (self.options.itemWrapper) {
if (self.options.itemWrapper) {
self.$wrapper = self.$item.is(self.options.itemWrapper) ? self.$item : self.$item.find(self.options.itemWrapper);
self.$wrapper = self.$item.is(self.options.itemWrapper) ? self.$item : self.$item.find(self.options.itemWrapper);
}
}


// find state fields
// find state fields
self.$stateFields = self.$item.find('[data-lnstate]');
self.$stateFields = self.$item.find('[data-lnstate]');


self.renderItems();
self.renderItems();


// Render state value
// Render state value
self.renderStateFields ();
self.renderStateFields ();


self.afterRender();
self.afterRender();
self.rendered = true;
self.rendered = true;


var e = $.Event('afterRender');
var e = $.Event('afterRender');
e.lntype = self.type;
e.lntype = self.type;
e.lntarget = self;
e.lntarget = self;
self.$item.trigger(e);
self.$item.trigger(e);
});
});
var e = $.Event('completeRender');
var e = $.Event('completeRender');
e.lntype = self.type;
e.lntype = self.type;
e.lntarget = self;
e.lntarget = self;
self.$item.trigger(e);
self.$item.trigger(e);
}
}


self.renderStateFields = function () {
self.renderStateFields = function () {
if (self.$stateFields.length) {
if (self.$stateFields.length) {
self.$stateFields.each(function () {
self.$stateFields.each(function () {
var $field = $(this),
var $field = $(this),
field = $field.data('lnstate'),
field = $field.data('lnstate'),
value = self.getField (field);
value = self.getField (field);
$field.html(value);
$field.html(value);
})
})
}
}
}
}


self.beforeRender = function () {
self.beforeRender = function () {
if (self.options.beforeRender) self.options.beforeRender.apply(self);
if (self.options.beforeRender) self.options.beforeRender.apply(self);
}
}


self.afterRender = function () {
self.afterRender = function () {
if (self.options.afterRender) self.options.afterRender.apply(self);
if (self.options.afterRender) self.options.afterRender.apply(self);
}
}


self.beforeUpdateRender = function () {
self.beforeUpdateRender = function () {
if (self.options.beforeUpdateRender) self.options.beforeUpdateRender.apply(self);
if (self.options.beforeUpdateRender) self.options.beforeUpdateRender.apply(self);
}
}


self.afterUpdateRender = function () {
self.afterUpdateRender = function () {
if (self.options.afterUpdateRender) self.options.afterUpdateRender.apply(self);
if (self.options.afterUpdateRender) self.options.afterUpdateRender.apply(self);
}
}


self.beforeRenderItems = function () {
self.beforeRenderItems = function () {
if (self.options.beforeRenderItems) self.options.beforeRenderItems.apply(self);
if (self.options.beforeRenderItems) self.options.beforeRenderItems.apply(self);
if (!Object.keys(self.items).length) return;
if (!Object.keys(self.items).length) return;
if (self.options.showAllItems) {
if (self.options.showAllItems) {
self.matchedIds = Object.keys(self.items);
self.matchedIds = Object.keys(self.items);
self.endIdx = self.matchedIds.length;
self.endIdx = self.matchedIds.length;
self.startIdx = 1;
self.startIdx = 1;
} else {
} else {
self.endIdx = self.startIdx + self.itemPerPage - 1;
self.endIdx = self.startIdx + self.itemPerPage - 1;
if (self.endIdx > self.matchedIds.length) self.endIdx = self.matchedIds.length;
if (self.endIdx > self.matchedIds.length) self.endIdx = self.matchedIds.length;
}
}
if (!self.matchedIds || !self.matchedIds.length) return false;
if (!self.matchedIds || !self.matchedIds.length) return false;
self.showingIds = self.matchedIds.slice(self.startIdx - 1, self.endIdx);
self.showingIds = self.matchedIds.slice(self.startIdx - 1, self.endIdx);
return true;
return true;
}
}


self.afterRenderItems = function () {
self.afterRenderItems = function () {
if (self.options.afterRenderItems) self.options.afterRenderItems.apply(self);
if (self.options.afterRenderItems) self.options.afterRenderItems.apply(self);
}
}


self.renderItems = function () {
self.renderItems = function () {
// render children item
// render children item
if (self.beforeRenderItems()) {
if (self.beforeRenderItems()) {
var oldIds = [];
var oldIds = [];
for(var i=0; i<self.shownIds.length; i++) {
for(var i=0; i<self.shownIds.length; i++) {
// remove old item on page
// remove old item on page
var id = self.shownIds[i];
var id = self.shownIds[i];
if ($.inArray(id, self.showingIds) == -1) {
if ($.inArray(id, self.showingIds) == -1) {
// remove html item
// remove html item
self.getItem(id).$item.remove();
self.getItem(id).$item.remove();
} else {
} else {
oldIds.push(id);
oldIds.push(id);
}
}
}
}
// Render for new item
// Render for new item
self.$currentItem = null;
self.$currentItem = null;
for(var i=0; i<self.showingIds.length; i++) {
for(var i=0; i<self.showingIds.length; i++) {
var id = self.showingIds[i];
var id = self.showingIds[i];
if ($.inArray(id, oldIds) == -1) {
if ($.inArray(id, oldIds) == -1) {
// render new one
// render new one
self.renderItem(id);
self.renderItem(id);
} else {
} else {
var item = self.getItem (id);
var item = self.getItem (id);
item.updateRender();
item.updateRender();
if (self.$currentItem) item.$item.insertAfter(self.$currentItem);
if (self.$currentItem) item.$item.insertAfter(self.$currentItem);
self.$currentItem = item.$item;
self.$currentItem = item.$item;
}
}
}
}
// update shownIds
// update shownIds
self.shownIds = self.showingIds.slice();
self.shownIds = self.showingIds.slice();
} else {
} else {
if (self.$wrapper) self.$wrapper.empty();
if (self.$wrapper) self.$wrapper.empty();
self.shownIds = []
self.shownIds = []
}
}


self.afterRenderItems();
self.afterRenderItems();
}
}


self.renderItem = function (id) {
self.renderItem = function (id) {
var item = self.getItem(id);
var item = self.getItem(id);


item.render(function($item){
item.render(function($item){
$item.addClass(self.options.itemClass);
$item.addClass(self.options.itemClass);
if (self.$currentItem) $item.insertAfter(self.$currentItem);
if (self.$currentItem) $item.insertAfter(self.$currentItem);
else $item.appendTo(self.$wrapper);
else $item.appendTo(self.$wrapper);
self.$currentItem = $item;
self.$currentItem = $item;
return $item;
return $item;
});
});
}
}


self.updateRender = function () {
self.updateRender = function () {
self.delayCall('_updateRender', 100);
self.delayCall('_updateRender', 100);
}
}


self._updateRender = function () {
self._updateRender = function () {
var e = $.Event('beforeUpdateRender');
var e = $.Event('beforeUpdateRender');
e.lntype = self.type;
e.lntype = self.type;
e.lntarget = self;
e.lntarget = self;
self.$item.trigger(e);
self.$item.trigger(e);


if (self.options.rerenderWhenUpdate) {
if (self.options.rerenderWhenUpdate) {
self.render();
self.render();
} else {
} else {
self.beforeUpdateRender();
self.beforeUpdateRender();
self.renderItems();
self.renderItems();
self.renderStateFields ();
self.renderStateFields ();
self.afterUpdateRender();
self.afterUpdateRender();
}
}


if (self.type === 'LNBase' && self.options.autopage) {
if (self.type === 'LNBase' && self.options.autopage) {
self.autoPage();
self.autoPage();
}
}


var e = $.Event('afterUpdateRender');
var e = $.Event('afterUpdateRender');
e.lntype = self.type;
e.lntype = self.type;
e.lntarget = self;
e.lntarget = self;
self.$item.trigger(e);
self.$item.trigger(e);
}
}


self.addItem = function (child, id) {
self.addItem = function (child, id) {
if (!id) id = child.data[id];
if (!id) id = child.data[id];
child.lnid = id.slugify();
child.lnid = id.slugify();
child.parent = self;
child.parent = self;
self.items[child.lnid] = child;
self.items[child.lnid] = child;
}
}


self.getData = function () {
self.getData = function () {
return self.data;
return self.data;
}
}


self.setData = function (data) {
self.setData = function (data) {
self.data = data;
self.data = data;
}
}


self.getField = function (field) {
self.getField = function (field) {
if (self[field] !== undefined) return self[field];
if (self[field] !== undefined) return self[field];
if (self.data[field] !== undefined) return self.data[field];
if (self.data[field] !== undefined) return self.data[field];
// check if path field, eg: stats.HP
// check if path field, eg: stats.HP
var fields = field.split('.'),
var fields = field.split('.'),
v = self.data,
v = self.data,
i=0;
i=0;
while(v && i<fields.length) {
while(v && i<fields.length) {
v = v[fields[i++]];
v = v[fields[i++]];
}
}
return v === undefined ? '' : v;
return v === undefined ? '' : v;
}
}


self.getTemplate = function () {
self.getTemplate = function () {
return self.options.template;
return self.options.template;
}
}


self.getItem = function (id) {
self.getItem = function (id) {
return self.items[id.slugify()];
return self.items[id.slugify()];
}
}


self.getId = function () {
self.getId = function () {
return self.lnid;
return self.lnid;
}
}


self.is = function (check) {
self.is = function (check) {
if (typeof check == 'string') {
if (typeof check == 'string') {
return check === self.type;
return check === self.type;
}
}


if (check instanceof LNBase) {
if (check instanceof LNBase) {
return (check.is(self.type) && check.getId() == self.getId());
return (check.is(self.type) && check.getId() == self.getId());
}
}


return false;
return false;
}
}


// pages
// pages
self.setPage = function (p) {
self.setPage = function (p) {
if (!p) return;
if (!p) return;
self.setQS('page', p);
self.setQS('page', p);
self.page = p;
self.page = p;
self.startIdx = (p-1) * self.itemPerPage + 1;
self.startIdx = (p-1) * self.itemPerPage + 1;
// if (self.startIdx >= self.matchedIds.length) {
// if (self.startIdx >= self.matchedIds.length) {
// // reset to first page
// // reset to first page
// self.startIdx = 1;
// self.startIdx = 1;
// self.page = 1;
// self.page = 1;
// }
// }
return self;
return self;
}
}


// sticky
// sticky
self.sticky = function () {
self.sticky = function () {
if(!isMobile.any ) {
if(!isMobile.any ) {
$(self.options.container).parent().stick_in_parent().trigger('sticky_kit:recalc');
$(self.options.container).parent().stick_in_parent().trigger('sticky_kit:recalc');
}
}
}
}


// auto page
// auto page
self.autoPage = function () {
self.autoPage = function () {
var itemWrapper = $(self.options.itemWrapper),
var itemWrapper = $(self.options.itemWrapper),
div = $('<div>', {id:'autopage','page-data': 1, 'style':'clear:both'}),
div = $('<div>', {id:'autopage','page-data': 1, 'style':'clear:both'}),
reachEnd = 0;
reachEnd = 0;


if ($('#autopage').length) {
if ($('#autopage').length) {
$('#autopage').remove();
$('#autopage').remove();
itemWrapper.append(div);
itemWrapper.append(div);
}
}
else {
else {
itemWrapper.append(div);
itemWrapper.append(div);
}
}


self.startIdx = 1;
self.startIdx = 1;
self.endIdx = self.matchedIds.length;
self.endIdx = self.matchedIds.length;


$(window).on('scroll.page',function () {
$(window).on('scroll.page',function () {
var wheight = $(window).outerHeight(),
var wheight = $(window).outerHeight(),
target = $('#autopage').offset().top,
target = $('#autopage').offset().top,
numpage = parseInt($('#autopage').attr('page-data')),
numpage = parseInt($('#autopage').attr('page-data')),
start = numpage * self.itemPerPage + 1,
start = numpage * self.itemPerPage + 1,
end = start + self.itemPerPage - 1;
end = start + self.itemPerPage - 1;


if (end > self.endIdx )
if (end > self.endIdx )
end = self.endIdx;
end = self.endIdx;


if( ($(window).scrollTop() + wheight + 400) >= target ) {
if( ($(window).scrollTop() + wheight + 400) >= target ) {
self.showingIds = self.matchedIds.slice(start - 1, end)
self.showingIds = self.matchedIds.slice(start - 1, end)


for(var i=0; i<self.showingIds.length; i++) {
for(var i=0; i<self.showingIds.length; i++) {
var id = self.showingIds[i];
var id = self.showingIds[i];
self.renderItem(id);
self.renderItem(id);
self.shownIds.push(id);
self.shownIds.push(id);
}
}
if (end === self.endIdx) {
if (end === self.endIdx) {
$(window).off('scroll.page')
$(window).off('scroll.page')
} else {
} else {
numpage = numpage + 1;
numpage = numpage + 1;
$('#autopage').attr('page-data', numpage );
$('#autopage').attr('page-data', numpage );
}
}


// for afterAutoPage() callback
// for afterAutoPage() callback
var e = $.Event('afterAutoPage');
var e = $.Event('afterAutoPage');
e.lntype = self.type;
e.lntype = self.type;
e.lntarget = self;
e.lntarget = self;
self.$item.trigger(e);
self.$item.trigger(e);
}
}
});
});
}
}


// pages
// pages
self.setLimiter = function (limiter) {
self.setLimiter = function (limiter) {
self.setQS('limiter', limiter);
self.setQS('limiter', limiter);
self.itemPerPage = parseInt(limiter);
self.itemPerPage = parseInt(limiter);
self.startIdx = (self.page-1) * self.itemPerPage + 1;
self.startIdx = (self.page-1) * self.itemPerPage + 1;
if (self.startIdx >= self.matchedIds.length) {
if (self.startIdx >= self.matchedIds.length) {
// reset to first page
// reset to first page
self.startIdx = 1;
self.startIdx = 1;
self.page = 1;
self.page = 1;
}
}
return self;
return self;
}
}


// sort
// sort
self.sort = function (field, dir) {
self.sort = function (field, dir) {
if (field !== undefined) {
if (field !== undefined) {
self.setQS('sort', field);
self.setQS('sort', field);
self.sortField = field;
self.sortField = field;
}
}
if (dir == 'asc' || dir == 'desc') {
if (dir == 'asc' || dir == 'desc') {
self.setQS('sortdir', dir);
self.setQS('sortdir', dir);
self.sortDir = dir;
self.sortDir = dir;
}
}
var d = self.sortDir == 'desc' ? -1 : 1;
var d = self.sortDir == 'desc' ? -1 : 1;


if (!self.ids.length || (self.sortField == 'position' && d == -1))
if (!self.ids.length || (self.sortField == 'position' && d == -1))
self.ids = Object.keys(self.items);
self.ids = Object.keys(self.items);
// do sort
// do sort
if (self.sortField != 'position') {
if (self.sortField != 'position') {
self.ids.sort(function (a, b) {
self.ids.sort(function (a, b) {
var v1 = self.getItem(a).getField(self.sortField),
var v1 = self.getItem(a).getField(self.sortField),
v2 = self.getItem(b).getField(self.sortField);
v2 = self.getItem(b).getField(self.sortField);


// transfer array to string
// transfer array to string
if (Array.isArray(v1)) {
if (Array.isArray(v1)) {
v1.sort();
v1.sort();
v1 = v1.join(' ');
v1 = v1.join(' ');
}
}
if (Array.isArray(v2)) {
if (Array.isArray(v2)) {
v2.sort();
v2.sort();
v2 = v2.join(' ');
v2 = v2.join(' ');
}
}
if (v1 == v2) {
if (v1 == v2) {
var t1 = +self.getItem(a).getField('id'),
var t1 = +self.getItem(a).getField('id'),
t2 = +self.getItem(b).getField('id');
t2 = +self.getItem(b).getField('id');
return t1 > t2 ? d : -d;
return t1 > t2 ? d : -d;
}
}
if ( !isNaN(v1) && !isNaN(v2) ) {
if ( !isNaN(v1) && !isNaN(v2) ) {
v1 = +v1;
v1 = +v1;
v2 = +v2;
v2 = +v2;
return v1 > v2 ? d : -d;
} else if( v1 && v2 ) {
} else if( v1 && v2 ) {
v1 = v1.split('');
v1 = v1.split('');
v2 = v2.split('');
v2 = v2.split('');
var min = Math.min(v1.length, v2.length);
var min = Math.min(v1.length, v2.length);
for (var i = 0; i < min; i++) {
for (var i = 0; i < min; i++) {
if (v1[i] != v2[i]) {
if (v1[i] != v2[i]) {
return v1[i].localeCompare(v2[i]) > 0 ? d : -d;
return v1[i].localeCompare(v2[i]) > 0 ? d : -d;
}
}
}
}

return v1 > v2 ? d : -d;
}
}
// let empty value always goes to bottom
// let empty value always goes to bottom
if (!v1) {
if (!v1) {
return d > 0 ? d : -d;
return d > 0 ? d : -d;
}
}
if (!v2) {
if (!v2) {
return d < 0 ? d : -d;
return d < 0 ? d : -d;
}
}

return v1 > v2 ? d : -d;
});
});
} else if (d == 1) {
} else if (d == 1) {
self.ids.reverse();
self.ids.reverse();
}
}
return self;
return self;
}
}


self.setMatchedItems = function (ids) {
self.setMatchedItems = function (ids) {
self.matchedIds = [];
self.matchedIds = [];
if (!self.ids.length) self.ids = Object.keys(self.items);
if (!self.ids.length) self.ids = Object.keys(self.items);
self.ids.forEach(function(id) {
self.ids.forEach(function(id) {
if (ids.indexOf(id) != -1) self.matchedIds.push(id);
if (ids.indexOf(id) != -1) self.matchedIds.push(id);
})
})
return self;
return self;
}
}


self.setQS = function (name, value) {
self.setQS = function (name, value) {
self.getQS().set(name, value);
self.getQS().set(name, value);
}
}


self.getQS = function () {
self.getQS = function () {
if ($.lnqs == undefined) {
if ($.lnqs == undefined) {
$.lnqs = new LNQueryString();
$.lnqs = new LNQueryString();
$.lnqs.load();
$.lnqs.load();
}
}
return $.lnqs;
return $.lnqs;
}
}


self.delayCall = function (func, timeOut) {
self.delayCall = function (func, timeOut) {
if (self.timeout[func]) clearTimeout(self.timeout[func]);
if (self.timeout[func]) clearTimeout(self.timeout[func]);
if (self[func]) {
if (self[func]) {
self.timeout[func] = setTimeout(function () {self[func]()}, timeOut);
self.timeout[func] = setTimeout(function () {self[func]()}, timeOut);
}
}
}
}
});
});
;
;
var LNFilter = LNBase.extend(function(){
var LNFilter = LNBase.extend(function(){
// private variable
// private variable
var self = this,
var self = this,
$ = jQuery,
$ = jQuery,
so = setOps;
so = setOps;


self.type = 'LNFilter';
self.type = 'LNFilter';


self.defaultOptions = {
self.defaultOptions = {
template: 'filter-list',
template: 'filter-list',
container: '.sidebar',
container: '.sidebar',
itemWrapper: '.filter-list',
itemWrapper: '.filter-list',
showAllItems: true
showAllItems: true
};
};


self.lnItems = null;
self.lnItems = null;
self.filterResult = null;
self.filterResult = null;


// is first load
// is first load


self.isFirstLoad = true;
self.isFirstLoad = true;


// store selected value
// store selected value
self.selectedFilters = {};
self.selectedFilters = {};


// page
// page
self.page = 1;
self.page = 1;


// Filter base on list data items
// Filter base on list data items
self.addItems = function (lnItems) {
self.addItems = function (lnItems) {
self.lnItems = lnItems;
self.lnItems = lnItems;
}
}


// Filter result
// Filter result
self.addFilterResult = function (filterResult) {
self.addFilterResult = function (filterResult) {
self.filterResult = filterResult;
self.filterResult = filterResult;
self.filterResult.setSelectedFilters (self.selectedFilters);
self.filterResult.setSelectedFilters (self.selectedFilters);
}
}




self.addFilterSingle = function (options) {
self.addFilterSingle = function (options) {
// template
// template
self.addItem (new LNFilterGroup($.extend(options, {
self.addItem (new LNFilterGroup($.extend(options, {
template: 'filter.radio',
template: 'filter.radio',
type: 'single'
type: 'single'
})), 'filter-' + options.field);
})), 'filter-' + options.field);
}
}


self.addFilterDropdown = function (options) {
self.addFilterDropdown = function (options) {
// template
// template
self.addItem (new LNFilterGroup($.extend(options, {
self.addItem (new LNFilterGroup($.extend(options, {
template: 'filter.dropdown',
template: 'filter.dropdown',
type: 'dropdown'
type: 'dropdown'
})), 'filter-' + options.field);
})), 'filter-' + options.field);
}
}


self.addFilterList = function (options) {
self.addFilterList = function (options) {
// template
// template
self.addItem (new LNFilterGroup($.extend(options, {
self.addItem (new LNFilterGroup($.extend(options, {
template: 'filter.list',
template: 'filter.list',
type: 'list'
type: 'list'
})), 'filter-' + options.field);
})), 'filter-' + options.field);
}
}




self.addFilterMultiple = function (options) {
self.addFilterMultiple = function (options) {
// template
// template
self.addItem (new LNFilterGroup($.extend(options, {
self.addItem (new LNFilterGroup($.extend(options, {
template: 'filter.multiple',
template: 'filter.multiple',
type: 'multiple'
type: 'multiple'
})), 'filter-' + options.field);
})), 'filter-' + options.field);
}
}


self.addFilterValue = function (options) {
self.addFilterValue = function (options) {
// template
// template
self.addItem (new LNFilterValue(options), 'filter-' + options.field);
self.addItem (new LNFilterValue(options), 'filter-' + options.field);
}
}


self.addFilterDate = function (options) {
self.addFilterDate = function (options) {
// template
// template
self.addItem (new LNFilterDate(options), 'filter-' + options.field);
self.addItem (new LNFilterDate(options), 'filter-' + options.field);
}
}


self.addFilterColor = function (options) {
self.addFilterColor = function (options) {
// template
// template
self.addItem (new LNFilterGroup($.extend(options, {
self.addItem (new LNFilterGroup($.extend(options, {
template: 'filter.color',
template: 'filter.color',
type: 'color'
type: 'color'
})), 'filter-' + options.field);
})), 'filter-' + options.field);
}
}


self.addFilterMedia = function (options) {
self.addFilterMedia = function (options) {
// template
// template
self.addItem (new LNFilterGroup($.extend(options, {
self.addItem (new LNFilterGroup($.extend(options, {
template: 'filter.media',
template: 'filter.media',
type: 'media'
type: 'media'
})), 'filter-' + options.field);
})), 'filter-' + options.field);
}
}


self.addFilterRange = function (options) {
self.addFilterRange = function (options) {
// find max value
// find max value
if (!options.max) {
if (!options.max) {
var field = options.field,
var field = options.field,
vals = [];
vals = [];
for (var id in self.lnItems.items) {
for (var id in self.lnItems.items) {
var v = self.lnItems.getItem(id).getField(field);
var v = self.lnItems.getItem(id).getField(field);
if (Array.isArray(v)) {
if (Array.isArray(v)) {
for (var i = 0; i < v.length; i++) {
for (var i = 0; i < v.length; i++) {
vals.push(+self.cleanRangeValue(v[i]));
vals.push(+self.cleanRangeValue(v[i]));
}
}
} else {
} else {
vals.push (+self.cleanRangeValue(v));
vals.push (+self.cleanRangeValue(v));
}
}
}
}
options.min = Math.min.apply(Math, vals);
options.min = Math.min.apply(Math, vals);
options.max = Math.max.apply(Math, vals);
options.max = Math.max.apply(Math, vals);
// change max min value to float to int.
// change max min value to float to int.
if (!!(options.max % 1)) options.max = Math.ceil(options.max);
if (!!(options.max % 1)) options.max = Math.ceil(options.max);
if (!!(options.min % 1)) options.min = Math.floor(options.min);
if (!!(options.min % 1)) options.min = Math.floor(options.min);
}
}


// template
// template
self.addItem (new LNFilterRange(options), 'filter-' + options.field);
self.addItem (new LNFilterRange(options), 'filter-' + options.field);
}
}


self.cleanRangeValue = function (value) {
self.cleanRangeValue = function (value) {
if(isNaN(value)) {
if(isNaN(value)) {
var arr = [], pieces = value.split('');
var arr = [], pieces = value.split('');
for (var i = 0; i < pieces.length; i++) {
for (var i = 0; i < pieces.length; i++) {
pieces[i] = pieces[i].replace(',', '.');
pieces[i] = pieces[i].replace(',', '.');
if (pieces[i] == ' ') {
if (pieces[i] == ' ') {
continue;
continue;
}
}


if (pieces[i] === '.' || !isNaN(pieces[i])) {
if (pieces[i] === '.' || !isNaN(pieces[i])) {
arr.push(pieces[i]);
arr.push(pieces[i]);
}
}
}
}
value = arr.join('');
value = arr.join('');
return isNaN(value) ? 0 : value;
return isNaN(value) ? 0 : value;
}
}


return value;
return value;
}
}


// update value for filter type Single & Multiple
// update value for filter type Single & Multiple
self.updateFilter = function () {
self.updateFilter = function () {
for (var gid in self.items) {
for (var gid in self.items) {
var fgroup = self.getItem(gid),
var fgroup = self.getItem(gid),
field = fgroup.options.field,
field = fgroup.options.field,
type = fgroup.options.type,
type = fgroup.options.type,
frontend_value;
frontend_value;
if (fgroup.options.frontend_field)
if (fgroup.options.frontend_field)
frontend_value=fgroup.options.frontend_field;
frontend_value=fgroup.options.frontend_field;
else
else
frontend_value=fgroup.options.field;
frontend_value=fgroup.options.field;
// show all child
// show all child
fgroup.options.showAllItems = true;
fgroup.options.showAllItems = true;
fgroup.options.itemWrapper = '.filter-items';
fgroup.options.itemWrapper = '.filter-items';
// fetch child value from filter data
// fetch child value from filter data
if (fgroup.is('LNFilterGroup')) {
if (fgroup.is('LNFilterGroup')) {
// fetch field values into array
// fetch field values into array
for (var id in self.lnItems.items) {
for (var id in self.lnItems.items) {
var item = self.lnItems.getItem(id),
var item = self.lnItems.getItem(id),
val = item.getField(field),
val = item.getField(field),
frontend_val = item.getField(frontend_value);
frontend_val = item.getField(frontend_value);


if (val === undefined) continue;
if (val === undefined) continue;
if ($.isArray(val)) {
if ($.isArray(val)) {
for (var i=0; i<val.length; i++) {
for (var i=0; i<val.length; i++) {
var v = val[i],
var v = val[i],
key = field + '-' + v,
key = field + '-' + v,
fitem = fgroup.getItem(key);
fitem = fgroup.getItem(key);


if (!v || v == 'N/A') continue;
if (!v || v == 'N/A') continue;
if (!fitem) {
if (!fitem) {
fitem = new LNFilterItem({
fitem = new LNFilterItem({
template: fgroup.getTemplate() + '-item',
template: fgroup.getTemplate() + '-item',
name: field,
name: field,
frontend_value: frontend_val[i],
frontend_value: frontend_val[i],
value: v
value: v
});
});
fitem.mids = [];
fitem.mids = [];
fgroup.addItem(fitem, key);
fgroup.addItem(fitem, key);
}
}
fitem.mids.push(id);
fitem.mids.push(id);
}
}
} else {
} else {
var v = val,
var v = val,
key = field + '-' + v,
key = field + '-' + v,
fitem = fgroup.getItem(key);
fitem = fgroup.getItem(key);
if (!v || v == 'N/A') continue;
if (!v || v == 'N/A') continue;
if (!fitem) {
if (!fitem) {
fitem = new LNFilterItem({
fitem = new LNFilterItem({
template: fgroup.getTemplate() + '-item',
template: fgroup.getTemplate() + '-item',
name: field,
name: field,
value: v
value: v
});
});
fitem.mids = [];
fitem.mids = [];
fgroup.addItem(fitem, key);
fgroup.addItem(fitem, key);
}
}
fitem.mids.push(id);
fitem.mids.push(id);
}
}
}
}




// sort child items
// sort child items
var keys = Object.keys(fgroup.items);
var keys = Object.keys(fgroup.items);


// unset this fgroup if less than 1 values
// unset this fgroup if less than 1 values
if (keys.length < 1) {
if (keys.length < 1) {
delete self.items[gid];
delete self.items[gid];
} else {
} else {
var order = (fgroup.options.order.toUpperCase() == 'DESC') ? -1 : 1;
var order = (fgroup.options.order.toUpperCase() == 'DESC') ? -1 : 1;
keys.sort(function (a, b) {
keys.sort(function (a, b) {
return fgroup.getItem(a).options.frontend_value.localeCompare(fgroup.getItem(b).options.frontend_value) * order;
return fgroup.getItem(a).options.frontend_value.localeCompare(fgroup.getItem(b).options.frontend_value) * order;
});
});
var _items = {};
var _items = {};
keys.forEach(function (id) {
keys.forEach(function (id) {
_items[id] = fgroup.getItem(id);
_items[id] = fgroup.getItem(id);
});
});
fgroup.items = _items;
fgroup.items = _items;
}
}
}
}
}
}
return self;
return self;
}
}


self.afterRender = function () {
self.afterRender = function () {
// tracking change on filter
// tracking change on filter
self.$item.on('change', function (e) {
self.$item.on('change', function (e) {
if (self.options.sticky) {
if (self.options.sticky) {
self.sticky();
self.sticky();
}
}
// update filter selected
// update filter selected
var $value = $(e.target),
var $value = $(e.target),
$fgroup = $value.closest('.filter-field'),
$fgroup = $value.closest('.filter-field'),
fgroup = self.getItem($fgroup.data('lnid')),
fgroup = self.getItem($fgroup.data('lnid')),
field = fgroup.options.field,
field = fgroup.options.field,
type = fgroup.options.type;
type = fgroup.options.type;
if ($value.is('select')) {
if ($value.is('select')) {
// find element item
// find element item
var val = $value.val(),
var val = $value.val(),
key = field + '-' + val,
key = field + '-' + val,
fitem = fgroup.getItem(key);
fitem = fgroup.getItem(key);
// update to selected list
// update to selected list
if (val) {
if (val) {
self.selectedFilters[field] = fitem;
self.selectedFilters[field] = fitem;
} else {
} else {
delete self.selectedFilters[field];
delete self.selectedFilters[field];
}
}
} else {
} else {
if (fgroup.is('LNFilterValue')) {
if (fgroup.is('LNFilterValue')) {
fgroup.value = $value.val();
fgroup.value = $value.val();
if (fgroup.value) {
if (fgroup.value) {
self.selectedFilters[field] = fgroup;
self.selectedFilters[field] = fgroup;
} else {
} else {
delete self.selectedFilters[field];
delete self.selectedFilters[field];
}
}
}
}
if (fgroup.is('LNFilterGroup') && (type == 'multiple' || type == 'color' || type == 'media')) {
if (fgroup.is('LNFilterGroup') && (type == 'multiple' || type == 'color' || type == 'media')) {
var $fitem = $value.closest('.ln-element'),
var $fitem = $value.closest('.ln-element'),
fitem = fgroup.getItem($fitem.data('lnid')),
fitem = fgroup.getItem($fitem.data('lnid')),
key = $fitem.data('lnid');//field + '-' + fitem.options.value;
key = $fitem.data('lnid');//field + '-' + fitem.options.value;
// toggle
// toggle
if ($value.prop('checked')) {
if ($value.prop('checked')) {
self.selectedFilters[key] = fitem;
self.selectedFilters[key] = fitem;
} else {
} else {
delete self.selectedFilters[key];
delete self.selectedFilters[key];
}
}
}
}
if (fgroup.is('LNFilterGroup') && type == 'single') {
if (fgroup.is('LNFilterGroup') && type == 'single') {
var $fitem = $value.closest('.ln-element'),
var $fitem = $value.closest('.ln-element'),
fitem = fgroup.getItem($fitem.data('lnid'));
fitem = fgroup.getItem($fitem.data('lnid'));
if (fitem) {
if (fitem) {
self.selectedFilters[field] = fitem;
self.selectedFilters[field] = fitem;
} else {
} else {
delete self.selectedFilters[field];
delete self.selectedFilters[field];
}
}
}
}
if (fgroup.is('LNFilterRange')) {
if (fgroup.is('LNFilterRange')) {
fgroup.value = $value.val();
fgroup.value = $value.val();
fgroup.value[0] = parseInt(fgroup.value[0]); // to Int
fgroup.value[0] = parseInt(fgroup.value[0]); // to Int
fgroup.value[1] = parseInt(fgroup.value[1]); // to Int
fgroup.value[1] = parseInt(fgroup.value[1]); // to Int
if (fgroup.value) {
if (fgroup.value) {
self.selectedFilters[field] = fgroup;
self.selectedFilters[field] = fgroup;
} else {
} else {
delete self.selectedFilters[field];
delete self.selectedFilters[field];
}
}
}
}


if (fgroup.is('LNFilterDate')) {
if (fgroup.is('LNFilterDate')) {
fgroup.value = $value.val();
fgroup.value = $value.val();
if (fgroup.value) {
if (fgroup.value) {
self.selectedFilters[field] = fgroup;
self.selectedFilters[field] = fgroup;
} else {
} else {
delete self.selectedFilters[field];
delete self.selectedFilters[field];
}
}
}
}
}
}


// using timeout to prevent multiple change in sort time
// using timeout to prevent multiple change in sort time
clearTimeout(self.filterChangeTimeout);
clearTimeout(self.filterChangeTimeout);
self.filterChangeTimeout = setTimeout(function() {self.filterChangeHandle();}, 100);
self.filterChangeTimeout = setTimeout(function() {self.filterChangeHandle();}, 100);
});
});


self.super.afterRender();
self.super.afterRender();


}
}


self.filterChangeHandle = function () {
self.filterChangeHandle = function () {
// fetch matched item
// fetch matched item
var matchedIds = [];
var matchedIds = [];
jQuery('span.color-item-bg').removeClass('color-active');
jQuery('span.color-item-bg').removeClass('color-active');
jQuery('img.img-item').removeClass('media-active');
jQuery('img.img-item').removeClass('media-active');
if (Object.keys(self.selectedFilters).length) {
if (Object.keys(self.selectedFilters).length) {
var fields = {},
var fields = {},
ids = [],
ids = [],
vfields = [];
vfields = [];
for(var prop in self.selectedFilters) {
for(var prop in self.selectedFilters) {
var fitem = self.selectedFilters[prop],
var fitem = self.selectedFilters[prop],
field;
field;


if (!fitem.is('LNFilterItem')) {
if (!fitem.is('LNFilterItem')) {
field = fitem.options.field;
field = fitem.options.field;
// process for value & range filter
// process for value & range filter
// vfields.push(prop);
// vfields.push(prop);
var _ids = [];
var _ids = [];
for (var id in self.lnItems.items) {
for (var id in self.lnItems.items) {
var item = self.lnItems.getItem(id),
var item = self.lnItems.getItem(id),
matched = true;
matched = true;
if (!fitem.options.match || !fitem.options.match(item, field, fitem.value))
if (!fitem.options.match || !fitem.options.match(item, field, fitem.value))
matched = false;
matched = false;
if (matched) _ids.push(id);
if (matched) _ids.push(id);
}
}
fields[field] = _ids;
fields[field] = _ids;
} else {
} else {
field = fitem.parent.options.field;
field = fitem.parent.options.field;
if (fitem.options.template === 'filter.color-item') {
if (fitem.options.template === 'filter.color-item') {
fitem.$item.find('.color-item-bg').addClass('color-active');
fitem.$item.find('.color-item-bg').addClass('color-active');
} else if (fitem.options.template === 'filter.media-item') {
} else if (fitem.options.template === 'filter.media-item') {
fitem.$item.find('img').addClass('media-active');
fitem.$item.find('img').addClass('media-active');
}
}
fields[field] = fields[field] ? setOps.union(fields[field], fitem.mids) : fitem.mids;
fields[field] = fields[field] ? setOps.union(fields[field], fitem.mids) : fitem.mids;
}
}
ids = setOps.union(ids, fields[field]);
ids = setOps.union(ids, fields[field]);
}
}


var t = 0;
var t = 0;
// find matched items
// find matched items
for(var field in fields) {
for(var field in fields) {
matchedIds = t ? setOps.intersection(matchedIds, fields[field]) : fields[field];
matchedIds = t ? setOps.intersection(matchedIds, fields[field]) : fields[field];
t++;
t++;
}
}


// update counter for this field
// update counter for this field
for (var gid in self.items) {
for (var gid in self.items) {
var fgroup = self.getItem(gid),
var fgroup = self.getItem(gid),
field = fgroup.options.field,
field = fgroup.options.field,
fmatchedIds = [];
fmatchedIds = [];


// reset before count
// reset before count
for (var fid in fgroup.items) {
for (var fid in fgroup.items) {
fgroup.getItem(fid).mcount = 0;
fgroup.getItem(fid).mcount = 0;
}
}


if (field in fields) {
if (field in fields) {
if (Object.keys(fields).length == 1) {
if (Object.keys(fields).length == 1) {
// use global count
// use global count
// update counter for each item
// update counter for each item
for (var fid in fgroup.items) {
for (var fid in fgroup.items) {
fgroup.getItem(fid).mcount = fgroup.getItem(fid).mids.length;
fgroup.getItem(fid).mcount = fgroup.getItem(fid).mids.length;
}
}
} else {
} else {
// find matched items except this condition
// find matched items except this condition
var t = 0
var t = 0
for(var f in fields) {
for(var f in fields) {
if (f == field) continue;
if (f == field) continue;
fmatchedIds = t ? setOps.intersection(fmatchedIds, fields[f]):fields[f];
fmatchedIds = t ? setOps.intersection(fmatchedIds, fields[f]):fields[f];
t++
t++
}
}
}
}
} else {
} else {
fmatchedIds = matchedIds;
fmatchedIds = matchedIds;
}
}


if (fmatchedIds.length) {
if (fmatchedIds.length) {
// reset before count
// reset before count
fmatchedIds.forEach(function(id) {
fmatchedIds.forEach(function(id) {
var item = self.lnItems.getItem(id),
var item = self.lnItems.getItem(id),
val = item.getField(field);
val = item.getField(field);


if ($.isArray(val)) {
if ($.isArray(val)) {
val.forEach(function(v){
val.forEach(function(v){
var fitem = fgroup.getItem(field + '-' + v);
var fitem = fgroup.getItem(field + '-' + v);
if (fitem) fitem.mcount += 1;
if (fitem) fitem.mcount += 1;
});
});
} else {
} else {
var v = val,
var v = val,
key = field + '-' + v,
key = field + '-' + v,
fitem = fgroup.getItem(key);
fitem = fgroup.getItem(key);
if (fitem) fitem.mcount += 1;
if (fitem) fitem.mcount += 1;
}
}
})
})
}
}
}
}
} else {
} else {
matchedIds = Object.keys(self.lnItems.items);
matchedIds = Object.keys(self.lnItems.items);
// reset counter
// reset counter
for (gid in self.items) {
for (gid in self.items) {
var fgroup = self.getItem(gid);
var fgroup = self.getItem(gid);
for (var fid in fgroup.items) {
for (var fid in fgroup.items) {
fgroup.getItem(fid).mcount = fgroup.getItem(fid).mids.length;
fgroup.getItem(fid).mcount = fgroup.getItem(fid).mids.length;
}
}
}
}
}
}
self.lnItems.setMatchedItems(matchedIds);
self.lnItems.setMatchedItems(matchedIds);


if (self.isFirstLoad) {
if (self.isFirstLoad) {
self.isFirstLoad = false;
self.isFirstLoad = false;
} else {
} else {
self.page = 1;
self.page = 1;
}
}
self.lnItems.setPage(self.page);
self.lnItems.setPage(self.page);
self.lnItems.updateRender();
self.lnItems.updateRender();


self.updateRender();
self.updateRender();
self.updateFilterResult();
self.updateFilterResult();
}
}


self.updateFilterResult = function () {
self.updateFilterResult = function () {
if (self.filterResult) {
if (self.filterResult) {
self.filterResult.updateRender();
self.filterResult.updateRender();
}
}
}
}


self.load = function () {
self.load = function () {
var qs = self.getQS().qs,
var qs = self.getQS().qs,
filtered = false;
filtered = false;


for (var gid in self.items) {
for (var gid in self.items) {
var fgroup = self.getItem(gid),
var fgroup = self.getItem(gid),
field = fgroup.options.field;
field = fgroup.options.field;
if (qs[field]) {
if (qs[field]) {
fgroup.setValue(qs[field]);
fgroup.setValue(qs[field]);
filtered = true;
filtered = true;
}
}
}
}


return self;
return self;
}
}
});;
});;
var LNFilterGroup = LNBase.extend(function() {
var LNFilterGroup = LNBase.extend(function() {
// private variable
// private variable
var self = this,
var self = this,
$ = jQuery;
$ = jQuery;


self.type = 'LNFilterGroup';
self.type = 'LNFilterGroup';


self.options = null;
self.options = null;
self.defaultOptions = {
self.defaultOptions = {
class: 'filter-field',
class: 'filter-field',
order: 'ASC'
order: 'ASC'
};
};
self.afterRender = function () {
self.afterRender = function () {
// easy way to change the category tree name.
// easy way to change the category tree name.
// only use field name that we can detect it's category tree.
// only use field name that we can detect it's category tree.
if (self.options.field == 'attr.cat.value' || self.options.field == 'attr.category.value' || self.options.field == 'attr.tag.value') {
if (self.options.field == 'attr.cat.value' || self.options.field == 'attr.category.value' || self.options.field == 'attr.tag.value') {
var $lv;
var $lv;
switch (self.options.type) {
switch (self.options.type) {
case 'multiple':
case 'multiple':
self.$item.find('input').each(function() {
self.$item.find('input').each(function() {
$lv = ($(this).next().text().match(/ » /g) || []).length+1;
$lv = ($(this).next().text().match(/ » /g) || []).length+1;
$(this).parents('li').addClass('lv-'+$lv);
$(this).parents('li').addClass('lv-'+$lv);
$(this).next().text($(this).next().text().replace(/^(.*)?» /, ''));
$(this).next().text($(this).next().text().replace(/^(.*)?» /, ''));
});
});
break;
break;
case 'single':
case 'single':
self.$item.find('input').each(function() {
self.$item.find('input').each(function() {
$lv = ($(this).next().text().match(/ » /g) || []).length+1;
$lv = ($(this).next().text().match(/ » /g) || []).length+1;
$(this).parents('li').addClass('lv-'+$lv);
$(this).parents('li').addClass('lv-'+$lv);
$(this).next().text($(this).next().text().replace(/^(.*)?» /, ''));
$(this).next().text($(this).next().text().replace(/^(.*)?» /, ''));
});
});
break;
break;


case 'dropdown':
case 'dropdown':
self.$item.find('option').each(function() {
self.$item.find('option').each(function() {
$lv = ($(this).text().match(/ » /g) || []).length+1;
$lv = ($(this).text().match(/ » /g) || []).length+1;
var $space = '';
var $space = '';
for (i=1;i<$lv;i++) {
for (i=1;i<$lv;i++) {
$space += String.fromCharCode(160)+''+String.fromCharCode(160)+''+String.fromCharCode(160);
$space += String.fromCharCode(160)+''+String.fromCharCode(160)+''+String.fromCharCode(160);
}
}
$(this).text($space+''+$(this).text().replace(/^(.*)?» /, ''));
$(this).text($space+''+$(this).text().replace(/^(.*)?» /, ''));
});
});
break;
break;
case 'color':
case 'color':
case 'list':
case 'list':
case 'media':
case 'media':
break;
break;
}
}
}
}
if (self.options.type == 'color') {
if (self.options.type == 'color') {
self.$item.find('span.color-item-bg').each(function() {
self.$item.find('span.color-item-bg').each(function() {
if ((JAnameColor[$(this).data('bgcolor').toLowerCase().trim()]) != undefined) {
if ((JAnameColor[$(this).data('bgcolor').toLowerCase().trim()]) != undefined) {
$(this).css('background-color', JAnameColor[$(this).data('bgcolor').toLowerCase().trim()]);
$(this).css('background-color', JAnameColor[$(this).data('bgcolor').toLowerCase().trim()]);
} else {
} else {
$(this).css('background-color', ($(this).data('bgcolor').toLowerCase().trim().indexOf('#') === -1 ? '#' : '')+jQuery(this).data('bgcolor').toLowerCase().trim());
$(this).css('background-color', ($(this).data('bgcolor').toLowerCase().trim().indexOf('#') === -1 ? '#' : '')+jQuery(this).data('bgcolor').toLowerCase().trim());
}
}
});
});
}
}
}
}


self.reset = function () {
self.reset = function () {
/*
/*
switch (self.opti
switch (self.options.type) {
case 'multiple':