'use strict'; oml.ui.filter = function(id) { var ui = oml.user.ui, filter = Ox.getObjectById(oml.config.filters, id), filterIndex = Ox.getIndexById(ui.filters, id), filterSize = oml.getFilterSizes()[filterIndex], that = Ox.TableList({ _selected: !ui.showFilters ? ui._filterState[filterIndex].selected : false, columns: [ { format: Ox.encodeHTMLEntities, id: 'name', operator: '+', title: Ox._(filter.title), visible: true, width: filterSize - 48 - Ox.UI.SCROLLBAR_SIZE }, { align: 'right', format: function(value) { return Ox.formatNumber(value); }, id: 'items', operator: '-', title: '#', visible: true, width: 48 } ], columnsVisible: true, items: function(data, callback) { if (ui.showFilters) { delete data.keys; return oml.api.find(Ox.extend(data, { group: filter.id, query: ui._filterState[filterIndex].find }), callback); } else { callback({ data: {items: data.keys ? [] : 0} }); } }, scrollbarVisible: true, selected: ui.showFilters ? ui._filterState[filterIndex].selected : [], sort: Ox.clone(ui.filters[filterIndex].sort, true), unique: 'name' }) .bindEvent({ init: function(data) { that.setColumnTitle( 'name', Ox._(filter.title) + '
' + Ox.formatNumber(data.items) + ' 
' ); }, select: function(data) { // fixme: cant index be an empty array, instead of -1? // FIXME: this is still incorrect when deselecting a filter item // makes a selected item in another filter disappear var conditions = data.ids.map(function(value) { return { key: id, value: value, operator: '==' }; }), index = ui._filterState[filterIndex].index, find = Ox.clone(ui.find, true); if (Ox.isArray(index)) { // this filter had multiple selections and the | query // was on the top level, i.e. not bracketed find = { conditions: conditions, operator: conditions.length > 1 ? '|' : '&' } } else { if (index == -1) { // this filter had no selection, i.e. no query index = find.conditions.length; if (find.operator == '|') { find = { conditions: [find], operator: '&' }; index = 1; } else { find.operator = '&'; } } if (conditions.length == 0) { // nothing selected find.conditions.splice(index, 1); if (find.conditions.length == 1) { if (find.conditions[0].conditions) { // unwrap single remaining bracketed query find = { conditions: find.conditions[0].conditions, operator: '|' }; } else { find.operator = '&'; } } } else if (conditions.length == 1) { // one item selected find.conditions[index] = conditions[0]; } else { // multiple items selected if (ui.find.conditions.length == 1) { find = { conditions: conditions, operator: '|' }; } else { find.conditions[index] = { conditions: conditions, operator: '|' }; } } } oml.stayInItemView = true; oml.UI.set({find: find}); oml.stayInItemView = false; oml.updateFilterMenus(); }, sort: function(data) { var filters = Ox.clone(ui.filters, true); filters[filterIndex].sort = [{key: data.key, operator: data.operator}]; oml.UI.set({filters: filters}); } }), $menu = Ox.MenuButton({ items: [ {id: 'clearFilter', title: Ox._('Clear Filter'), keyboard: 'shift control a'}, {id: 'clearFilters', title: Ox._('Clear All Filters'), keyboard: 'shift alt control a'}, {}, {group: 'filter', max: 1, min: 1, items: oml.config.filters.map(function(filter) { return Ox.extend({checked: filter.id == id}, filter); })} ], type: 'image', }) .css(Ox.UI.SCROLLBAR_SIZE == 16 ? { right: 0, width: '14px' } : { right: '-1px', width: '8px', }) .bindEvent({ change: function(data) { var id_ = data.checked[0].id, filter_ = Ox.getObjectById(oml.config.filters, id_), filterIndex_ = Ox.getIndexById(ui.filters, id_), filters = Ox.clone(ui.filters), filterState, find; if (filterIndex_ == -1) { // New filter was not part of old filter set if (ui._filterState[filterIndex].selectedLength) { // Filter with selection gets replaced, update find find = Ox.clone(ui.find, true); find.conditions.splice( ui._filterState[filterIndex].index, 1 ); } filters[filterIndex] = { id: id_, sort: filter_.sort }; oml.UI.set(Ox.extend({ filters: filters }, find ? { find: find } : {})); replaceFilter(filterIndex, id_); } else { // Swap two exisiting filters filterState = Ox.clone(ui._filterState[filterIndex]); ui._filterState[filterIndex] = ui._filterState[filterIndex_]; ui._filterState[filterIndex_] = filterState; filters[filterIndex] = { id: id_, sort: ui.filters[filterIndex_].sort }; filters[filterIndex_] = { id: id, sort: ui.filters[filterIndex].sort }; oml.UI.set({filters: filters}); replaceFilter(filterIndex, id_); replaceFilter(filterIndex_, id); } function replaceFilter(index, id) { var isOuter = index % 4 == 0; oml.$ui[ isOuter ? 'filtersOuterPanel' : 'filtersInnerPanel' ].replaceElement( isOuter ? index / 2 : index - 1, oml.$ui.filters[index] = oml.ui.filter(id) ); } }, click: function(data) { if (data.id == 'clearFilter') { that.options({selected: []}).triggerEvent('select', {ids: []}); } else if (data.id == 'clearFilters') { oml.clearFilters(); } } }) .appendTo(that.$bar.$element); if (Ox.UI.SCROLLBAR_SIZE < 16) { $($menu.find('input')[0]).css({ marginRight: '-3px', marginTop: '1px', width: '8px', height: '8px' }); } that.disableMenuItem = function(id) { $menu.disableItem(id); }; that.enableMenuItem = function(id) { $menu.enableItem(id); }; return that; };