Skip to content

Instantly share code, notes, and snippets.

@kurtisdunn
Created June 4, 2015 03:05
Show Gist options
  • Save kurtisdunn/32d35577beb940e9c229 to your computer and use it in GitHub Desktop.
Save kurtisdunn/32d35577beb940e9c229 to your computer and use it in GitHub Desktop.
BackboneJS Backgrid Advanced
define([
'app'
,'libs'
,'text!templates/review/review.tpl'
,'collections/tcidCollection'
], function(App, libs, review, TCIDCollection, undefined) {
//-- private -----------------------------------------------------------------------------------
var $ = libs.$, _ = libs._, JSON = libs.JSON, Backbone = libs.Backbone, bootstrapValidator = libs.bootstrapValidator, Backgrid = window.Backgrid, tcidCollection, templateData, ReviewView, target, grid;
// Start building the table columns
// applies to view.grid();
var myColumns = App.columns = new Backgrid.Columns([
{
name: "Term Code",
id: "Term Code",
cell: "string",
editable: false,
renderable: true
//sortable: false
},
{
name: "CRN",
cell: "string",
id: name,
editable: false, renderable: true
},
{
name: "Subject Code",
cell: "string",
editable: false, renderable: true,
sortType : "toggle"
},
{
name: "Title",
cell: "string",
editable: false, renderable: true
},
{
name: "Campus",
cell: "string",
editable: false, renderable: true
},
{
name: "Mode",
cell: "string",
editable: false, renderable: true
},
{
name: "Faculty",
cell: "string",
editable: false, renderable: true
},
{
name: "Teaching AOU",
cell: "string",
editable: false, renderable: true
},
{
name: "Teaching School Name",
cell: "string",
editable: false, renderable: true
},
{
name: "Convening AOU",
cell: "string",
editable: false, renderable: true
},
{
name: "Credit Points",
title: "Credit Points",
cell: "string",
editable: false, renderable: true
},
{
name: "Teaching Pattern",
cell: Backgrid.Cell.extend({
template: _.template("<span class='teaching-pattern'><%= obj['Teaching Pattern'] %></span>"),
render: function () {
templateData = this.model.attributes;
this.$el.html(this.template(templateData));
return this;
}
}),
editable: false, renderable: true
},
{
name: "Intake Pattern",
cell: Backgrid.Cell.extend({
template: _.template("<span class='intake-pattern'><%= obj['Intake Pattern'] %></span>"),
render: function () {
templateData = this.model.attributes;
this.$el.html(this.template(templateData));
return this;
}
}),
editable: false, renderable: true
},
{
name: "Comments",
cell: Backgrid.Cell.extend({
template: _.template ("<span class='comments'><%= obj['Comments'] %></span>"),
render: function () {
templateData = this.model.attributes;
this.$el.html(this.template(templateData));
return this;
}
}),
editable: false,
renderable: true
},
{
name: "Duration",
cell: Backgrid.Cell.extend({
template: _.template ("<div class='text-center'><strong><span class='label duration-label'><%= obj['Duration'] %></span><strong></div>"),
durationColors: function (){
if (templateData.Duration === 1){
$(this.$el).find(".duration-label").addClass("label-default")
}
else if (templateData.Duration === 2){
$(this.$el).find(".duration-label").addClass("label-danger")
}
else if (templateData.Duration === 4){
$(this.$el).find(".duration-label").addClass("label-success")
}
else if (templateData.Duration === 6){
$(this.$el).find(".duration-label").addClass("label-info")
}
else if (templateData.Duration === 8){
$(this.$el).find(".duration-label").addClass("label-warning")
}
},
render: function () {
templateData = this.model.attributes;
this.$el.html(this.template(templateData));
this.durationColors();
return this;
}
}),
editable: false, renderable: true
},
{
name: "View Cohorts",
sortable: false,
editable: false, renderable: true,
cell: Backgrid.Cell.extend({
template: _.template("<div class='text-center'><button type='button' class='btn btn-cohort btn-default btn-xs viewCohorts'> <span class='glyphicon glyphicon-tasks'></span></button></div>"),
render: function () {
this.$el.html(this.template());
return this;
}
})
},
{
name: "Actions",
label: "Actions",
sortable: false,
editable: false, renderable: true,
cell: Backgrid.Cell.extend({
template: _.template("<div class='text-center'><div class='btn-group'><button class='btn-default btn btn-xs dropdown-toggle actions' type='button' data-toggle='dropdown'>Actions &nbsp;&nbsp;<span class='caret'></span></button><ul class='dropdown-menu' role='menu'><li><a class='cloneOffering btn' disabled>Clone </a></li><li><a class='deleteOffering btn' disabled>Delete</a></li><li class='divider'></li><li><a class='auditTrail'>Audit Trail</a></li><li class='link'></li></ul></div></div>"),
appendLinks: function(){
var href = "handbook/subjects/" + this.model.attributes['Subject Code'] + ".html";
var newLink = $("<a />", {
id : this.model.id,
name : "link",
href : href,
text : "View in Handbook",
target: "_blank"
});
$(this.$el).find(".link").append(newLink);
$(this.$el).find('.cloneOffering').attr('id', this.model.id);
$(this.$el).find('.deleteOffering').attr('id', this.model.id);
},
render: function (options) {
this.$el.html(this.template());
this.appendLinks();
return this;
}
})
},
/* {
name: "Active",
sortable: false,
editable: false, renderable: true,
cell: Backgrid.Cell.extend({
template: _.template("<div class='text-center'><input type='checkbox' class='active center' value='active' checked disabled></div>"),
render: function () {
this.$el.html(this.template());
return this;
}
})
},*/
{
name: "SWRTCIN_STATUS",
label: "Active",
sortable: false,
editable: false, renderable: true,
cell: Backgrid.Cell.extend({
appendId: function(){
$(this.$el).find('.active').attr('id', this.model.id);
},
render: function () {
if(this.model.attributes.SWRTCIN_STATUS === "A"){
this.$el.html(_.template("<div class='text-center'><input type='checkbox' class='active center' value='active' checked disabled></div>"));
}else{
this.$el.html(_.template("<div class='text-center'><input type='checkbox' class='active center' value='inactive' disabled></div>"));
}
this.appendId();
return this;
}
})
},
{
name: "Correct",
sortable: false,
editable: false,
renderable: true,
cell: Backgrid.Cell.extend({
template: _.template("<div class='text-center'><input type='checkbox' class='center activate' value='correct' checked></div>"),
events: {
"click .activate": "activate"
},
activate: function (e) {
var tr = $(this.el.parentNode);
if($(this.el).find(".activate").is(':checked')){
console.log("correct == true")
$(tr).find('.deleteOffering, .cloneOffering, .active').attr("disabled", true);
$(tr).removeClass("selected-row");
}else{
console.log("correct == false")
$(tr).find('.deleteOffering, .cloneOffering, .active').removeAttr('disabled');
$(tr).addClass("selected-row");
}
},
render: function () {
this.$el.html(this.template());
this.delegateEvents();
return this;
}
}),
}
]);
//-- public ------------------------------------------------------------------------------------
var ReviewView = Backbone.View.extend({
initialize: function (options) {
App.log('ReviewView.init(',arguments,');');
document.title = "SAL+ 2014 Review";
reviewView = ReviewView;
this.startModal();
this.fetchData();
this.render();
templateData = {
records: undefined
};
},
events: {
'click .column-trigger': 'showHideColumns',
"change .per-page": "resultsPerPage",
"click .newSubject": "addOffering",
"click .newMssc": "newMssc",
"click .viewCohorts": "viewCohorts",
"click .cloneOffering": "cloneOffering",
"click .deleteOffering": "deleteOffering",
"click .auditTrail": "auditTrail",
"click #xls": "saveAsXls",
"click #csv": "saveAsCsv",
'click input.active': "changeStatus"
},
//Build The data grid
fetchData: function () {
that = this;
if (!tcidCollection) { tcidCollection = App.collections.tcidCollection = new TCIDCollection(); }
tcidCollection.fetch({
cache: true,
success: function (collection) {
templateData.records = collection.fullCollection.length;
that.grid();
},
error: function (collection, response) { }
});
},
columnsDropDown: function(options, collection) {
array = _.map(options.columns.models, _.clone);
array.reverse();
_.each(array, function(column){
var li = $('<li/>')
.attr('role', 'menuitem').html(column.attributes.name).addClass('show-hide')
.insertAfter('.columns');
$("<input />", {
type: 'checkbox',
id : column.attributes.name,
name : column.attributes.name,
checked: "checked"
// dataToggle: true,
}).addClass('column-trigger pull-left')
.appendTo(li);
});
$('.show-hide li:last').remove();
$('.show-hide li:last').remove();
$('.show-hide li:last').remove();
$('.show-hide li:last').remove();
},
showHideColumns: function(events, options, collection, columns) {
var columns = myColumns;
var columnModel = myColumns.where({ name: $(events.currentTarget).attr("id")});
if ($(events.currentTarget).is(':checked')){
columnModel[0].set("renderable", true);
}
else {
columnModel[0].set("renderable", false);
}
//this.stickyHeader().reload();
events.stopPropagation();
},
resultsPerPage: function (){
var perPage = parseInt($( ".per-page" ).val())
tcidCollection.setPageSize(perPage);
},
saveAsCsv: function (){
console.log('Saving As CSV');
require(['/_app/_js/table2csv/table2csv.js'], function (table2CSV) {
$('#reviewGrid').table2CSV();
});
},
saveAsXls: function (events){
//getting values of current time for generating the file name
var dt = new Date();
var day = dt.getDate();
var month = dt.getMonth() + 1;
var year = dt.getFullYear();
var hour = dt.getHours();
var mins = dt.getMinutes();
var postfix = day + "." + month + "." + year + "_" + hour + "." + mins;
//creating a temporary HTML link element (they support setting file names)
var a = document.createElement('a');
//getting data from our div that contains the HTML table
var data_type = 'data:application/vnd.ms-excel';
var table_div = document.getElementById('reviewGrid');
var table_html = table_div.outerHTML.replace(/ /g, '%20');
a.href = data_type + ', ' + table_html;
//setting the file name
a.download = 'exported_table_' + postfix + '.xls';
//triggering the function
a.click();
//just in case, prevent default behaviour
events.preventDefault();
},
grid: function(options){
var grid = App.grid = new Backgrid.Grid({
columns: myColumns,
collection: tcidCollection,
Backgrid: Backgrid
});
var paginator = new Backgrid.Extension.Paginator({
collection: tcidCollection
});
var clientSideFilter = new Backgrid.Extension.ClientSideFilter({
collection: tcidCollection,
placeholder: "Filter..",
// The model fields to search for matches
fields: ['Title', 'Subject Code'],
// How long to wait after typing has stopped before searching can start
wait: 150
});
grid.render().sort("Term Code", "ascending");
$("#grid").append(grid.el);
//this.stickyHeader();
$("#paginator").append(paginator.render().$el);
$("#filter").append(clientSideFilter.render().el);
$('#total-records').prepend('<strong>'+ grid.collection.fullCollection.length +' &nbsp;</strong>');
console.log("User-perceived page loading time: " + performance.timing.navigationStart);
},
/*sortArrows: function(events){
//TODO figure out listen to event for var columnName = this.column.get("name");
target = $(events.currentTarget);
console.log('target: ', target)
var ascending = '<span class="glyphicon glyphicon-arrow-up pull-right"></span>';
descending = '<span class="glyphicon glyphicon-arrow-down pull-right"></span>'
if ($(target).hasClass('ascending')){
$(target).append(ascending);
}
else if ($(target).hasClass('descending')) {
console.log('target = "descending"')
$(target).find('span').toggleClass("glyphicon-arrow-up glyphicon-arrow-down");
}
else if (!$(target).hasClass('descending') && !$(target).hasClass('ascending')) {
console.log('target = "!ascending!descending"')
//$(target glyphicon'.glyphicon').empty();
var test = $(target).find('span');
test.remove();
console.log(test)
}
//$(target).find(".ascending").toggleClass("glyphicon-chevron-right glyphicon-chevron-down");
},*/
// Build the modal events
startModal: function(collection, events){
var StartModal = Backbone.View.extend({
render: function() {
var modalElement = this.$el
require(['text!templates/review/modals/start.tpl'], function (template) {
modalElement.html(_.template(template));
$('<span />').addClass('pull-left dismisable').appendTo('.modal-footer').prepend('<label>Dont show this again&nbsp;&nbsp;&nbsp; </label>' );
label = '<label>Dont show this again: </label>';
$("<input />", {
type: 'checkbox',
checked: false
}).addClass('not-again')
.appendTo('label');
$('.modal-dialog').addClass('modal-lg');
$('.modal').removeClass('animate').removeClass('bounceInUp');
$( ".not-again" ).change(function() {
localStorage.setItem('startModal', 'true' );
$('.not-again').attr( "disabled", "disabled" );
});
return this;
});
}
});
if (localStorage.getItem('startModal') == "true") {
return;
} else {
var startModal = new Backbone.BootstrapModal({
animate: true,
content: new StartModal(),
modalOptions: {
backdrop: 'static',
keyboard: false
}
}).open();
}
},
addOffering: function(events){
if (!tcidCollection) { tcidCollection = App.collections.tcidCollection; }
var NewOffering = Backbone.View.extend({
initialize: function(options){
tcidCollection = options.collection;
this.$el.on('destroyed');
},
events: { 'click #reset': 'reset'},
form: function(e){
$('#new-offering').bootstrapValidator({
resetFormData: false,
message: 'This value is not valid',
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
CRN: {
validators: {
notEmpty: {
message: 'A CRN is unique and is required'
}
/* remote: {
message: 'A CRN must be Unique.',
url: 'js/datamssc.json',
type: 'get',
data: {}
} */
}
}
}}).on('success.form.bv', function(e) {
// Prevent form submission
e.preventDefault();
var data,
term_code = $('#term-code').val() || undefined,
crn = $('#crn').val() || undefined,
subject_code = $('#subject-code').val() || undefined,
title = $('#title').val() || undefined,
campus = $('#campus').val() || undefined,
mode = $('#mode').val() || undefined,
faculty = $('#faculty').val() || undefined,
teaching_auo = $('#teaching-aou').val() || undefined,
teaching_school_name = $('#teaching-school-name').val() || undefined,
convening_auo = $('#convening-auo').val() || undefined,
credit_points = $('#credit-points').val() || undefined,
durartion = $('#duration').val() || undefined,
teaching_pattern = $('#teaching-pattern').val() || undefined,
intake_pattern = $('#intake-pattern').val() || undefined,
comments = $('textarea#comments').val() || undefined,
active = $( "#active option:selected" ).val(),
data = {
"Term Code": term_code,
"CRN": crn,
"Subject Code": subject_code,
"Title": title,
"Campus": campus,
"Mode": mode,
"Faculty": faculty,
"Teaching AOU": teaching_auo,
"Teaching School Name": teaching_school_name,
"Convening AOU": convening_auo,
"Credit Points": credit_points,
"Duration": durartion,
"Teaching Pattern": teaching_pattern,
"Intake Pattern": intake_pattern,
"Comments": comments,
"SWRTCIN_STATUS": active
};
tcidCollection.on("add");
tcidCollection.add(data, {at: 0});
$('.alert-area').append(
'<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button><strong>Offering:</strong> '+ title +' '+ subject_code + '/' + term_code + ', has been created.</div>');
window.setTimeout(function() {
$(".alert").fadeTo(500, 0).slideUp(500, function(){
$(this).remove();
$('.alert-area').empty();
});
}, 2500);
$('.modal').modal('hide');
$('.modal').remove();
return;
});
},
reset: function(){
$(".modal").modal('hide');
$('.modal').remove();
},
render: function() {
var that = this;
var modalElement = this.$el
require(['text!templates/review/modals/newOffering.tpl'], function (template) {
$('#new-offering').empty();
modalElement.html(_.template(template));
$('.modal').removeClass('bounceInUp').addClass('rotatevInDownLeft')
$('.modal-dialog').removeClass('modal-lg');
$("body").addClass("modal-open");
that.form();
return this;
});
}
});
var newSubjectModal = new Backbone.BootstrapModal({
animate: true,
content: new NewOffering({
collection: tcidCollection,
}),
footer: false,
modalOptions: {
backdrop: 'static',
keyboard: false
}
}).open();
},
viewCohorts: function(events){
var ViewCohorts = Backbone.View.extend({
render: function() {
var modalElement = this.$el
require(['text!templates/review/modals/viewCohorts.tpl'], function (template) {
modalElement.html(_.template(template));
$("body").addClass("modal-open");
return this;
});
// $('.modal-dialog').addClass('modal-lg');
},
});
var viewCohorts = new Backbone.BootstrapModal({
animate: true,
content: new ViewCohorts(),
modalOptions: {
backdrop: 'static',
keyboard: false
}
}).open();
// $("body").removeClass("modal-open")
},
cloneOffering: function(events){
if (!tcidCollection) { tcidCollection = App.collections.tcidCollection; }
var id = $(events.currentTarget).attr('id');
selectedModel = App.collections.tcidCollection.get(id).toJSON();
var CloneOffering = Backbone.View.extend({
initialize: function(options){
this.$el.on('destroyed');
tcidCollection = options.collection;
selectedModel = options.selectedModel;
},
events: { 'click #reset': 'reset'},
form: function (){
$('#clone-obj-form').bootstrapValidator({
resetFormData: true,
message: 'This value is not valid',
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
CRNcheck: {},
CRN: {
validators: {
notEmpty: {
message: 'A CRN is unique and is required'
},
different: {
field: 'CRNcheck',
message: 'The CRN must be unquie.'
}
}
}
}}).on('success.form.bv', function(e) {
// Prevent form submission
var data,
term_code = $('#term-code').val() || undefined,
crn = $('#crn').val() || undefined,
subject_code = $('#subject-code').val() || undefined,
title = $('#title').val() || undefined,
campus = $('#campus').val() || undefined,
mode = $('#mode').val() || undefined,
faculty = $('#faculty').val() || undefined,
teaching_auo = $('#teaching-aou').val() || undefined,
teaching_school_name = $('#teaching-school-name').val() || undefined,
convening_auo = $('#convening-auo').val() || undefined,
credit_points = $('#credit-points').val() || undefined,
durartion = $('#duration').val() || undefined,
teaching_pattern = $('#teaching-pattern').val() || undefined,
intake_pattern = $('#intake-pattern').val() || undefined,
comments = $('textarea#comments').val() || undefined,
active = $( "#active option:selected" ).val(),
data = {
"Term Code": term_code,
"CRN": crn,
"Subject Code": subject_code,
"Title": title,
"Campus": campus,
"Mode": mode,
"Faculty": faculty,
"Teaching AOU": teaching_auo,
"Teaching School Name": teaching_school_name,
"Convening AOU": convening_auo,
"Credit Points": credit_points,
"Duration": durartion,
"Teaching Pattern": teaching_pattern,
"Intake Pattern": intake_pattern,
"Comments": comments,
"SWRTCIN_STATUS": active
};
tcidCollection.on("add");
tcidCollection.add(data, {at: 0}).addClass('test');
$('.alert-area').append( '<div class="alert alert-warning alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button><strong>Offering:</strong> '+ title +' '+ subject_code + '/' + term_code + ', has been cloned.</div>' );
window.setTimeout(function() {
$(".alert").fadeTo(500, 0).slideUp(500, function(){
$('.alert-area').empty();
});
}, 2500);
$('.modal').modal('hide');
$('.modal').remove();
e.preventDefault();
return;
});
},
reset: function(){
$(".modal").modal('hide');
$('.modal').remove();
},
render: function() {
var that = this;
var modalElement = this.$el
require(['text!templates/review/modals/cloneOffering.tpl'], function (template) {
modalElement.html(_.template(template, selectedModel));
$("body").addClass("modal-open");
$('.modal-dialog').addClass('modal-lg');
that.form();
return this;
});
}
});
var cloneOffering = new Backbone.BootstrapModal({
animate: true,
content: new CloneOffering({
collection: tcidCollection,
selectedModel: selectedModel
}),
modalOptions: {
backdrop: 'static',
keyboard: false
}
}).open();
},
deleteOffering: function(events){
if (!tcidCollection) { tcidCollection = App.collections.tcidCollection; }
var id = $(events.currentTarget).attr('id');
selectedModel = App.collections.tcidCollection.get(id);
console.log(selectedModel)
var DeleteOffering = Backbone.View.extend({
initialize: function(options){
this.$el.on('destroyed');
tcidCollection = options.collection;
selectedModel = options.selectedModel;
},
events: {
'click #reset': 'reset',
'click #delete-offering': 'deleteModel'
},
deleteModel: function (){
tcidCollection.on("remove", function(model){
});
$('.alert-area').append( '<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button><strong>Offering:</strong> '+ selectedModel.attributes['Title'] +' '+ selectedModel.attributes['Subject Code'] + '/' + selectedModel.attributes['Term Code'] + ', has been deleted.</div>' );
window.setTimeout(function() {
$(".alert").fadeTo(500, 0).slideUp(500, function(){
$('.alert-area').empty();
});
}, 2500);
tcidCollection.remove(selectedModel);
$('.modal').modal('hide');
$('.modal').remove();
},
reset: function(){
$(".modal").modal('hide');
$('.modal').remove();
},
render: function(options) {
var that = this;
var modalElement = this.$el
require(['text!templates/review/modals/deleteOffering.tpl'], function (template) {
modalElement.html(_.template(template, selectedModel));
$('.modal-dialog').removeClass('modal-lg');
$("body").addClass("modal-open");
return this;
});
/*
if(selectedModel.attributes.SWRTCIN_STATUS === 'A'){
this.$el.html('DeleteOffering - This mofo is active');
}
else{
this.$el.html('DeleteOffering - This mofo is inactive');
}
*/
return this;
}
});
var deleteOffering = new Backbone.BootstrapModal({
animate: true,
content: new DeleteOffering({
collection: tcidCollection,
selectedModel: selectedModel
}),
modalOptions: {
backdrop: 'static',
keyboard: false
}
}).open();
},
changeStatus: function(e){
if(e.currentTarget.checked){
console.log()
$(e.currentTarget).attr('value', 'active');
}else{
$(e.currentTarget).attr('value', 'inactive');
}
},
auditTrail: function(collection, events){
var viewHistory = new Backbone.BootstrapModal({
animate: true,
allowCancel: false,
content: new AuditTrail()
}).open();
},
render: function(options){
App.log('ReviewView.render(',templateData,');');
$('.main').html(_.template(review, templateData));
$('table').attr('id', 'reviewGrid');
this.columnsDropDown({columns: myColumns});
var datetime = null,
date = null;
var update = function () {
date = moment(new Date())
datetime.html(date.format('dddd, MMMM Do YYYY, h:mm:ss a'));
};
datetime = $('.time')
update();
setInterval(update, 1000);
$('.btn-cohort').tooltip( {
"delay": 0,
"track": true,
"fade": 250,
"title": 'TCID 9876123456; \n Start Session 201430;'
});
$('.teaching-pattern').tooltip( {
"title": "The Teaching Pattern must indicate the sessions which the subject is taught. \n If a subject is multi year the pattern will repeat until the duration is reached.",
"delay": 0,
"animation": true,
"placement": "left",
"fade": 250,
"html": true
});
$('.intake-pattern').tooltip( {
"title": "The Intake Pattern must indicate the session(s) a new intake of students occurs, i.e. the Start Session for each commencing cohort. Adding an intake will automatically add the Start Session to the Teaching Pattern.",
"delay": 0,
"animation": true,
"placement": "right",
"fade": 250,
"html": true
});
}
});
var AuditTrail = Backbone.View.extend({
render: function() {
this.$el.html('auditTrail');
return this;
}
});
jQuery.event.special.destroyed = {
remove: function(o) {
console.log("remove")
if (o.handler) {
o.handler()
}
}
}
return ReviewView;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment