import './Venues.html'; let QUERY_LIMIT = 20; let PREFIX = "Venues."; Tracker.autorun(function() { Meteor.subscribe("venues"); }); Template.Venues.onCreated(function() { Session.set(PREFIX + "displayNewVenue", false); Session.set(PREFIX + "showHidden", false); }); Template.Venues.helpers({ displayNewVenue: function() { return Session.get(PREFIX + "displayNewVenue"); }, venues: function() { let skipCount = Session.get(PREFIX + 'skipCount') || 0; let query = Session.get(PREFIX + 'searchQuery'); let dbQuery = []; if(query) { _.each(_.keys(query), function(key) { if(_.isFunction(query[key])) dbQuery.push({[key]: query[key]}); //dbQuery[key] = query[key](); else if(_.isObject(query[key])) dbQuery.push({[key]: query[key]}); //dbQuery[key] = query[key]; //Will look something like: {$in: [xxx,xxx,xxx]} else if(_.isNumber(query[key])) dbQuery.push({[key]: query[key]}); //dbQuery[key] = query[key]; else { //dbQuery[key] = {$regex: query[key], $options: 'i'}; let searchValue = query[key]; let searches = searchValue && searchValue.length > 0 ? searchValue.split(/\s+/) : undefined; for(let search of searches) { dbQuery.push({[key]: {$regex: '\\b' + search, $options: 'i'}}); } } }) } if(!Session.get(PREFIX + "showHidden")) { //Ignore any hidden elements by showing those not hidden, or those without the hidden field. dbQuery.push({$or: [{hidden: false}, {hidden: {$exists:false}}]}); } dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {}; Session.set(PREFIX + 'venueCount', Meteor.collections.Venues.find(dbQuery).count()); //Always get a full count. return Meteor.collections.Venues.find(dbQuery, {limit: QUERY_LIMIT, skip: skipCount, sort: {order: 1}}); }, disablePrev: function() { return (Session.get(PREFIX + 'skipCount') || 0) == 0; }, disableNext: function() { return Session.get(PREFIX + 'venueCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0; } }); Template.Venues.events({ 'click .prevVenues': function(event, template) { if(!$(event.target).hasClass('disabled')) Session.set(PREFIX + 'skipCount', Math.max(0, (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT)); }, 'click .nextVenues': function(event, template) { if(!$(event.target).hasClass('disabled')) Session.set(PREFIX + 'skipCount', (Session.get(PREFIX + 'skipCount') || 0) + QUERY_LIMIT); }, 'click .newVenueButton': function(event, template) { if(template.$('.newVenueButton').hasClass('active')) { Session.set(PREFIX + 'displayNewVenue', false); } else { Session.set(PREFIX + 'displayNewVenue', true); Session.set(PREFIX + "editedVenue", undefined); //Clear the edited venue so that only one editor is open at a time. } template.$('.newVenueButton').toggleClass('active'); }, 'change input[name="showHidden"]': function(event, template) { Session.set(PREFIX + "showHidden", $(event.target).prop('checked')); } }); Template.VenueSearch.events({ "keyup .searchInput": _.throttle(function(event, template) { let searchQuery = Session.get(PREFIX + 'searchQuery') || {}; let searchFields = Session.get(PREFIX + 'searchFields') || {}; let searchValue = template.$('.searchInput').val(); if(searchValue) { if(this.number) searchValue = parseFloat(searchValue); if(this.collection) { let ids = Meteor.collections[this.collection].find({[this.collectionQueryColumnName]: {$regex: searchValue, $options: 'i'}}, {fields: {[this.collectionResultColumnName]: 1}}).fetch(); //Convert the ids to an array of ids instead of an array of objects containing an id. for(let i = 0; i < ids.length; i++) {ids[i] = ids[i]._id;} searchQuery[this.columnName] = {$in: ids}; searchFields[this.columnName] = searchValue; } else { searchFields[this.columnName] = searchQuery[this.columnName] = searchValue; } } else { //Remove columns from the search query whose values are empty so we don't bother the database with them. delete searchQuery[this.columnName]; delete searchFields[this.columnName]; } Session.set(PREFIX + 'searchQuery', searchQuery); Session.set(PREFIX + 'searchFields', searchFields); Session.set(PREFIX + 'skipCount', 0); //Reset the paging of the results. }, 500) }); Template.VenueSearch.helpers({ searchValue: function() { let searchFields = Session.get(PREFIX + 'searchFields'); return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : ''; } }); Template.Venue.helpers({ venues: function() { let result = ""; if(this.venues && this.venues.length > 0) { let venueNames = []; for(let i = 0; i < this.venues.length; i++) { let venueObject = Meteor.collections.Venues.findOne(this.venues[i]); if(venueObject && venueObject.name) venueNames.push(venueObject.name); } result = venueNames.join(", "); } return result; }, editing: function() { let editedVenue = Session.get(PREFIX + "editedVenue"); return editedVenue == this._id; }, getRowClass: function() { return this.hidden ? "hidden" : this.deactivated ? "deactivated" : ""; } }); Template.Venue.events({ "click .actionEdit": function(event, template) { Session.set(PREFIX + "editedVenue", this._id); Session.set(PREFIX + 'displayNewVenue', false); //Ensure the new venue editor is closed. template.$('.newVenueButton').removeClass('active'); }, "click .actionRemove": function(event, template) { Meteor.call('deactivateVenue', this._id, function(error, result) { if(error) sAlert.error(error); else sAlert.success("Venue Deactivated"); }); }, 'click .actionActivate': function(event, template) { Meteor.call('reactivateVenue', this._id, function(error, result) { if(error) sAlert.error(error); else sAlert.success("Venue Reactivated"); }); }, "click .actionShow": function(event, template) { Meteor.call('showVenue', this._id, function(error, result) { if(error) sAlert.error(error); else sAlert.success("Venue Visibility Enabled"); }); }, 'click .actionHide': function(event, template) { Meteor.call('hideVenue', this._id, function(error, result) { if(error) sAlert.error(error); else sAlert.success("Venue Visibility Disabled"); }); } }); Template.VenueEditor.helpers({ }); Template.VenueEditor.events({ "click .editorCancel": function(event, template) { Session.set(PREFIX + "editedVenue", undefined); Session.set(PREFIX + 'displayNewVenue', false); template.parentTemplate().$('.newVenueButton').removeClass('active'); }, "click .editorApply": function(event, template) { let name = template.$("input[name='name']").val().trim(); let type = template.$("input[name='type']").val().trim(); let order = 0; //TODO: if(Session.get(PREFIX + 'displayNewVenue')) { Meteor.call("createVenue", name, type, order, function(error, result) { if(error) sAlert.error(error); else { sAlert.success("Venue created."); Session.set(PREFIX + 'displayNewVenue', false); template.parentTemplate().$('.newVenueButton').removeClass('active'); } }); } else { Meteor.call("updateVenue", this._id, name, type, order, function(error, result) { if(error) sAlert.error(error); else { sAlert.success("Venue updated."); Session.set(PREFIX + "editedVenue", undefined); template.parentTemplate().$('.newVenueButton').removeClass('active'); } }); } } });