var g_listviews = {}; function Listview(opt) { $WH.cO(this, opt); if (this.id) { var divId = (this.tabs ? 'tab-' : 'lv-') + this.id; if (this.parent) { var d = $WH.ce('div'); d.id = divId; $WH.ae($WH.ge(this.parent), d); this.container = d; } else this.container = $WH.ge(divId); } else return; var get = $WH.g_getGets(); if ((get.debug != null || g_user.debug) && g_user.roles & U_GROUP_MODERATOR) this.debug = true; if (this.template && Listview.templates[this.template]) this.template = Listview.templates[this.template]; else return; g_listviews[this.id] = this; if (this.data == null) this.data = []; if (this.poundable == null) { if (this.template.poundable != null) this.poundable = this.template.poundable; else this.poundable = true; } if (this.searchable == null) { if (this.template.searchable != null) this.searchable = this.template.searchable; else this.searchable = false; } if (this.filtrable == null) { if (this.template.filtrable != null) this.filtrable = this.template.filtrable; else this.filtrable = false; } if (this.sortable == null) { if (this.template.sortable != null) this.sortable = this.template.sortable; else this.sortable = true; } if (this.customPound == null) { if (this.template.customPound != null) this.customPound = this.template.customPound; else this.customPound = false; } if (this.data.length == 1) { this.filtrable = false; this.searchable = false; } if (this.searchable && this.searchDelay == null) { if (this.template.searchDelay != null) this.searchDelay = this.template.searchDelay; else this.searchDelay = 333; } if (this.clickable == null) { if (this.template.clickable != null) this.clickable = this.template.clickable; else this.clickable = true; } if (this.hideBands == null) this.hideBands = this.template.hideBands; if (this.hideNav == null) this.hideNav = this.template.hideNav; if (this.hideHeader == null) this.hideHeader = this.template.hideHeader; if (this.hideCount == null) this.hideCount = this.template.hideCount; if (this.computeDataFunc == null && this.template.computeDataFunc != null) this.computeDataFunc = this.template.computeDataFunc; if (this.createCbControls == null && this.template.createCbControls != null) this.createCbControls = this.template.createCbControls; if (this.template.onBeforeCreate != null) { if (this.onBeforeCreate == null) this.onBeforeCreate = this.template.onBeforeCreate; else this.onBeforeCreate = [this.template.onBeforeCreate, this.onBeforeCreate]; } if (this.onAfterCreate == null && this.template.onAfterCreate != null) this.onAfterCreate = this.template.onAfterCreate; if (this.onNoData == null && this.template.onNoData != null) this.onNoData = this.template.onNoData; if (this.createNote == null && this.template.createNote != null) this.createNote = this.template.createNote; if (this.sortOptions == null && this.template.sortOptions != null) this.sortOptions = this.template.sortOptions; if (this.customFilter == null && this.template.customFilter != null) this.customFilter = this.template.customFilter; if (this.onSearchSubmit == null && this.template.onSearchSubmit != null) this.onSearchSubmit = this.template.onSearchSubmit; if (this.getItemLink == null && this.template.getItemLink != null) this.getItemLink = this.template.getItemLink; if (this.clip == null && this.template.clip != null) this.clip = this.template.clip; if (this.clip || this.template.compute || this.id == 'topics' || this.id == 'recipes') this.debug = false; // Don't add columns to picker windows if (this.mode == null) this.mode = this.template.mode; if (this.template.noStyle != null) this.noStyle = this.template.noStyle; if (this.nItemsPerPage == null) { if (this.template.nItemsPerPage != null) this.nItemsPerPage = this.template.nItemsPerPage; else this.nItemsPerPage = 50; } this.nItemsPerPage |= 0; if (this.nItemsPerPage <= 0) this.nItemsPerPage = 0; this.nFilters = 0; this.resetRowVisibility(); if (this.mode == Listview.MODE_TILED) { if (this.nItemsPerRow == null) { var ipr = this.template.nItemsPerRow; this.nItemsPerRow = (ipr != null ? ipr : 4); } this.nItemsPerRow |= 0; if (this.nItemsPerRow <= 1) this.nItemsPerRow = 1; } else if (this.mode == Listview.MODE_CALENDAR) { this.dates = []; this.nItemsPerRow = 7; // Days per row this.nItemsPerPage = 1; // Months per page this.nDaysPerMonth = []; if (this.template.startOnMonth != null) this.startOnMonth = this.template.startOnMonth; else this.startOnMonth = new Date(); this.startOnMonth.setDate(1); this.startOnMonth.setHours(0, 0, 0, 0); if (this.nMonthsToDisplay == null) { if (this.template.nMonthsToDisplay != null) this.nMonthsToDisplay = this.template.nMonthsToDisplay; else this.nMonthsToDisplay = 1; } var y = this.startOnMonth.getFullYear(), m = this.startOnMonth.getMonth(); for (var j = 0; j < this.nMonthsToDisplay; ++j) { var date = new Date(y, m + j, 32); this.nDaysPerMonth[j] = 32 - date.getDate(); for (var i = 1; i <= this.nDaysPerMonth[j]; ++i) this.dates.push({ date: new Date(y, m + j, i) }); } if (this.template.rowOffset != null) this.rowOffset = this.template.rowOffset; } else this.nItemsPerRow = 1; this.columns = []; for (var i = 0, len = this.template.columns.length; i < len; ++i) { var ori = this.template.columns[i], cpy = {}; $WH.cO(cpy, ori); this.columns.push(cpy); } // ************************ // Extra Columns if (this.extraCols != null) { for (var i = 0, len = this.extraCols.length; i < len; ++i) { var pos = null; var col = this.extraCols[i]; if (col.after || col.before) { var index = $WH.in_array(this.columns, (col.after ? col.after : col.before), function(x) { return x.id; } ); if (index != -1) pos = (col.after ? index + 1 : index); } if (pos == null) pos = this.columns.length; if (col.id == 'debug-id') this.columns.splice(0, 0, col); else this.columns.splice(pos, 0, col); } } // ************************ // Visibility this.visibility = []; var visibleCols = [], hiddenCols = []; if (this.visibleCols != null) $WH.array_walk(this.visibleCols, function(x) { visibleCols[x] = 1; }); if (this.hiddenCols != null) $WH.array_walk(this.hiddenCols, function(x) { hiddenCols[x] = 1; }); if ($.isArray(this.sortOptions)) { for (var i = 0, len = this.sortOptions.length; i < len; ++i) { var sortOpt = this.sortOptions[i]; if (visibleCols[sortOpt.id] != null || (!sortOpt.hidden && hiddenCols[sortOpt.id] == null)) this.visibility.push(i); } } else { for (var i = 0, len = this.columns.length; i < len; ++i) { var col = this.columns[i]; if (visibleCols[col.id] != null || (!col.hidden && hiddenCols[col.id] == null)) this.visibility.push(i); } } // ************************ // Sort if (this.sort == null && this.template.sort) { this.sort = this.template.sort.slice(0); } if (this.sort != null) { var sortParam = this.sort; this.sort = []; for (var i = 0, len = sortParam.length; i < len; ++i) { var col = parseInt(sortParam[i]); if (isNaN(col)) { var desc = 0; if (sortParam[i].charAt(0) == '-') { desc = 1; sortParam[i] = sortParam[i].substring(1); } var index = $WH.in_array(this.columns, sortParam[i], function(x) { return x.id; } ); if (index != -1) { if (desc) this.sort.push(-(index + 1)); else this.sort.push(index + 1); } } else this.sort.push(col); } } else this.sort = []; if (this.debug) { this.columns.splice(0, 0, { id: 'debug-id', compute: function(data, td) { if (data.id) { let pre = $WH.ce('pre', { style: { display: 'inline', margin: '0' }}, $WH.ct(data.id)); $WH.clickToCopy(pre); $WH.ae(td, pre); } }, getVisibleText: function(data) { return data.id || ''; }, getValue: function(data) { return data.id || 0; }, sortFunc: function(a, b, col) { if (a.id == null) return -1; else if (b.id == null) return 1; return $WH.strcmp(a.id, b.id); }, name: 'ID', width: '5%', tooltip: 'ID' }); this.visibility.splice(0, 0, -1); for (var i = 0, len = this.visibility.length; i < len; ++i) this.visibility[i] = this.visibility[i] + 1; for (var i = 0, len = this.sort.length; i < len; ++i) { if (this.sort[i] < 0) this.sort[i] = this.sort[i] - 1; else this.sort[i] = this.sort[i] + 1; } } if (this.tabs) { this.tabIndex = this.tabs.add(this.getTabName(), { id: this.id, onLoad: this.initialize.bind(this) }); this.tabClick = Tabs.trackClick.bind(this.tabs, this.tabs.tabs[this.tabIndex]); } else this.initialize(); } Listview.MODE_DEFAULT = 0; Listview.MODE_CHECKBOX = 1; Listview.MODE_DIV = 2; Listview.MODE_TILED = 3; Listview.MODE_CALENDAR = 4; Listview.MODE_FLEXGRID = 5; Listview.prototype = { initialize: function() { if (this.data.length) { if (this.computeDataFunc != null) { for (var i = 0, len = this.data.length; i < len; ++i) this.computeDataFunc(this.data[i]); } } if (this.tabs) { this.pounded = (this.tabs.poundedTab == this.tabIndex); if (this.pounded) this.readPound(); } else this.readPound(); this.applySort(); var obcResult; if (this.onBeforeCreate != null) { if (typeof this.onBeforeCreate == 'function') obcResult = this.onBeforeCreate(); else { for (var i = 0; i < this.onBeforeCreate.length; ++i) (this.onBeforeCreate[i].bind(this))(); } } this.noData = $WH.ce('div'); this.noData.className = 'listview-nodata text'; if (this.mode == Listview.MODE_DIV) { this.mainContainer = this.mainDiv = $WH.ce('div'); if (!this.noStyle) this.mainContainer.className = 'listview-mode-div'; } else if (this.mode == Listview.MODE_FLEXGRID) { this.mainContainer = this.mainDiv = $WH.ce('div', { className: 'listview-mode-flexgrid' }); this.mainContainer.setAttribute('data-cell-min-width', this.template.cellMinWidth); if (this.clickable) this.mainContainer.className += ' clickable'; var layout = $('.layout'); var totalWidth = parseInt(layout.css('max-width')) - (parseInt(layout.css('padding-left')) || 0) - (parseInt(layout.css('padding-right')) || 0); var slots = Math.floor(totalWidth / this.template.cellMinWidth); var extraStyle = '.listview-mode-flexgrid[data-cell-min-width="' + this.template.cellMinWidth + '"] > div {min-width:' + this.template.cellMinWidth + "px;width:" + (100 / slots) + "%}"; while (slots--) { if (slots) { extraStyle += "\n@media screen and (max-width: " + (((slots + 1) * this.template.cellMinWidth) - 1 + 40) + "px) {"; extraStyle += '\n .listview-mode-flexgrid[data-cell-min-width="' + this.template.cellMinWidth + '"] > div {width:' + (100 / slots) + "%}"; extraStyle += "\n}" } } $("