提交 610a3790 编写于 作者: S Sercan
上级 c73d567d
......@@ -27,4 +27,4 @@ npm-container
momentjs:moment
arch:ace-editor
aldeed:collection2
ephemer:reactive-datatables-modified
aldeed:tabular
\ No newline at end of file
......@@ -3,6 +3,7 @@ aldeed:collection2-core@1.0.0
aldeed:schema-deny@1.0.1
aldeed:schema-index@1.0.1
aldeed:simple-schema@1.5.3
aldeed:tabular@1.6.0
arch:ace-editor@1.2.1
autoupdate@1.2.4
babel-compiler@5.8.24_1
......@@ -27,7 +28,6 @@ diff-sequence@1.0.1
ecmascript@0.1.6
ecmascript-runtime@0.2.6
ejson@1.0.7
ephemer:reactive-datatables-modified@1.1.0
es5-shim@4.1.14
fastclick@1.0.7
fortawesome:fontawesome@4.5.0
......@@ -50,7 +50,7 @@ launch-screen@1.0.4
less@2.5.1
livedata@1.0.15
logging@1.0.8
mdg:validation-error@0.2.0
mdg:validation-error@0.4.0
meteor@1.1.10
meteor-base@1.0.1
meteorhacks:async@1.0.0
......@@ -59,7 +59,7 @@ minifiers@1.1.7
minimongo@1.0.10
mobile-experience@1.0.1
mobile-status-bar@1.0.6
momentjs:moment@2.10.6
momentjs:moment@2.11.1
mongo@1.1.3
mongo-id@1.0.1
npm-container@1.2.0
......
......@@ -8,4 +8,12 @@ tr.selected {
.modal-dialog {
width: 1000px !important;
}
.table.dataTable {
width: 100% !important;
}
div.dataTables_wrapper div.dataTables_processing {
visibility: hidden;
}
\ No newline at end of file
......@@ -46,7 +46,9 @@
</small>
</div>
<div class="modal-body">
{{> ReactiveDatatable tableData=reactiveDataFunction options=optionsObject tableId="tblConnection" }}
<div class="datatables_wrapper">
{{> tabular table=TabularTables.Connections class="table table-striped table-bordered table-hover" id="tblConnection"}}
</div>
<button id="btnCreateNewConnection" type="button" class="btn btn-block btn-outline btn-primary"
data-toggle="modal"
data-target="#connectionCreateModal">Create New
......
Template.topNavbar.rendered = function () {
var selector = $('#tblConnection');
selector.addClass('table-striped table-bordered table-hover');
selector.find('tbody').on('click', 'tr', function () {
var table = selector.DataTable();
......@@ -27,59 +26,6 @@ Template.topNavbar.rendered = function () {
};
Template.topNavbar.helpers({
reactiveDataFunction: function () {
return function () {
return Connections.find().fetch(); // or .map()
};
},
optionsObject: {
columns: [
{
title: '_id',
data: '_id',
className: 'center',
sClass: "hide_column"
},
{
title: 'Connection Name',
data: 'name',
className: 'center'
},
{
title: 'Hostname',
data: 'host',
className: 'center'
},
{
title: 'Port',
data: 'port',
className: 'center'
},
{
title: 'Database Name',
data: 'databaseName',
className: 'center'
},
{
title: 'Edit',
data: null,
className: 'center',
bSortable: false,
defaultContent: '<a href="" title="Edit" class="editor_edit"><i class="fa fa-edit text-navy"></i></a>'
},
{
title: 'Delete',
data: null,
className: 'center',
bSortable: false,
defaultContent: '<a href="" title="Delete" class="editor_remove"><i class="fa fa-remove text-navy"></i></a>'
}
]
}
});
Template.topNavbar.events({
'click #btnCreateNewConnection': function () {
$('#inputConnectionName').val('');
......
......@@ -10,7 +10,7 @@
<h5>Dumps for {{getConnection.name}}</h5>
</div>
<div class="ibox-content">
{{> ReactiveDatatable tableData=getDumps options=dumpsTableOptions tableId="tblDumps" }}
{{> tabular table=TabularTables.Dumps class="table table-striped table-bordered table-hover" id="tblDumps"}}
</div>
<div class="ibox-footer">
<!--<span class="pull-right">
......
......@@ -58,7 +58,7 @@ Template.databaseDumpRestore.events({
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "Yes, do it!",
closeOnConfirm: false
closeOnConfirm: true
}, function () {
var laddaButton = $('#btnTakeDump').ladda();
laddaButton.ladda('start');
......@@ -80,86 +80,3 @@ Template.databaseDumpRestore.events({
}
}
});
Template.databaseDumpRestore.helpers({
'getDumps': function () {
return function () {
return Dumps.find({}, {sort: {date: -1}}).fetch(); // or .map()
};
},
'dumpsTableOptions': {
columns: [
{
title: '_id',
data: '_id',
className: 'center',
sClass: "hide_column"
},
{
title: 'Connection name',
data: 'connectionName',
width: '20%',
className: 'center'
},
{
title: 'Date',
data: 'date',
width: '15%',
render: function (cellData) {
return moment(cellData).format('YYYY-MM-DD HH:mm:ss');
},
className: 'center'
},
{
title: 'File Path',
data: 'filePath',
width: '30%',
className: 'center'
},
{
title: 'Size',
data: 'sizeInBytes',
width: '10%',
render: function (cellData) {
var scale = 1;
var text = "Bytes";
var settings = Settings.findOne();
switch (settings.scale) {
case "MegaBytes":
scale = 1024 * 1024;
text = "MBs";
break;
case "KiloBytes":
scale = 1024;
text = "KBs";
break;
default:
scale = 1;
text = "Bytes";
break;
}
var result = isNaN(Number(cellData / scale).toFixed(2)) ? "0.00" : Number(cellData / scale).toFixed(2);
return result + " " + text;
},
className: 'center'
},
{
title: 'Import Status',
data: 'status',
width: '15%',
className: 'center'
},
{
title: 'Import',
data: null,
className: 'center',
width: '10%',
bSortable: false,
defaultContent: '<a href="" title="Import" class="editor_import"><i class="fa fa-database text-navy"></i></a>'
}
]
}
});
\ No newline at end of file
/**
* Created by RSercan on 24.1.2016.
*/
TabularTables = {};
Meteor.isClient && Template.registerHelper('TabularTables', TabularTables);
TabularTables.Connections = new Tabular.Table({
name: 'ConnectionList',
collection: Connections,
stateSave: true,
columns: [
{
title: '_id',
data: '_id',
className: 'center',
sClass: "hide_column"
},
{
title: 'Connection Name',
data: 'name',
className: 'center'
},
{
title: 'Hostname',
data: 'host',
className: 'center'
},
{
title: 'Port',
data: 'port',
className: 'center'
},
{
title: 'Database Name',
data: 'databaseName',
className: 'center'
},
{
title: 'Edit',
data: null,
className: 'center',
bSortable: false,
defaultContent: '<a href="" title="Edit" class="editor_edit"><i class="fa fa-edit text-navy"></i></a>'
},
{
title: 'Delete',
data: null,
className: 'center',
bSortable: false,
defaultContent: '<a href="" title="Delete" class="editor_remove"><i class="fa fa-remove text-navy"></i></a>'
}
]
});
TabularTables.Dumps = new Tabular.Table({
name: 'DumpList',
collection: Dumps,
stateSave: true,
columns: [
{
title: '_id',
data: '_id',
className: 'center',
sClass: "hide_column"
},
{
title: 'Connection name',
data: 'connectionName',
width: '20%',
className: 'center'
},
{
title: 'Date',
data: 'date',
width: '15%',
render: function (cellData) {
return moment(cellData).format('YYYY-MM-DD HH:mm:ss');
},
className: 'center'
},
{
title: 'File Path',
data: 'filePath',
width: '30%',
className: 'center'
},
{
title: 'Size',
data: 'sizeInBytes',
width: '10%',
render: function (cellData) {
var scale = 1;
var text = "Bytes";
var settings = Settings.findOne();
switch (settings.scale) {
case "MegaBytes":
scale = 1024 * 1024;
text = "MBs";
break;
case "KiloBytes":
scale = 1024;
text = "KBs";
break;
default:
scale = 1;
text = "Bytes";
break;
}
var result = isNaN(Number(cellData / scale).toFixed(2)) ? "0.00" : Number(cellData / scale).toFixed(2);
return result + " " + text;
},
className: 'center'
},
{
title: 'Import Status',
data: 'status',
width: '15%',
className: 'center'
},
{
title: 'Import',
data: null,
className: 'center',
width: '10%',
bSortable: false,
defaultContent: '<a href="" title="Import" class="editor_import"><i class="fa fa-database text-navy"></i></a>'
}
]
});
\ No newline at end of file
base64@1.0.3
blaze@2.1.2
blaze-tools@1.0.3
deps@1.0.7
ejson@1.0.6
ephemer:reactive-datatables@1.1.0
geojson-utils@1.0.3
html-tools@1.0.4
htmljs@1.0.4
id-map@1.0.3
jquery@1.11.3_2
json@1.0.3
meteor@1.1.6
minifiers@1.1.5
minimongo@1.0.8
observe-sequence@1.0.6
ordered-dict@1.0.3
random@1.0.3
reactive-var@1.0.5
spacebars-compiler@1.0.6
templating@1.1.1
tracker@1.0.7
underscore@1.0.3
The MIT License (MIT)
Copyright (c) 2014 Geordie
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# Reactive Datatables
Provides a [meteor.js](http://www.meteor.com) way of using [jquery.dataTables](http://datatables.net/) with reactively-updating data, instant search, state saving / pagination etc.
## Installation
`meteor add ephemer:reactive-datatables`
## Usage
In your template:
<template name="containsTheDataTable">
{{> ReactiveDatatable tableData=reactiveDataFunction options=optionsObject }}
</template>
**Important:** Due to the way Blaze interprets parameters upon calling a template, `reactiveDataFunction` should *return a __function__ that returns an array*, not return the data itself. I'm sure there's a cleverer way to do this, but it works for now:
dataTableData = function () {
return Meteor.users.find().fetch(); // or .map()
};
Template.containsTheDataTable.helpers({
reactiveDataFunction: function () {
return dataTableData;
},
optionsObject: optionsObject // see below
});
Set up your datatable's options as per the jquery.dataTables API, e.g.:
var optionsObject = {
columns: [{
title: 'Real Name',
data: 'profile.realname', // note: access nested data like this
className: 'nameColumn'
}, {
title: 'Photo',
data: 'profile.picture',
render: renderPhoto, // optional data transform, see below
className: 'imageColumn'
}],
// ... see jquery.dataTables docs for more
}
function renderPhoto(cellData, renderType, currentRow) {
// You can return html strings, change sort order etc. here
// Again, see jquery.dataTables docs
var img = "<img src='" + cellData + "' title='" + currentRow.profile.realname + "'>"
return img;
}
I've deliberately kept this package as close as possible to the original API. I've also deliberately not exposed any global variables, although you can access the DataTable API in the usual jquery way using the '#datatable' selector from your template, i.e., to get an array with your data:
`$('#datatable').DataTable().rows()`
## About returning a function
The reason you need to return a function with an array and not just the array itself (see code example above) is because the autorun / reactive context is on the datatable end (which is how the datatable knows to do the reactive updates).
If you just pass an array into the datatable (this would involve a 1-line source code change), it won't know when the array has been updated. This is because arrays by themselves don't have an .invalidate() function attached. The trick of passing a wrapped function into the datatable's template is the only way I can see to encapsulate the datatable functionality in a package. Please send me a pull request if you can see a better way around this.
## Acknowledgements
Thank you to @smowden for finding the key to getting this whole package off the ground: `$('#datatable').DataTable().clear().rows.add(data).draw()`
Package.describe({
name: 'ephemer:reactive-datatables-modified',
summary: "Fast and reactive jQuery DataTables using standard Cursors / DataTables API. Supports Bootstrap 3.",
version: "1.1.0",
git: "https://github.com/ephemer/meteor-reactive-datatables.git"
});
Package.onUse(function(api) {
api.versionsFrom('0.9.0');
api.use(['templating'], 'client');
api.addFiles([
'jquery.dataTables.min.js',
'reactive-datatables.js',
'reactive-datatable-template.html',
'reactive-datatable-template.js'
], 'client');
});
<template name="ReactiveDatatable">
<div class="datatable_wrapper"></div>
</template>
\ No newline at end of file
Template.ReactiveDatatable.rendered = function () {
var data = this.data;
if (typeof data.tableData !== "function") {
throw new Meteor.Error('Your tableData must be a function that returns an array via Cursor.fetch(), .map() or another (hopefully reactive) means')
}
var reactiveDataTable = new ReactiveDatatable(data.options);
// Help Blaze cleanly remove entire datatable when changing template / route by
// wrapping table in existing element (#datatable_wrap) defined in the template.
var table = document.createElement('table');
table.className = 'table dataTable';
table.id = data.tableId;
// Render the table element and turn it into a DataTable
this.$('.datatable_wrapper').append(table);
var dt = $(table).DataTable(data.options);
reactiveDataTable.datatable = dt;
dt.on('page.dt', function () {
var info = dt.page.info();
reactiveDataTable.page = info.page;
});
this.autorun(function () {
reactiveDataTable.update(data.tableData());
});
};
\ No newline at end of file
/*Tinytest.add('example', function (test) {
test.equal(true, true);
});
*/
\ No newline at end of file
ReactiveDatatable = function(options) {
var self = this;
this.options = options = _.defaults(options, {
// Any of these can be overriden by passing an options
// object into your ReactiveDatatable template (see readme)
stateSave: true,
stateDuration: -1, // Store data for session only
pageLength: 5,
lengthMenu: [3, 5, 10, 50, 100],
columnDefs: [{ // Global default blank value to avoid popup on missing data
targets: '_all',
defaultContent: '–––'
}],
stateLoadParams: function(settings, data) {
// Make it easy to change to the stored page on .update()
self.page = data.start / data.length;
}
});
};
ReactiveDatatable.prototype.update = function(data) {
if (!data) return;
var self = this;
self.datatable
.clear()
.rows.add(data)
.draw(false)
.page(self.page || 0) // XXX: Can we avoid drawing twice?
.draw(false); // I couldn't get the page drawing to work otherwise
};
{
"dependencies": [
[
"blaze",
"1.0.3"
],
[
"deps",
"1.0.1"
],
[
"ejson",
"1.0.0"
],
[
"geojson-utils",
"1.0.0"
],
[
"htmljs",
"1.0.0"
],
[
"id-map",
"1.0.0"
],
[
"jquery",
"1.0.0"
],
[
"json",
"1.0.0"
],
[
"meteor",
"1.0.2"
],
[
"minimongo",
"1.0.1"
],
[
"observe-sequence",
"1.0.1"
],
[
"ordered-dict",
"1.0.0"
],
[
"random",
"1.0.0"
],
[
"templating",
"1.0.4"
],
[
"ui",
"1.0.0"
],
[
"underscore",
"1.0.0"
]
],
"pluginDependencies": [],
"toolVersion": "meteor-tool@1.0.26",
"format": "1.0"
}
\ No newline at end of file
......@@ -4,7 +4,7 @@
Meteor.publish('dumps', function (connectionId) {
if (connectionId) {
var connection = Connections.findOne({_id: connectionId});
return Dumps.find({connectionName: connection.name});
return Dumps.find({connectionName: connection.name}, {sort: {date: 1}});
}
return [];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册