Last active
December 31, 2015 20:49
-
-
Save mohitmayank/8043113 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*global define:false */ | |
define([ | |
'underscore', | |
'jquery', | |
'backbone', | |
'marionette', | |
'./templates/TableViewTmpl', | |
'./templates/TableRowTmpl', | |
'vendor/downloadify/swfobject', | |
'vendor/downloadify/downloadify', | |
'Timer' | |
'plugin/jquery/tablesorter', | |
'plugin/jquery/tablesorter.widgets', | |
//'plugin/jquery/tablesorter.widgets-filter-formatter', | |
'plugin/jquery/jquery.iframe-transport', | |
'plugin/jquery/jquery.fileupload', | |
//'jquery.ui.widget', | |
'vendor/bootstrap/plugins/bootstrap-datetimepicker' | |
], function(_, $, Backbone, Marionette, TableViewTmpl, TableRowTmpl, swfobject, Downloadify, Timer) { | |
'use strict'; | |
var tagsToReplace = { | |
'&': '&', | |
'<': '<', | |
'>': '>' | |
}; | |
var replaceTag = function(tag) { | |
return tagsToReplace[tag] || tag; | |
}; | |
var safe_tags_replace = function(str) { | |
str = str.replace(/[<>]/g, replaceTag); | |
return str; | |
}; | |
var noop = function(){}; | |
var noopFalse = function(){return false;}; | |
/*************************\ | |
UI Datepicker (2 inputs) | |
\*************************/ | |
var uiDatepicker = function($cell) { | |
var $minDateField = $('<div class="input-prepend minDateFilterField"><span class="add-on"><i data-time-icon="icon-chevron-right" data-date-icon="icon-chevron-right"></i></span><input class="forceHide" type="text"></div>').appendTo($cell); | |
$minDateField.datetimepicker({ | |
pickDate: true, | |
pickTime: false, | |
format : "dd-MM-yyyy" | |
}); | |
var minDatePicker = $minDateField.find('input'); | |
var $input = $('<input type="text" class="dateFilterField"/>').appendTo($cell); | |
var $maxDateField = $('<div class="input-append maxDateFilterField"><input class="forceHide" type="text"><span class="add-on"><i data-time-icon="icon-chevron-left" data-date-icon="icon-chevron-left"></i></span></div>').appendTo($cell); | |
$maxDateField.datetimepicker({ | |
pickDate: true, | |
pickTime: false, | |
format : "dd-MM-yyyy" | |
}); | |
var maxDatePicker = $maxDateField.find('input'); | |
$minDateField.on('changeDate', function(){ | |
if(maxDatePicker.val() !== '') { | |
$input.val(minDatePicker.val() + ' - ' + maxDatePicker.val()); | |
} else { | |
$input.val('>= ' + minDatePicker.val()); | |
} | |
$input.trigger('search'); | |
}); | |
$maxDateField.on('changeDate', function(){ | |
if(minDatePicker.val() !== '') { | |
$input.val(minDatePicker.val() + ' - ' + maxDatePicker.val()); | |
} else { | |
$input.val('<= ' + maxDatePicker.val()); | |
} | |
$input.trigger('search'); | |
}); | |
$input.change(function(){ | |
if($input.val() === '') { | |
minDatePicker.val(''); | |
maxDatePicker.val(''); | |
} | |
return false; | |
}); | |
return $input; | |
}; | |
// var select2Picker = function($cell, index) { | |
// return $input; | |
// }; | |
return Marionette.ItemView.extend({ | |
template : TableViewTmpl, | |
constructor: function(options){ | |
Marionette.ItemView.prototype.constructor.apply(this, _.toArray(arguments)); | |
options = options || {}; | |
_.bindAll(this, | |
'renderUploader', | |
'renderDownloader', | |
'startTableSorter', | |
'addModel', | |
'removeModel', | |
'addRows', | |
'removeRow' | |
); | |
_.extend(this, _.pick(options, [ | |
'columns', | |
'strikeRow', | |
'colorRow', | |
'gridName', | |
'uploadUrl', | |
'autoFilter', | |
'enableUpload', | |
'title' | |
])); | |
if(_.isFunction(this.columns)) { | |
this.columns = this.columns.call(this); | |
} | |
_.each(this.columns, function(item){ | |
item.fieldEscaped = item.field.replace('.', '_dc_'); | |
item.colVals = []; | |
}); | |
this.csvColumns = _.pluck(this.csv, 'field'); | |
this.csvHeaders = _.pluck(this.csv, 'title'); | |
this.rows = {}; | |
}, | |
enableUpload : false, | |
autoFilter : false, | |
columns : [], | |
gridName : 'download', | |
title : function(){ | |
return this.gridName; | |
}, | |
uploadUrl : function(){ | |
if(this.collection) { | |
return this.collection.uploadUrl(); | |
} else { | |
return ''; | |
} | |
}, | |
ui : { | |
'buttonOnfiltersort' : 'button.onfiltersort', | |
'columnMenuInput' : '.columnMenuInput', | |
'buttonTablePrint' : 'button.tablePrint', | |
'buttonFilterReset' : 'button.filterReset', | |
'buttonDownloadify' : 'button.downloadifyButton', | |
'tableGrid' : '.tableGrid', | |
'gridRecordCountEl' : '.gridRecordCount', | |
'table' : 'table', | |
'tbody' : 'tbody', | |
'gridSortingInfo' : '.gridSortingInfo' | |
}, | |
events: { | |
'click tr.tableDataRow' : 'onRowClick', | |
'dblclick tr.tableDataRow' : 'onRowDblClick', | |
'click @ui.buttonOnfiltersort' : 'startTableSorter', | |
'click @ui.columnMenuInput' : 'columnMenuEvent', | |
'click @ui.buttonTablePrint' : 'printTable', | |
'click @ui.buttonFilterReset' : 'filterReset', | |
'click @ui.buttonDownloadify' : 'uriDownload' | |
}, | |
onRowClick: function(e) { | |
this.trigger('onRowClick', e.currentTarget.id); | |
}, | |
onRowDblClick: function(e) { | |
this.trigger('onRowDblClick', e.currentTarget.id); | |
}, | |
printTable : function(){ | |
var title = _.result(this, 'title'); | |
var printWindow = window.open('', title, 'height=400,width=600'); | |
printWindow.document.write('<html><head><title>'+title+'</title>'); | |
printWindow.document.write('<style>.columnHide, .filtered, .tablesorter-filter-row {display: none} table, tr, td, th {border : solid 1px black; border-collapse : collapse} td, th {padding: 2px;}</style>'); | |
printWindow.document.write('</head><body>'); | |
printWindow.document.write('<h4>' + title + '</h4>'); | |
printWindow.document.write(this.ui.tableGrid.html()); | |
printWindow.document.write(this.ui.gridRecordCountEl.html()); | |
printWindow.document.write('</body></html>'); | |
printWindow.print(); | |
printWindow.close(); | |
return true; | |
}, | |
filterReset : function(){ | |
this.ui.table.trigger('filterReset'); | |
}, | |
columnMenuEvent : function(e){ | |
var colClass = e.currentTarget.value; | |
var hide = true; | |
if (e.currentTarget.checked) { | |
self.$('.'+colClass).removeClass('columnHide'); | |
hide = false; | |
} else { | |
self.$('.'+colClass).addClass('columnHide'); | |
} | |
_.each(this.columns, function(col){ | |
if(col.fieldEscaped === colClass) | |
{ | |
col.hidden = hide; | |
} | |
}); | |
}, | |
uriDownload : function(){ | |
var uri = 'data:application/csv;charset=UTF-8,' + encodeURIComponent(this.toCSV()); | |
window.open(uri); | |
}, | |
strikeRow : noopFalse, | |
colorRow : noopFalse, | |
sortOn : false, | |
lineCount : 0, | |
collectionEvents : { | |
'add' : 'addModel', | |
'remove' : 'removeModel' | |
}, | |
addModel : function(model){ | |
var rows = {}; | |
rows[model.get('_id')] = model; | |
this.addRows(rows); | |
}, | |
removeModel : function(model){ | |
this.removeRow(model.get('_id')); | |
}, | |
fetchColVal : function (model, key) { | |
try{ | |
var n=key.split("."); | |
var test = model; | |
var schema = this._args.schema; | |
if(!test) | |
{ | |
return ''; | |
} | |
for (var i=0;i<n.length;i++) | |
{ | |
if(test[n[i]]) | |
{ | |
test = test[n[i]]; | |
} else if (test.get) { | |
test = test.get(n[i]); | |
} | |
else | |
{ | |
return ''; | |
} | |
} | |
if(!_.isString(test) && test.toString) { | |
test = test.toString(); | |
} | |
return safe_tags_replace(test); | |
} | |
catch(err){ | |
return ''; | |
} | |
}, | |
addRows : function(rows){ | |
_.each(rows, function(row, id){ | |
var style = this.colorRow(row); | |
if(style) { | |
style = 'style="background-color:' + style + '"'; | |
} else { | |
style = ''; | |
} | |
var values = {}; | |
_.each(this.columns, function(item){ | |
var v = this.fetchColVal(row, item.field); | |
item.colVals.push(v); | |
values[item.field] = v; | |
}, this); | |
// console.log(values); | |
this.ui.tbody.append(TableRowTmpl({ | |
_id : id, | |
columns : this.columns, | |
values : values, | |
strikeRow : this.strikeRow(row), | |
style : style | |
})); | |
this.lineCount++; | |
this.rows[id] = values; | |
}, this); | |
this._updateTimer.reset(); | |
}, | |
removeRow : function(id) { | |
this.$('#'+id).remove(); | |
this.lineCount--; | |
if(this.lineCount < 0) | |
{ | |
this.lineCount = 0; | |
} | |
this._updateTimer.reset(); | |
}, | |
startTableSorter : function(){ | |
if(!this.sortOn) | |
{ | |
var that = this; | |
_.defer(function(){ | |
var filterFormatter = {}; | |
//var filterFunctions = {}; | |
_.each(that.columns, function(item, index){ | |
if(item.schema.type === 'Date') { | |
filterFormatter[index] = uiDatepicker; | |
} | |
// else { | |
//filterFunctions[index] = true; | |
// } | |
}); | |
that.ui.table.tablesorter({ | |
dateFormat : 'ddmmyyyy', | |
theme: 'bootstrap', | |
widthFixed: false, | |
headerTemplate: '{content} {icon}', | |
// cssAsc : 'tableViewSortedCol', | |
// cssDesc : 'tableViewSortedCol', | |
headers: { | |
/* | |
0: { | |
sorter: false, | |
filter: false | |
} | |
*/ | |
}, | |
widgets: [ | |
//'reorder', | |
'resizable', | |
'uitheme', | |
'filter', | |
//'zebra', | |
'stickyHeaders' | |
], | |
widgetOptions: { | |
filter_liveSearch : true, | |
filter_searchDelay : 800, | |
// // reorder_axis: 'xy', | |
// // reorder_complete: function() { | |
// // that.filterPatch(); | |
// // }, | |
// // zebra: [ | |
// 'even', | |
// 'odd' | |
// ] | |
filter_formatter : filterFormatter, | |
//filter_functions : filterFunctions | |
} | |
}); | |
that.sortOn = true; | |
that.ui.table.bind('filterEnd', function() { | |
that.patchLineNumbers(); | |
}); | |
that.ui.table.bind('sortStart', function() { | |
that.ui.gridSortingInfo.show(); | |
}); | |
that.ui.table.bind('sortEnd', function() { | |
that.ui.gridSortingInfo.hide(); | |
}); | |
_.each(that.columns, function(item, index) { | |
var _classes = item.fieldEscaped + ' ' + (item.hidden ? 'columnHide' : ''); | |
that.$('.tablesorter-filter-row td:eq(' + index + ')').addClass(_classes); | |
}); | |
}); | |
this.ui.buttonOnfiltersort.hide(); | |
this.ui.buttonFilterReset.show(); | |
} | |
}, | |
patchLineNumbers: function(length) { | |
var that = this; | |
_.defer(function(){ | |
try { | |
var length = that.lineCount; | |
var suffix = ''; | |
if(that.sortOn) | |
{ | |
that.ui.table.trigger('update'); | |
that.ui.table.trigger('appendCache'); | |
length = that.$('tr.tableDataRow:not(.filtered)').size(); | |
if(length != that.lineCount) | |
{ | |
if(that.lineCount <= 0) { | |
suffix = ''; | |
}else if(that.lineCount === 1){ | |
suffix = ' / ' + NSpace.Language.Generic.OneRecord; | |
}else{ | |
suffix = ' / ' + that.lineCount + ' ' + NSpace.Language.Generic.Records; | |
} | |
} | |
} | |
if(length <= 0) | |
{ | |
that.ui.gridRecordCountEl.removeClass('label-warning').removeClass('label-success').html(NSpace.Language.Generic.NoRecord + suffix); | |
} | |
else if(length === 1) | |
{ | |
that.ui.gridRecordCountEl.removeClass('label-warning').addClass('label-success').html(NSpace.Language.Generic.OneRecord + suffix); | |
} | |
else | |
{ | |
that.ui.gridRecordCountEl.removeClass('label-warning').addClass('label-success').html(length + ' ' + NSpace.Language.Generic.Records + suffix); | |
} | |
} catch(e){ | |
} | |
}); | |
_.defer(function(){ | |
_.each(that.columns, function(item, index){ | |
item.colVals = _.unique(item.colVals); | |
}, that); | |
}); | |
}, | |
serializeData : function(){ | |
return { | |
columns : this.columns | |
}; | |
}, | |
render : function(){ | |
Marionette.ItemView.prototype.render.apply(this, _.toArray(arguments)); | |
this.ui.gridSortingInfo.hide(); | |
this._updateTimer = new Timer(1000, this.patchLineNumbers, function(){ | |
this.ui.gridRecordCountEl.addClass('label-warning').removeClass('label-success').html('Loading ...'); | |
},this); | |
this._updateTimer.reset(); | |
// if(this.collection) { | |
// var self = this; | |
// this.collection.fetch(); | |
// } | |
if(this.autoFilter) { | |
_.defer(this.startTableSorter); | |
} | |
_.defer(this.renderDownloader); | |
_.defer(this.renderUploader); | |
}, | |
renderUploader : function(){ | |
var self = this; | |
if (self.enableUpload) { | |
self.$('.fileupload').fileupload({ | |
url: _.result(self, 'uploadUrl'), | |
dataType: 'json', | |
formData: { | |
source: self.gridName | |
}, | |
start: function() { | |
self.$('.fileUploadModal').modal('show'); | |
}, | |
cache: false, | |
done: function(e, data) { | |
self.collection.fetch(); | |
if (data.result.success) { | |
self.$('.fileUploadDonelabel').removeClass('label-important').addClass('label-success').html('Success'); | |
} else { | |
self.$('.fileUploadDonelabel').removeClass('label-success').addClass('label-important').html('Error'); | |
} | |
self.$('.modal-body').html('<p>' + data.result.msg + '</p>'); | |
if (data.result.dirty) { | |
var dirty = '<dl class="dl-horizontal">'; | |
_.each(data.result.dirty, function(val, key) { | |
dirty += '<dt>Row ' + key + '</dt>'; | |
dirty += '<dd>' + val + '</dd>'; | |
}); | |
self.$('.modal-body').append(dirty); | |
} | |
self.triggerMethod('upload:done', self); | |
}, | |
progressall: function(e, data) { | |
var progress = parseInt(data.loaded / data.total * 100, 10); | |
self.$('.bar').css('width', progress + '%'); | |
} | |
}).prop('disabled', !$.support.fileInput).parent().addClass($.support.fileInput ? undefined : 'disabled'); | |
} else { | |
self.$('.fileinput-button').hide(); | |
} | |
}, | |
renderDownloader : function(){ | |
var self = this; | |
self.$('.downloadifyTarget').downloadify({ | |
filename: function() { | |
return self.gridName + '.csv'; | |
}, | |
data: function() { | |
return self.toCSV(); | |
}, | |
onComplete: noop, | |
onCancel: noop, | |
onError: noop, | |
swf: 'public/media/downloadify.swf', | |
downloadImage: 'public/images/download_small.png', | |
width: 40, | |
height: 30, | |
transparent: true, | |
append: true | |
}); | |
self.$('.downloadifyTarget object').css('display', 'block'); | |
if (swfobject.hasFlashPlayerVersion('10')) { | |
self.ui.buttonDownloadify.hide(); | |
} else { | |
self.ui.buttonDownloadify.show(); | |
} | |
}, | |
toCSV: function() { | |
var self = this; | |
var dataView = []; | |
this.$('tr.tableDataRow:not(.filtered)').each(function(){ | |
dataView.push(self.rows[$(this).attr('id')]); | |
}); | |
var ar = _.map(dataView, function(value) { | |
return _.pick(value, self.csvColumns); | |
}); | |
var l = self.csvColumns.length; | |
var csvArray = []; | |
csvArray.push(_.map(self.csvHeaders, function(val) { | |
return '"' + val.replace(/"/g, '""') + '"'; | |
}).join(',')); | |
_.each(ar, function(line) { | |
var tmp = []; | |
console.log(line); | |
for (var i = 0; i < l; i++) { | |
if(line[self.csvColumns[i]]) | |
{ | |
if(line[self.csvColumns[i]].replace) { | |
tmp.push('"' + line[self.csvColumns[i]].replace(/"/g, '""') + '"'); | |
} else { | |
tmp.push('"' + line[self.csvColumns[i]].toString().replace(/"/g, '""') + '"'); | |
} | |
} | |
else | |
{ | |
tmp.push(""); | |
} | |
} | |
csvArray.push(tmp.join(',')); | |
}); | |
return csvArray.join('\n'); | |
} | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<tr id='<%=_id %>' class='tableDataRow <%= strikeRow ? "strikeRow" : ""%>' <%=style%>> | |
<% _.each(columns, function(item){ %> | |
<td <%=style%> class='<%= item.fieldEscaped %> <%=item.hidden ? "columnHide" : "" %>'><%=values[item.field] %></td> | |
<% }); %> | |
</tr> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class='tableToolBar'> | |
<span class="gridRecordCount label">...</span> | |
<span class="gridSortingInfo label label-inverse"><i class='icon-refresh'></i> ...</span> | |
<div class="btn-group pull-right columnMenuButton"> | |
<a class="btn btn-info dropdown-toggle" data-toggle="dropdown" href="#"> | |
<i class='icon-check icon-white'></i> | |
<span class="caret"></span> | |
</a> | |
<ul class="dropdown-menu columnMenu"> | |
<% _.each(columns, function(item){ %> | |
<li> | |
<label class="checkbox"> | |
<input class='columnMenuInput' type="checkbox" value="<%= item.fieldEscaped %>" <%=item.hidden ? "" : "checked" %>> | |
<%=item.title %> | |
</label> | |
</li> | |
<% }); %> | |
</ul> | |
</div> | |
<button class="pull-right btn btn-info onfiltersort"><i class='icon-filter icon-white'></i></button> | |
<button class="pull-right btn btn-info filterReset" style='display:none'><i class='icon-refresh icon-white'></i></button> | |
<button class='pull-right btn btn-info tablePrint'><i class='icon-print icon-white'></i></button> | |
<div class='pull-right downloadifyTarget'></div> | |
<button class='btn btn-info downloadifyButton pull-right'><i class='icon-arrow-down icon-white'></i></button> | |
<div class='pull-right'> | |
<span class='btn btn-info fileinput-button'> | |
<i class='icon-arrow-up icon-white'></i> | |
<span></span> | |
<!-- The file input field used as target for the file upload widget --> | |
<input class='fileupload' type='file' name='files'> | |
</span> | |
</div> | |
</div> | |
<div class='clearfix'></div> | |
<div class='tableGrid'> | |
<table class='table table-striped table-condensed table-bordered'> | |
<thead> | |
<tr> | |
<% _.each(columns, function(item){ %> | |
<th class='<%= item.fieldEscaped %> <%=item.hidden ? "columnHide" : "" %>'><%=item.title %></th> | |
<% }); %> | |
</tr> | |
</thead> | |
<tbody> | |
</tbody> | |
<!--tfoot> | |
<tr> | |
<% _.each(columns, function(item){ %> | |
<th class='<%= item.fieldEscaped %> <%=item.hidden ? "columnHide" : "" %>'><%=item.title %></th> | |
<% }); %> | |
</tr> | |
</tfoot--> | |
</table> | |
</div> | |
<div class="fileUploadModal modal hide fade"> | |
<div class="modal-header"> | |
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | |
<h3><i class='icon-arrow-up'></i> <span class="fileUploadDonelabel label label-important"></span></h3> | |
</div> | |
<div class="modal-body"> | |
<p></p> | |
</div> | |
<div class="modal-footer"> | |
<div class='pull-right' style='margin-left: 15px; margin-top:-6px;'> | |
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button> | |
</div> | |
<div class='progress progress-striped'> | |
<div class='bar'></div> | |
</div> | |
</div> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function(_delay, _callback, _onStart, _context) { | |
var args = arguments, | |
_timerId, _start = 0, | |
_remaining = _delay, | |
_running = false; | |
if (!_onStart) { | |
_onStart = function(){}; | |
} | |
if (!_context) { | |
_context = this; | |
} | |
this.start = function(delay) { | |
if (!_running) { | |
if (delay) { | |
_delay = delay; | |
} | |
if(!_running) | |
{ | |
_onStart.apply(_context, Array.prototype.slice.call(args, 3, args.length)); | |
} | |
_running = true; | |
_start = new Date(); | |
_timerId = window.setTimeout(function() { | |
_callback.apply(_context, Array.prototype.slice.call(args, 3, args.length)); | |
}, _delay); | |
} | |
}; | |
this.stop = function() { | |
if (_running) { | |
window.clearTimeout(_timerId); | |
} | |
_running = false; | |
_remaining = _delay; | |
}; | |
this.pause = function() { | |
this.stop(); | |
_remaining -= new Date() - _start; | |
}; | |
this.resume = function() { | |
this.start(_remaining); | |
}; | |
this.reset = function(delay) { | |
this.stop(); | |
this.start(delay); | |
}; | |
this.setTime = function(delay) { | |
if (delay) { | |
_delay = delay; | |
} | |
}; | |
this.set = this.start; | |
this.clear = this.stop; | |
this.remaining = function() { | |
return new Date() - _start; | |
}; | |
}, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment