Updates to the data tracking app; Updated the VAP list.
This commit is contained in:
@@ -3,7 +3,7 @@ var fs = require('fs');
|
|||||||
var path = require('path');
|
var path = require('path');
|
||||||
var adminPath;
|
var adminPath;
|
||||||
|
|
||||||
var PRODUCT_LIST_PATH = "VAP_Availability_List_Oct2016.pdf";
|
var PRODUCT_LIST_PATH = "VAP_Availability_List_Nov2016.pdf";
|
||||||
|
|
||||||
//Notes:
|
//Notes:
|
||||||
//Use res.send or res.sendFile for static resources (like images or html)
|
//Use res.send or res.sendFile for static resources (like images or html)
|
||||||
@@ -222,9 +222,9 @@ module.exports = function(app, rootPath, passport, smtpTransport, sequelize) {
|
|||||||
//TODO: Can we just use extend?
|
//TODO: Can we just use extend?
|
||||||
Object.keys(req.body).forEach(function(key) {params[key] = req.body[key]});
|
Object.keys(req.body).forEach(function(key) {params[key] = req.body[key]});
|
||||||
|
|
||||||
// if(params.msgpack) {
|
//The client must wrapper any JSON it wants to send into another JSON object whose sole attribute is 'request' and whose value is the actual parameter JSON stringified.
|
||||||
// params = msgpack.decode(params.msgpack);
|
//This is because for some unknown reason, jquery.ajax (or derivative methods) does not stringify the JSON correctly (converts bool, int, etc, into strings), and the server cannot convert the strings back into native types.
|
||||||
// }
|
params = params.request ? JSON.parse(params.request) : params;
|
||||||
|
|
||||||
if(!model) {
|
if(!model) {
|
||||||
res.status(400).end();
|
res.status(400).end();
|
||||||
@@ -325,10 +325,11 @@ module.exports = function(app, rootPath, passport, smtpTransport, sequelize) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'restore': {
|
case 'restore': {
|
||||||
|
params.paranoid = false;
|
||||||
model.find(params).then(function(value) {
|
model.find(params).then(function(value) {
|
||||||
if(value) {
|
if(value) {
|
||||||
value.deletedAt = null;
|
value.setDataValue('deletedAt', null);
|
||||||
value.save().then(function() {
|
value.save({paranoid: false}).then(function() {
|
||||||
res.status(200).end();
|
res.status(200).end();
|
||||||
}).catch(function(err) {
|
}).catch(function(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -378,7 +379,10 @@ module.exports = function(app, rootPath, passport, smtpTransport, sequelize) {
|
|||||||
res.status(400).end();
|
res.status(400).end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(e) {console.log(e); res.status(400).end();}
|
catch(e) {
|
||||||
|
console.log(e);
|
||||||
|
res.status(400).end();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
BIN
downloaded tools/bootstrap-3.3.7-dist.zip
Normal file
BIN
downloaded tools/bootstrap-3.3.7-dist.zip
Normal file
Binary file not shown.
@@ -19,6 +19,10 @@ module.exports = {
|
|||||||
type: DataTypes.JSON,
|
type: DataTypes.JSON,
|
||||||
allowNull: false
|
allowNull: false
|
||||||
},
|
},
|
||||||
|
aliases: {
|
||||||
|
type: DataTypes.JSON,
|
||||||
|
allowNull: true
|
||||||
|
},
|
||||||
defaultPrice: {
|
defaultPrice: {
|
||||||
type: DataTypes.DECIMAL(9,2),
|
type: DataTypes.DECIMAL(9,2),
|
||||||
allowNull: false
|
allowNull: false
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ module.exports = {
|
|||||||
type: DataTypes.DATEONLY,
|
type: DataTypes.DATEONLY,
|
||||||
allowNull: false
|
allowNull: false
|
||||||
},
|
},
|
||||||
quantity: {
|
amount: {
|
||||||
type: DataTypes.DECIMAL(13,2),
|
type: DataTypes.DECIMAL(13,2),
|
||||||
allowNull: false
|
allowNull: false
|
||||||
},
|
},
|
||||||
@@ -58,15 +58,11 @@ module.exports = {
|
|||||||
updatedAt: {
|
updatedAt: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
allowNull: false
|
allowNull: false
|
||||||
},
|
|
||||||
deletedAt: {
|
|
||||||
type: DataTypes.DATE,
|
|
||||||
allowNull: true
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
charset: 'utf8',
|
charset: 'utf8',
|
||||||
timestamps: true,
|
timestamps: true,
|
||||||
paranoid: true
|
paranoid: false
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ module.exports = function(sequelize, DataTypes) {
|
|||||||
type: DataTypes.JSON,
|
type: DataTypes.JSON,
|
||||||
allowNull: false
|
allowNull: false
|
||||||
},
|
},
|
||||||
|
aliases: { //An array of alias names (strings) for this item. Used only to find the item, and not checked to ensure that names are unique.
|
||||||
|
type: DataTypes.JSON,
|
||||||
|
allowNull: true
|
||||||
|
},
|
||||||
defaultPrice: {
|
defaultPrice: {
|
||||||
type: DataTypes.DECIMAL(9,2),
|
type: DataTypes.DECIMAL(9,2),
|
||||||
allowNull: false
|
allowNull: false
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ module.exports = function(sequelize, DataTypes) {
|
|||||||
type: DataTypes.DATEONLY,
|
type: DataTypes.DATEONLY,
|
||||||
allowNull: false
|
allowNull: false
|
||||||
},
|
},
|
||||||
quantity: {
|
amount: {
|
||||||
type: DataTypes.DECIMAL(13,2),
|
type: DataTypes.DECIMAL(13,2),
|
||||||
allowNull: false
|
allowNull: false
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,12 @@
|
|||||||
"1. start": "node server.js",
|
"1. start": "node server.js",
|
||||||
"3. update-db": "sequelize db:migrate",
|
"3. update-db": "sequelize db:migrate",
|
||||||
"4. create-db-migration": "sequelize migration:create",
|
"4. create-db-migration": "sequelize migration:create",
|
||||||
"2. install": "npm install"
|
"2. install": "npm install",
|
||||||
|
"5. prune": "npm prune",
|
||||||
|
"start": "node server.js",
|
||||||
|
"migrateDB": "sequelize db:migrate",
|
||||||
|
"dropDB": "sudo -u postgres dropdb PetitTeton",
|
||||||
|
"createDB": "sudo -u postgres createdb PetitTeton"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcrypt-nodejs": "^0.0.3",
|
"bcrypt-nodejs": "^0.0.3",
|
||||||
|
|||||||
BIN
public/VAP_Availability_List_Nov2016.pdf
Normal file
BIN
public/VAP_Availability_List_Nov2016.pdf
Normal file
Binary file not shown.
@@ -4,7 +4,7 @@
|
|||||||
<!-- Main Page Content -->
|
<!-- Main Page Content -->
|
||||||
<h1><span class="fa fa-users"></span> Manage Venues</h1>
|
<h1><span class="fa fa-users"></span> Manage Venues</h1>
|
||||||
|
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-12">
|
||||||
<div class="dt-buttons btn-group" style="display: inline-block">
|
<div class="dt-buttons btn-group" style="display: inline-block">
|
||||||
<a id="createButton" class="btn btn-default buttons-create" tabindex="0" href="javaScript:void(0);"><span>New</span></a>
|
<a id="createButton" class="btn btn-default buttons-create" tabindex="0" href="javaScript:void(0);"><span>New</span></a>
|
||||||
<a id="editButton" class="btn btn-default buttons-selected buttons-edit" tabindex="0" href="javaScript:void(0);"><span>Edit</span></a>
|
<a id="editButton" class="btn btn-default buttons-selected buttons-edit" tabindex="0" href="javaScript:void(0);"><span>Edit</span></a>
|
||||||
@@ -75,46 +75,57 @@
|
|||||||
var $btnDelete = $page.find("#deleteButton");
|
var $btnDelete = $page.find("#deleteButton");
|
||||||
var $btnRestore = $page.find("#restoreButton");
|
var $btnRestore = $page.find("#restoreButton");
|
||||||
|
|
||||||
$btnEdit.hide();
|
$btnEdit.disable(true);
|
||||||
$btnDelete.hide();
|
$btnDelete.disable(true);
|
||||||
$btnRestore.hide();
|
$btnRestore.disable(true);
|
||||||
|
|
||||||
|
var selectionChanged = function($tr, model) {
|
||||||
|
if($tr && model) {
|
||||||
|
$btnEdit.disable(false);
|
||||||
|
|
||||||
|
//If the object was deleted (hidden), then allow it to be restored, otherwise allow the model to be deleted.
|
||||||
|
if(model.deletedAt) {
|
||||||
|
$btnRestore.disable(false);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnRestore.disable(true);
|
||||||
|
$btnDelete.disable(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnEdit.disable(true);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
$btnRestore.disable(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var dataTable = new LinkedTable($page.find('#dataTable'), {
|
var dataTable = new LinkedTable($page.find('#dataTable'), {
|
||||||
url: "data/Venue/readAll",
|
url: "data/Venue/readAll",
|
||||||
attr: "data-key-name",
|
attr: "data-key-name",
|
||||||
selection: "row",
|
selection: "row",
|
||||||
selectionChanged: function($tr, model) {
|
selectionChanged: selectionChanged,
|
||||||
if($tr && model) {
|
|
||||||
$btnEdit.show();
|
|
||||||
|
|
||||||
//If the object was deleted (hidden), then allow it to be restored, otherwise allow the model to be deleted.
|
|
||||||
if(model.deletedAt) {
|
|
||||||
$btnRestore.show();
|
|
||||||
$btnDelete.hide();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$btnRestore.hide();
|
|
||||||
$btnDelete.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$btnEdit.hide();
|
|
||||||
$btnDelete.hide();
|
|
||||||
$btnRestore.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
parameters: function() {
|
parameters: function() {
|
||||||
return {msgpack: msgpack.encode({paranoid: !$page.find('#includeDeletedToggle').is(":checked")})};
|
return {paranoid: !$page.find('#includeDeletedToggle').is(":checked")};
|
||||||
},
|
},
|
||||||
postAddRowHandler: function($row, dataObject) {
|
postAddRowHandler: function($row, dataObject) {
|
||||||
if(dataObject.deletedAt) {
|
if(dataObject.deletedAt) {
|
||||||
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
postUpdateRowHandler: function($row, dataObject) {
|
||||||
|
if(dataObject.deletedAt) {
|
||||||
|
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if($row.is(dataTable.getSelectedRow())) {
|
||||||
|
selectionChanged($row, dataObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Call the refresh user table function once initially.
|
//Call the refresh user table function once initially.
|
||||||
dataTable.refresh();
|
dataTable.build();
|
||||||
|
|
||||||
//Refresh the data table if the user toggles the button to show/hide deleted elements.
|
//Refresh the data table if the user toggles the button to show/hide deleted elements.
|
||||||
$page.find('#includeDeletedToggle').on('click', function(event) {
|
$page.find('#includeDeletedToggle').on('click', function(event) {
|
||||||
@@ -126,7 +137,7 @@
|
|||||||
var model = dataTable.getSelectedRow() ? dataTable.getSelectedRow().data('model') : undefined;
|
var model = dataTable.getSelectedRow() ? dataTable.getSelectedRow().data('model') : undefined;
|
||||||
|
|
||||||
if(model && model.deletedAt) {
|
if(model && model.deletedAt) {
|
||||||
$.post("data/Venue/restore", {id: model.id}, "json").done(function(data) {
|
$.post("data/Venue/restore", {request: JSON.stringify({where: {id: model.id}})}, "json").done(function(data) {
|
||||||
dataTable.refresh();
|
dataTable.refresh();
|
||||||
}).fail(function(data) {
|
}).fail(function(data) {
|
||||||
alert("Failed to restore the desired object due to a server side error.");
|
alert("Failed to restore the desired object due to a server side error.");
|
||||||
@@ -175,21 +186,14 @@
|
|||||||
var createFunction = function(close) {
|
var createFunction = function(close) {
|
||||||
$editorForm.data('bs.validator').validate(function(isValid) {
|
$editorForm.data('bs.validator').validate(function(isValid) {
|
||||||
if(isValid) {
|
if(isValid) {
|
||||||
try {
|
$.ajax({url: "data/Venue/create", type: "POST", dataType: "json", data: encodeData({
|
||||||
$.post("data/Venue/create", {
|
name: $editorForm.find("#DFName").val()
|
||||||
name: $editorForm.find("#DFName").val()
|
})}).done(function(data) {
|
||||||
}, function(data) {
|
if(close) $editorDialog.modal("hide");
|
||||||
if(data.result == "success") {
|
dataTable.refresh();
|
||||||
if(close) $editorDialog.modal("hide");
|
}).fail(function(data) {
|
||||||
dataTable.refresh();
|
alert("Server call failed.");
|
||||||
}
|
});
|
||||||
else {
|
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
} catch(e) {
|
|
||||||
alert(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -203,22 +207,15 @@
|
|||||||
$editorDialog.find('#DFSave').on('click', function(event) {
|
$editorDialog.find('#DFSave').on('click', function(event) {
|
||||||
$editorForm.data('bs.validator').validate(function(isValid) {
|
$editorForm.data('bs.validator').validate(function(isValid) {
|
||||||
if(isValid) {
|
if(isValid) {
|
||||||
try {
|
$.ajax({url: "data/Venue/edit", type: "POST", dataType: "json", data: encodeData({
|
||||||
$.post("data/Venue/edit", {
|
id: dataTable.getSelectedRow().data("model").id,
|
||||||
id: dataTable.getSelectedRow().data("model").id,
|
name: $editorForm.find("#DFName").val()
|
||||||
name: $editorForm.find("#DFName").val()
|
})}).done(function(data) {
|
||||||
}, function(data) {
|
if(close) $editorDialog.modal("hide");
|
||||||
if(data.result == "success") {
|
dataTable.refresh();
|
||||||
$editorDialog.modal("hide");
|
}).fail(function(data) {
|
||||||
dataTable.refresh();
|
alert("Server call failed.");
|
||||||
}
|
});
|
||||||
else {
|
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
} catch(e) {
|
|
||||||
alert(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -244,11 +241,11 @@
|
|||||||
//Delete the element and close the dialog.
|
//Delete the element and close the dialog.
|
||||||
$deleteDialog.find('#DFDelete').on("click", function(event) {
|
$deleteDialog.find('#DFDelete').on("click", function(event) {
|
||||||
if(dataTable.getSelectedRow() != null) {
|
if(dataTable.getSelectedRow() != null) {
|
||||||
$.post("data/Venue/delete", {where: {id: dataTable.getSelectedRow().data("model").id}}, "json").done(function(data) {
|
$.ajax({url: "data/Venue/delete", type: "POST", dataType: "json", data: encodeData({where: {id: dataTable.getSelectedRow().data("model").id}})}).done(function(data) {
|
||||||
$deleteDialog.modal("hide");
|
$deleteDialog.modal("hide");
|
||||||
dataTable.refresh();
|
dataTable.refresh();
|
||||||
}).fail(function(data) {
|
}).fail(function(data) {
|
||||||
alert("Failed to delete the selection.")
|
alert("Server call failed.");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<!-- Main Page Content -->
|
<!-- Main Page Content -->
|
||||||
<h1><span class="fa fa-users"></span> Manage Categories</h1>
|
<h1><span class="fa fa-users"></span> Manage Categories</h1>
|
||||||
|
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-12">
|
||||||
<div class="dt-buttons btn-group" style="display: inline-block">
|
<div class="dt-buttons btn-group" style="display: inline-block">
|
||||||
<a id="createButton" class="btn btn-default buttons-create" tabindex="0" href="javaScript:void(0);"><span>New</span></a>
|
<a id="createButton" class="btn btn-default buttons-create" tabindex="0" href="javaScript:void(0);"><span>New</span></a>
|
||||||
<a id="editButton" class="btn btn-default buttons-selected buttons-edit" tabindex="0" href="javaScript:void(0);"><span>Edit</span></a>
|
<a id="editButton" class="btn btn-default buttons-selected buttons-edit" tabindex="0" href="javaScript:void(0);"><span>Edit</span></a>
|
||||||
@@ -74,6 +74,31 @@
|
|||||||
var $btnDelete = $page.find("#deleteButton");
|
var $btnDelete = $page.find("#deleteButton");
|
||||||
var $btnRestore = $page.find("#restoreButton");
|
var $btnRestore = $page.find("#restoreButton");
|
||||||
|
|
||||||
|
$btnEdit.disable(true);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
$btnRestore.disable(true)
|
||||||
|
|
||||||
|
var selectionChanged = function($tr, model) {
|
||||||
|
if($tr && model) {
|
||||||
|
$btnEdit.disable(false);
|
||||||
|
|
||||||
|
//If the object was deleted (hidden), then allow it to be restored, otherwise allow the model to be deleted.
|
||||||
|
if(model.deletedAt) {
|
||||||
|
$btnRestore.disable(false);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnRestore.disable(true);
|
||||||
|
$btnDelete.disable(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnEdit.disable(true);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
$btnRestore.disable(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var dataTable = new LinkedTable($page.find('#dataTable'), {
|
var dataTable = new LinkedTable($page.find('#dataTable'), {
|
||||||
url: "data/Category/readAll",
|
url: "data/Category/readAll",
|
||||||
attr: "data-key-name",
|
attr: "data-key-name",
|
||||||
@@ -81,35 +106,25 @@
|
|||||||
parameters: function() {
|
parameters: function() {
|
||||||
return {paranoid: !$page.find('#includeDeletedToggle').is(":checked")};
|
return {paranoid: !$page.find('#includeDeletedToggle').is(":checked")};
|
||||||
},
|
},
|
||||||
selectionChanged: function($tr, model) {
|
selectionChanged: selectionChanged,
|
||||||
if($tr && model) {
|
|
||||||
$btnEdit.show();
|
|
||||||
|
|
||||||
//If the object was deleted (hidden), then allow it to be restored, otherwise allow the model to be deleted.
|
|
||||||
if(model.deletedAt) {
|
|
||||||
$btnRestore.show();
|
|
||||||
$btnDelete.hide();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$btnRestore.hide();
|
|
||||||
$btnDelete.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$btnEdit.hide();
|
|
||||||
$btnDelete.hide();
|
|
||||||
$btnRestore.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
postAddRowHandler: function($row, dataObject) {
|
postAddRowHandler: function($row, dataObject) {
|
||||||
if(dataObject.deletedAt) {
|
if(dataObject.deletedAt) {
|
||||||
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
postUpdateRowHandler: function($row, dataObject) {
|
||||||
|
if(dataObject.deletedAt) {
|
||||||
|
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if($row.is(dataTable.getSelectedRow())) {
|
||||||
|
selectionChanged($row, dataObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Call the refresh user table function once initially.
|
//Call the refresh user table function once initially.
|
||||||
dataTable.refresh();
|
dataTable.build();
|
||||||
|
|
||||||
//Refresh the data table if the user toggles the button to show/hide deleted elements.
|
//Refresh the data table if the user toggles the button to show/hide deleted elements.
|
||||||
$page.find('#includeDeletedToggle').on('click', function(event) {
|
$page.find('#includeDeletedToggle').on('click', function(event) {
|
||||||
@@ -170,21 +185,14 @@
|
|||||||
var createFunction = function(close) {
|
var createFunction = function(close) {
|
||||||
$editorForm.data('bs.validator').validate(function(isValid) {
|
$editorForm.data('bs.validator').validate(function(isValid) {
|
||||||
if(isValid) {
|
if(isValid) {
|
||||||
try {
|
$.ajax({url: "data/Category/create", type: "POST", dataType: "json", data: encodeData({
|
||||||
$.post("data/Category/create", {
|
name: $editorForm.find("#DFName").val()
|
||||||
name: $editorForm.find("#DFName").val()
|
})}).done(function(data) {
|
||||||
}, function(data) {
|
if(close) $editorDialog.modal("hide");
|
||||||
if(data.result == "success") {
|
dataTable.refresh();
|
||||||
if(close) $editorDialog.modal("hide");
|
}).fail(function(data) {
|
||||||
dataTable.refresh();
|
alert("Server call failed.");
|
||||||
}
|
});
|
||||||
else {
|
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
} catch(e) {
|
|
||||||
alert(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -198,22 +206,15 @@
|
|||||||
$editorDialog.find('#DFSave').on('click', function(event) {
|
$editorDialog.find('#DFSave').on('click', function(event) {
|
||||||
$editorForm.data('bs.validator').validate(function(isValid) {
|
$editorForm.data('bs.validator').validate(function(isValid) {
|
||||||
if(isValid) {
|
if(isValid) {
|
||||||
try {
|
$.ajax({url: "data/Category/edit", type: "POST", dataType: "json", data: {
|
||||||
$.post("data/Category/edit", {
|
id: dataTable.getSelectedRow().data("model").id,
|
||||||
id: dataTable.getSelectedRow().data("model").id,
|
name: $editorForm.find("#DFName").val()
|
||||||
name: $editorForm.find("#DFName").val()
|
}}).done(function(data) {
|
||||||
}, function(data) {
|
$editorDialog.modal("hide");
|
||||||
if(data.result == "success") {
|
dataTable.refresh();
|
||||||
$editorDialog.modal("hide");
|
}).fail(function(data) {
|
||||||
dataTable.refresh();
|
alert("Server side error.");
|
||||||
}
|
});
|
||||||
else {
|
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
} catch(e) {
|
|
||||||
alert(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -239,15 +240,12 @@
|
|||||||
//Delete the element and close the dialog.
|
//Delete the element and close the dialog.
|
||||||
$deleteDialog.find('#deleteButton').on("click", function(event) {
|
$deleteDialog.find('#deleteButton').on("click", function(event) {
|
||||||
if(dataTable.getSelectedRow() != null) {
|
if(dataTable.getSelectedRow() != null) {
|
||||||
$.post("data/Category/delete", {where: {id: dataTable.getSelectedRow().data("model").id}}, function(data) {
|
$.ajax({url: "data/Category/delete", type: "POST", dataType: "json", data: encodeData({where: {id: dataTable.getSelectedRow().data("model").id}})}).done(function(data) {
|
||||||
if(data.result == "success") {
|
$deleteDialog.modal("hide");
|
||||||
$deleteDialog.modal("hide");
|
dataTable.refresh();
|
||||||
dataTable.refresh();
|
}).fail(function(data) {
|
||||||
}
|
alert("Server call failed.");
|
||||||
else {
|
});
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$deleteDialog.find('#DFCancelDelete').on('click', function(event) {
|
$deleteDialog.find('#DFCancelDelete').on('click', function(event) {
|
||||||
|
|||||||
373
public/admin/css/bootstrap-datetimepicker.css
vendored
Normal file
373
public/admin/css/bootstrap-datetimepicker.css
vendored
Normal file
@@ -0,0 +1,373 @@
|
|||||||
|
/*!
|
||||||
|
* Datetimepicker for Bootstrap 3
|
||||||
|
* version : 4.17.43
|
||||||
|
* https://github.com/Eonasdan/bootstrap-datetimepicker/
|
||||||
|
*/
|
||||||
|
.bootstrap-datetimepicker-widget {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget.dropdown-menu {
|
||||||
|
margin: 2px 0;
|
||||||
|
padding: 4px;
|
||||||
|
width: 19em;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
|
||||||
|
width: 38em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
|
||||||
|
width: 38em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
|
||||||
|
width: 38em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget.dropdown-menu:before,
|
||||||
|
.bootstrap-datetimepicker-widget.dropdown-menu:after {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before {
|
||||||
|
border-left: 7px solid transparent;
|
||||||
|
border-right: 7px solid transparent;
|
||||||
|
border-bottom: 7px solid #ccc;
|
||||||
|
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||||
|
top: -7px;
|
||||||
|
left: 7px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after {
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-right: 6px solid transparent;
|
||||||
|
border-bottom: 6px solid white;
|
||||||
|
top: -6px;
|
||||||
|
left: 8px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget.dropdown-menu.top:before {
|
||||||
|
border-left: 7px solid transparent;
|
||||||
|
border-right: 7px solid transparent;
|
||||||
|
border-top: 7px solid #ccc;
|
||||||
|
border-top-color: rgba(0, 0, 0, 0.2);
|
||||||
|
bottom: -7px;
|
||||||
|
left: 6px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget.dropdown-menu.top:after {
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-right: 6px solid transparent;
|
||||||
|
border-top: 6px solid white;
|
||||||
|
bottom: -6px;
|
||||||
|
left: 7px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before {
|
||||||
|
left: auto;
|
||||||
|
right: 6px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after {
|
||||||
|
left: auto;
|
||||||
|
right: 7px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .list-unstyled {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget a[data-action] {
|
||||||
|
padding: 6px 0;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget a[data-action]:active {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .timepicker-hour,
|
||||||
|
.bootstrap-datetimepicker-widget .timepicker-minute,
|
||||||
|
.bootstrap-datetimepicker-widget .timepicker-second {
|
||||||
|
width: 54px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.2em;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget button[data-action] {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
border: 0;
|
||||||
|
content: "Increment Hours";
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
border: 0;
|
||||||
|
content: "Increment Minutes";
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
border: 0;
|
||||||
|
content: "Decrement Hours";
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
border: 0;
|
||||||
|
content: "Decrement Minutes";
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
border: 0;
|
||||||
|
content: "Show Hours";
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
border: 0;
|
||||||
|
content: "Show Minutes";
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
border: 0;
|
||||||
|
content: "Toggle AM/PM";
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .btn[data-action="clear"]::after {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
border: 0;
|
||||||
|
content: "Clear the picker";
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .btn[data-action="today"]::after {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
border: 0;
|
||||||
|
content: "Set the date to today";
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .picker-switch {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .picker-switch::after {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
border: 0;
|
||||||
|
content: "Toggle Date and Time Screens";
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .picker-switch td {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
height: auto;
|
||||||
|
width: auto;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .picker-switch td span {
|
||||||
|
line-height: 2.5;
|
||||||
|
height: 2.5em;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td,
|
||||||
|
.bootstrap-datetimepicker-widget table th {
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table th {
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table th.picker-switch {
|
||||||
|
width: 145px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table th.disabled,
|
||||||
|
.bootstrap-datetimepicker-widget table th.disabled:hover {
|
||||||
|
background: none;
|
||||||
|
color: #777777;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table th.prev::after {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
border: 0;
|
||||||
|
content: "Previous Month";
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table th.next::after {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
border: 0;
|
||||||
|
content: "Next Month";
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table thead tr:first-child th {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table thead tr:first-child th:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td {
|
||||||
|
height: 54px;
|
||||||
|
line-height: 54px;
|
||||||
|
width: 54px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td.cw {
|
||||||
|
font-size: .8em;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: #777777;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td.day {
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td.day:hover,
|
||||||
|
.bootstrap-datetimepicker-widget table td.hour:hover,
|
||||||
|
.bootstrap-datetimepicker-widget table td.minute:hover,
|
||||||
|
.bootstrap-datetimepicker-widget table td.second:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td.old,
|
||||||
|
.bootstrap-datetimepicker-widget table td.new {
|
||||||
|
color: #777777;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td.today {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td.today:before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
border: solid transparent;
|
||||||
|
border-width: 0 0 7px 7px;
|
||||||
|
border-bottom-color: #337ab7;
|
||||||
|
border-top-color: rgba(0, 0, 0, 0.2);
|
||||||
|
position: absolute;
|
||||||
|
bottom: 4px;
|
||||||
|
right: 4px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td.active,
|
||||||
|
.bootstrap-datetimepicker-widget table td.active:hover {
|
||||||
|
background-color: #337ab7;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td.active.today:before {
|
||||||
|
border-bottom-color: #fff;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td.disabled,
|
||||||
|
.bootstrap-datetimepicker-widget table td.disabled:hover {
|
||||||
|
background: none;
|
||||||
|
color: #777777;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td span {
|
||||||
|
display: inline-block;
|
||||||
|
width: 54px;
|
||||||
|
height: 54px;
|
||||||
|
line-height: 54px;
|
||||||
|
margin: 2px 1.5px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td span:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td span.active {
|
||||||
|
background-color: #337ab7;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td span.old {
|
||||||
|
color: #777777;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget table td span.disabled,
|
||||||
|
.bootstrap-datetimepicker-widget table td span.disabled:hover {
|
||||||
|
background: none;
|
||||||
|
color: #777777;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget.usetwentyfour td.hour {
|
||||||
|
height: 27px;
|
||||||
|
line-height: 27px;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget.wider {
|
||||||
|
width: 21em;
|
||||||
|
}
|
||||||
|
.bootstrap-datetimepicker-widget .datepicker-decades .decade {
|
||||||
|
line-height: 1.8em !important;
|
||||||
|
}
|
||||||
|
.input-group.date .input-group-addon {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.sr-only {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
5
public/admin/css/bootstrap-datetimepicker.min.css
vendored
Normal file
5
public/admin/css/bootstrap-datetimepicker.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -12,6 +12,8 @@
|
|||||||
<meta name="revisit-after" content="12 days"/>
|
<meta name="revisit-after" content="12 days"/>
|
||||||
<meta name="robots" content="index, follow"/>
|
<meta name="robots" content="index, follow"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<!-- Prevent IE from running in compatibility mode. -->
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
<title>Petit Teton Apps</title>
|
<title>Petit Teton Apps</title>
|
||||||
|
|
||||||
@@ -24,6 +26,7 @@
|
|||||||
<!--<link rel="stylesheet" href="/admin/css/chosen.css"/>-->
|
<!--<link rel="stylesheet" href="/admin/css/chosen.css"/>-->
|
||||||
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css"/>
|
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css"/>
|
||||||
<link rel="stylesheet" href="css/select2.css"/>
|
<link rel="stylesheet" href="css/select2.css"/>
|
||||||
|
<link rel="stylesheet" href="css/bootstrap-datetimepicker.css"/>
|
||||||
<link rel="stylesheet" href="main.css" type="text/css"/>
|
<link rel="stylesheet" href="main.css" type="text/css"/>
|
||||||
|
|
||||||
<script type="text/javascript" language="JavaScript" src="js/jquery-1.11.3.min.js"></script>
|
<script type="text/javascript" language="JavaScript" src="js/jquery-1.11.3.min.js"></script>
|
||||||
@@ -41,29 +44,68 @@
|
|||||||
<!--<script type="text/javascript" language="JavaScript" src="js/socket.io.js"></script>-->
|
<!--<script type="text/javascript" language="JavaScript" src="js/socket.io.js"></script>-->
|
||||||
<script type="text/javascript" language="JavaScript" src="js/LinkedTable.js"></script>
|
<script type="text/javascript" language="JavaScript" src="js/LinkedTable.js"></script>
|
||||||
<script type="text/javascript" language="JavaScript" src="js/Dropdown.js"></script>
|
<script type="text/javascript" language="JavaScript" src="js/Dropdown.js"></script>
|
||||||
|
<script type="text/javascript" language="JavaScript" src="js/moment.js"></script>
|
||||||
<script type="text/javascript" language="JavaScript" src="js/select2.min.js"></script>
|
<script type="text/javascript" language="JavaScript" src="js/select2.min.js"></script>
|
||||||
<!--<script type="text/javascript" language="JavaScript" src="js/chosen.jquery.js"></script>-->
|
<!--<script type="text/javascript" language="JavaScript" src="js/chosen.jquery.js"></script>-->
|
||||||
<!--<script type="text/javascript" language="JavaScript" src="js/jquery.validate.js"></script>-->
|
<!--<script type="text/javascript" language="JavaScript" src="js/jquery.validate.js"></script>-->
|
||||||
<script type="text/javascript" language="JavaScript" src="js/validator.js"></script> <!-- https://github.com/1000hz/bootstrap-validator http://1000hz.github.io/bootstrap-validator/ -->
|
<script type="text/javascript" language="JavaScript" src="js/validator.js"></script> <!-- https://github.com/1000hz/bootstrap-validator http://1000hz.github.io/bootstrap-validator/ -->
|
||||||
<!--
|
<script type="text/javascript" language="JavaScript" src="js/bootstrap-datetimepicker.js"></script>
|
||||||
<script type="text/javascript" language="JavaScript">
|
|
||||||
function check(x) {
|
|
||||||
alert(x);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- Compact message packing format that should preserve binary data (booleans, numbers, etc). -->
|
<script type="text/javascript" language="JavaScript">
|
||||||
<!-- https://github.com/mcollina/msgpack5 -->
|
//Add a disable(bool) method on jquery objects.
|
||||||
<!-- http://msgpack.org/index.html -->
|
jQuery.fn.extend({
|
||||||
<script type="text/javascript" language="JavaScript" src="js/msgpack5.js"></script>
|
disable: function(state) {
|
||||||
|
return this.each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
if($this.is('input, button, textarea, select'))
|
||||||
|
this.disabled = state;
|
||||||
|
else
|
||||||
|
$this.toggleClass('disabled', state);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//Ignore clicks on links that are disabled.
|
||||||
|
$('body').on('click', 'a.disabled', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
//Fix the select2 control to allow typing when focused.
|
||||||
|
$(document).on('focus', 'span.select2', function () {
|
||||||
|
$(this).prev('select:not([multiple])').select2('open');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('submit', 'form', function(event) {
|
||||||
|
var $form = $(this);
|
||||||
|
var $btn = $form.find('button.btn-default:visible');
|
||||||
|
|
||||||
|
$btn.first().click();
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
//A simple utility function to wrap parameters sent to the server with an object containing a sole attribute 'request' whose value is a stringified data object.
|
||||||
|
//This is required (stringifying and then adding it to an object) when using jquery to make an ajax request (post or get) because the default stringification looses the type information of native types: it turns everything (dates, integers, booleans, etc) into strings.
|
||||||
|
//Stringifying and then decoding on the server fixes the problem. We are using the attribute 'request' as a common code to do this.
|
||||||
|
function encodeData(data) {
|
||||||
|
return {request: JSON.stringify(data)};
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).on('focusin', function(event) {
|
||||||
|
var modal = $('div:visible[role="modal"]');
|
||||||
|
|
||||||
|
if(modal.length) {
|
||||||
|
if(modal[0] !== event.target && !modal[0].contains(event.target)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="overall">
|
<div id="overall">
|
||||||
<div id="page">
|
<div id="page">
|
||||||
<div id="menu"><!-- Note: Comment out spacing between the elements since the browser will interpret the spaces as characters to be displayed.
|
<div id="menu"><!-- Note: Comment out spacing between the elements since the browser will interpret the spaces as characters to be displayed.
|
||||||
--><a href="#!/dataEntry">Sales</a><!--
|
--><a href="#!/sales">Sales</a><!--
|
||||||
--><a href="#!/categories">Categories</a><!--
|
--><a href="#!/categories">Categories</a><!--
|
||||||
--><a href="#!/subcategories">Subcategories</a><!--
|
--><a href="#!/subcategories">Subcategories</a><!--
|
||||||
--><a href="#!/items">Items</a><!--
|
--><a href="#!/items">Items</a><!--
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
<th data-key-name="subcategory">Subcategory</th>
|
<th data-key-name="subcategory">Subcategory</th>
|
||||||
<th data-key-name="defaultPrice">Default Price</th>
|
<th data-key-name="defaultPrice">Default Price</th>
|
||||||
<th data-key-name="measures">Measures</th>
|
<th data-key-name="measures">Measures</th>
|
||||||
|
<th data-key-name="aliases">Aliases</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
@@ -54,6 +55,12 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<select class="js-states form-control" name="measures" id="DFMeasures" multiple="multiple" tabindex="0" style="width: 100%;" required></select>
|
<select class="js-states form-control" name="measures" id="DFMeasures" multiple="multiple" tabindex="0" style="width: 100%;" required></select>
|
||||||
</div>
|
</div>
|
||||||
|
<label for="DFNewAlias">Aliases</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<input name="newAlias" id="DFNewAlias" type="text" class="form-control text" tabindex="0"><span class="input-group-btn"><button id="DFNewAliasAdd" class="btn" type="button">Add</button></span>
|
||||||
|
</div>
|
||||||
|
<div id="DFAliases" class="list-group" tabindex="0">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button id="DFSave" type="button" class="btn btn-default btn-primary btn-md" tabindex="0">Save</button>
|
<button id="DFSave" type="button" class="btn btn-default btn-primary btn-md" tabindex="0">Save</button>
|
||||||
@@ -127,9 +134,6 @@
|
|||||||
return map;
|
return map;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
//Save the categories by id for use when setting the editor dialog's dropdown selection.
|
|
||||||
categoriesById = byId;
|
|
||||||
|
|
||||||
return byId;
|
return byId;
|
||||||
}},
|
}},
|
||||||
{name: "subcategories", url: "data/Subcategory/readAll", parameters: {showDeleted: true}, postProcess: function(data) {
|
{name: "subcategories", url: "data/Subcategory/readAll", parameters: {showDeleted: true}, postProcess: function(data) {
|
||||||
@@ -141,9 +145,6 @@
|
|||||||
return map;
|
return map;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
//Save the categories by id for use when setting the editor dialog's dropdown selection.
|
|
||||||
subcategoriesById = byId;
|
|
||||||
|
|
||||||
return byId;
|
return byId;
|
||||||
}}
|
}}
|
||||||
],
|
],
|
||||||
@@ -202,7 +203,10 @@
|
|||||||
var $editorDialog = $page.find('#editorDialog');
|
var $editorDialog = $page.find('#editorDialog');
|
||||||
var $deleteDialog = $page.find('#deleteDialog');
|
var $deleteDialog = $page.find('#deleteDialog');
|
||||||
var $editorForm = $editorDialog.find('form');
|
var $editorForm = $editorDialog.find('form');
|
||||||
var queries = [$.get("data/Category/readAll", {include: [{model: 'Subcategory', paranoid: true, as: 'subcategories'}], order: ['name', ['name']]}), $.get('data/Measure/readAll', {order: ['name']})];
|
var queries = [
|
||||||
|
$.get("data/Category/readAll", {request: JSON.stringify({paranoid: true, include: [{model: 'Subcategory', paranoid: true, as: 'subcategories'}], order: ['name', ['name']]})}),
|
||||||
|
$.get('data/Measure/readAll', {request: JSON.stringify({paranoid: true, order: ['name']})})
|
||||||
|
];
|
||||||
|
|
||||||
//Update the dialog drop downs when the queries finish.
|
//Update the dialog drop downs when the queries finish.
|
||||||
$.when.apply($, queries).then(function(query1, query2) {
|
$.when.apply($, queries).then(function(query1, query2) {
|
||||||
@@ -241,6 +245,14 @@
|
|||||||
// $('#createDialog form').find('*').on('focusout focus change input', function(event) {
|
// $('#createDialog form').find('*').on('focusout focus change input', function(event) {
|
||||||
// console.log("Event [" + event.type + "] on " + event.target + (event.target.name ? "." + event.target.name : event.target.id ? "." + event.target.id : "") + "{" + event.target.classList + "}");
|
// console.log("Event [" + event.type + "] on " + event.target + (event.target.name ? "." + event.target.name : event.target.id ? "." + event.target.id : "") + "{" + event.target.classList + "}");
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
$editorForm.find('#DFMeasures').on('select2:select', function(event) {
|
||||||
|
var $el = $(event.params.data.element);
|
||||||
|
|
||||||
|
$el.detach();
|
||||||
|
$(this).append($el);
|
||||||
|
$(this).trigger("change");
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
//Handle opening the create dialog.
|
//Handle opening the create dialog.
|
||||||
@@ -259,15 +271,28 @@
|
|||||||
$btnEdit.on("click", function(event) {
|
$btnEdit.on("click", function(event) {
|
||||||
//debugger;
|
//debugger;
|
||||||
if(dataTable.getSelectedRow() != null) {
|
if(dataTable.getSelectedRow() != null) {
|
||||||
|
var model = dataTable.getSelectedRow().data("model");
|
||||||
|
|
||||||
//Configure the dialog to edit an existing element.
|
//Configure the dialog to edit an existing element.
|
||||||
$editorDialog.find("#DFCreate, #DFCreatePlus").hide();
|
$editorDialog.find("#DFCreate, #DFCreatePlus").hide();
|
||||||
$editorDialog.find("#DFSave").show();
|
$editorDialog.find("#DFSave").show();
|
||||||
$editorDialog.find(".modal-title").text("Edit Item");
|
$editorDialog.find(".modal-title").text("Edit Item");
|
||||||
//Reset fields to selected values.
|
//Reset fields to selected values.
|
||||||
$editorDialog.find('#DFName').val(dataTable.getSelectedRow().data("model").name);
|
$editorDialog.find('#DFName').val(model.name);
|
||||||
$editorDialog.find('#DFSubcategory').val(dataTable.getSelectedRow().data("model").subcategoryId);
|
$editorDialog.find('#DFSubcategory').val(model.subcategoryId);
|
||||||
$editorDialog.find('#DFPrice').val(dataTable.getSelectedRow().data("model").defaultPrice);
|
$editorDialog.find('#DFPrice').val(model.defaultPrice);
|
||||||
$editorDialog.find('#DFMeasures').val(dataTable.getSelectedRow().data("model").measures);
|
$editorDialog.find('#DFMeasures').val(model.measures);
|
||||||
|
|
||||||
|
if(model.aliases && model.aliases.length) {
|
||||||
|
var $aliasesList = $editorDialog.find('DFAliases');
|
||||||
|
|
||||||
|
for(var a = 0; a < model.aliases.length; a++) {
|
||||||
|
var alias = model.aliases[a];
|
||||||
|
$aliasesList.append("<li>" + alias + "</li>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Open the dialog.
|
//Open the dialog.
|
||||||
$editorDialog.modal();
|
$editorDialog.modal();
|
||||||
}
|
}
|
||||||
@@ -277,24 +302,17 @@
|
|||||||
var createFunction = function(close) {
|
var createFunction = function(close) {
|
||||||
$editorForm.data('bs.validator').validate(function(isValid) {
|
$editorForm.data('bs.validator').validate(function(isValid) {
|
||||||
if(isValid) {
|
if(isValid) {
|
||||||
try {
|
$.ajax({url: "data/Item/create", type: "POST", dataType: "json", data: encodeData({
|
||||||
$.post("data/Item/create", {
|
name: $editorForm.find("#DFName").val(),
|
||||||
name: $editorForm.find("#DFName").val(),
|
subcategoryId: parseInt($editorForm.find("#DFSubcategory").val()),
|
||||||
subcategoryId: parseInt($editorForm.find("#DFSubcategory").val()),
|
defaultPrice: $editorForm.find("#DFPrice").val(),
|
||||||
defaultPrice: $editorForm.find("#DFPrice").val(),
|
measures: JSON.stringify($editorForm.find("#DFMeasures").val())
|
||||||
measures: JSON.stringify($editorForm.find("#DFMeasures").val())
|
})}).done(function(data) {
|
||||||
}, function(data) {
|
if(close) $editorDialog.modal("hide");
|
||||||
if(data.result == "success") {
|
dataTable.refresh();
|
||||||
if(close) $editorDialog.modal("hide");
|
}).fail(function(data) {
|
||||||
dataTable.refresh();
|
alert("Server call failed.");
|
||||||
}
|
});
|
||||||
else {
|
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
} catch(e) {
|
|
||||||
alert(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -308,31 +326,82 @@
|
|||||||
$editorDialog.find('#DFSave').on('click', function(event) {
|
$editorDialog.find('#DFSave').on('click', function(event) {
|
||||||
$editorForm.data('bs.validator').validate(function(isValid) {
|
$editorForm.data('bs.validator').validate(function(isValid) {
|
||||||
if(isValid) {
|
if(isValid) {
|
||||||
try {
|
$.ajax({url: "data/Item/edit", type: "POST", dataType: "json", data: encodeData({
|
||||||
$.post("data/Item/edit", {
|
id: dataTable.getSelectedRow().data("model").id,
|
||||||
id: dataTable.getSelectedRow().data("model").id,
|
name: $editorForm.find("#DFName").val(),
|
||||||
name: $editorForm.find("#DFName").val(),
|
subcategoryId: parseInt($editorForm.find("#DFSubcategory").val()),
|
||||||
subcategoryId: parseInt($editorForm.find("#DFSubcategory").val()),
|
defaultPrice: $editorForm.find("#DFPrice").val(),
|
||||||
defaultPrice: $editorForm.find("#DFPrice").val(),
|
measures: JSON.stringify($editorForm.find("#DFMeasures").val())
|
||||||
measures: JSON.stringify($editorForm.find("#DFMeasures").val())
|
})}).done(function(data) {
|
||||||
}, function(data) {
|
if(close) $editorDialog.modal("hide");
|
||||||
if(data.result == "success") {
|
dataTable.refresh();
|
||||||
$editorDialog.modal("hide");
|
}).fail(function(data) {
|
||||||
dataTable.refresh();
|
alert("Server call failed.");
|
||||||
}
|
});
|
||||||
else {
|
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
} catch(e) {
|
|
||||||
alert(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$editorDialog.find('#DFCancel').on('click', function(event) {
|
$editorDialog.find('#DFCancel').on('click', function(event) {
|
||||||
$editorDialog.modal('hide');
|
$editorDialog.modal('hide');
|
||||||
});
|
});
|
||||||
|
//Add a new alias to the alias list.
|
||||||
|
$editorDialog.find('#DFNewAliasAdd').on('click', function(event) {
|
||||||
|
//Add the text in the DFNewAlias input as an alias in the list.
|
||||||
|
var $aliasInput = $editorDialog.find('#DFNewAlias');
|
||||||
|
var text = $aliasInput.val();
|
||||||
|
|
||||||
|
if(text) text = text.trim();
|
||||||
|
|
||||||
|
if(text && text.length) {
|
||||||
|
var $aliases = $editorDialog.find('#DFAliases');
|
||||||
|
|
||||||
|
$("<span>", {
|
||||||
|
roll: 'button',
|
||||||
|
tabindex: '0',
|
||||||
|
text: text
|
||||||
|
}).appendTo($aliases);
|
||||||
|
|
||||||
|
$aliasInput.val("");
|
||||||
|
}
|
||||||
|
|
||||||
|
$editorDialog.find('#DFNewAlias').focus();
|
||||||
|
});
|
||||||
|
//When the alias list is focused, select the first alias if none was previously selected.
|
||||||
|
$editorDialog.find('#DFAliases').on('focus', function(event) {
|
||||||
|
var $selected = $(event.target).children('.selected');
|
||||||
|
|
||||||
|
//If there isn't a selected list element, then select the first.
|
||||||
|
if(!$selected.length) {
|
||||||
|
$(event.target).children(':first').addClass('selected');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//Allow navigation of the selection with arrow keys, allow deletion with the delete key.
|
||||||
|
$editorDialog.find('#DFAliases').on('keyup', function(event) {
|
||||||
|
switch(event.keyCode) {
|
||||||
|
case 46:
|
||||||
|
var $selected = $(event.target).children('.selected');
|
||||||
|
|
||||||
|
$selected.prev().addClass('selected').siblings().removeClass('selected');
|
||||||
|
$selected.remove();
|
||||||
|
break;
|
||||||
|
case 38:
|
||||||
|
var $selected = $(event.target).children('.selected');
|
||||||
|
var $nextSelected = $selected.length ? $selected.prev().length ? $selected.prev() : $(event.target).children(':last') : $(event.target).children(':first');
|
||||||
|
|
||||||
|
$nextSelected.addClass('selected').siblings().removeClass('selected');
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
var $selected = $(event.target).children('.selected');
|
||||||
|
var $nextSelected = $selected.length ? $selected.next().length ? $selected.next() : $(event.target).children(':first') : $(event.target).children(':first');
|
||||||
|
|
||||||
|
$nextSelected.addClass('selected').siblings().removeClass('selected');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//Allow the user to click to select an alias.
|
||||||
|
$editorDialog.find('#DFAliases').on('click', 'span', function(event) {
|
||||||
|
$(event.target).addClass('selected').siblings().removeClass('selected');
|
||||||
|
});
|
||||||
//Set the initial focus control.
|
//Set the initial focus control.
|
||||||
$editorDialog.on('shown.bs.modal', function() {
|
$editorDialog.on('shown.bs.modal', function() {
|
||||||
$editorDialog.find('#DFName').focus();
|
$editorDialog.find('#DFName').focus();
|
||||||
@@ -352,15 +421,12 @@
|
|||||||
//Delete the element and close the dialog.
|
//Delete the element and close the dialog.
|
||||||
$deleteDialog.find('#deleteButton').on("click", function(event) {
|
$deleteDialog.find('#deleteButton').on("click", function(event) {
|
||||||
if(dataTable.getSelectedRow() != null) {
|
if(dataTable.getSelectedRow() != null) {
|
||||||
$.post("data/Item/delete", {where: {id: dataTable.getSelectedRow().data("model").id}}, function(data) {
|
$.ajax({url: "data/Item/delete", type: "POST", dataType: "json", data: encodeData({where: {id: dataTable.getSelectedRow().data("model").id}})}).done(function(data) {
|
||||||
if(data.result == "success") {
|
$deleteDialog.modal("hide");
|
||||||
$deleteDialog.modal("hide");
|
dataTable.refresh();
|
||||||
dataTable.refresh();
|
}).fail(function(data) {
|
||||||
}
|
alert("Server call failed.");
|
||||||
else {
|
});
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$deleteDialog.find('#DFCancelDelete').on('click', function(event) {
|
$deleteDialog.find('#DFCancelDelete').on('click', function(event) {
|
||||||
|
|||||||
@@ -1,2 +1,18 @@
|
|||||||
#items {
|
#items {
|
||||||
|
#DFAliases {
|
||||||
|
width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
overflow: scroll;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
font-size: 1.5em;
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.selected {
|
||||||
|
background-color: rgba(255, 248, 131, 0.51);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
var LinkedTreeTable;
|
|
||||||
|
|
||||||
+function($) {
|
|
||||||
//Pass an element (jquery or html reference), an options object (see DEFAULTS), and an array of node metadata objects (see NODE_DEFAULTS).
|
|
||||||
LinkedTreeTable = function(element, options, nodeMetadata) {
|
|
||||||
var _this = this;
|
|
||||||
this.$element = $(element);
|
|
||||||
this.options = $.extend({}, LinkedTreeTable.DEFAULTS, options);
|
|
||||||
this.nodes = [];
|
|
||||||
this.$selectedRow = null;
|
|
||||||
this.selectionHandler = function(event) {
|
|
||||||
$(this).addClass(_this.options.selectionCSS).siblings().removeClass(_this.options.selectionCSS);
|
|
||||||
_this.$selectedRow = $(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.addNodeMetadata = function(nodeMetadata) {
|
|
||||||
nodeMetadata = $.extend({}, LinkedTreeTable.NODE_DEFAULTS, nodeMetadata);
|
|
||||||
var nodes = this.nodes[nodeMetadata.type];
|
|
||||||
|
|
||||||
nodeMetadata.cls = "NODE";
|
|
||||||
|
|
||||||
if(typeof nodes == 'object') {
|
|
||||||
if(nodes.cls == 'NODE') {
|
|
||||||
this.nodes[nodeMetadata.type] = [nodes, nodeMetadata];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nodes.push(nodeMetadata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.nodes[nodeMetadata.type] = nodeMetadata
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//Add the node metadata to the mapping.
|
|
||||||
for(var index = 0; index < nodeMetadata.length; index++) {
|
|
||||||
this.addNodeMetadata(nodeMetadata[index]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
LinkedTreeTable.DEFAULTS = {
|
|
||||||
dataAttr: 'data-key-name', //The property name to use to attach the model sent by the server to the table row created for the data.
|
|
||||||
typeAttr: 'data-type-name', //The attribute name used to attach the type to the table row.
|
|
||||||
selectionCSS: 'selected',
|
|
||||||
selection: 'row', //Currently only row is supported.
|
|
||||||
getIdHandler: null //Optional global function that gets the id for an object. No ID will be used if not provided, in which case the row will not be re-opened or re-selected after refreshing the data from the server.
|
|
||||||
};
|
|
||||||
|
|
||||||
LinkedTreeTable.NODE_DEFAULTS = {
|
|
||||||
type: '', //The type name this node metadata applies to. Must be provided. The empty type is used to identify the metadata for collecting root nodes.
|
|
||||||
url: '', //The absolute or relative path to use to query the initial data. Server is expected to respond with a JSON array of objects.
|
|
||||||
typeHandler: null, //The optional handler called to determine the type for the model sent by the server. Must return a type name that is then matched to the node metadata to get children.
|
|
||||||
defaultType: null, //The default type to assign to the node if the type handler does not provide one. This normally should be set, particularly if a handler won't always provide a type.
|
|
||||||
postAddRowHandler: null, //Optional function that is passed the jquery table row and the data object sent by the server for that row. Allows post processing of the row prior to display.
|
|
||||||
parameters: null, //Optional function that returns an object, or an object whose attributes are passed to the URL as parameters.
|
|
||||||
getIdHandler: null //Optional function that gets the id for an object. The global version will be used if this one is not provided.
|
|
||||||
};
|
|
||||||
|
|
||||||
LinkedTreeTable.prototype.getSelectedRow = function() {
|
|
||||||
return this.$selectedRow;
|
|
||||||
};
|
|
||||||
|
|
||||||
//A function that will clean and rebuild the table displaying all the users.
|
|
||||||
//Note that each row of the table will have a data element attached to the table row. The key will be "model" and the value will be the object sent by the server.
|
|
||||||
//Pass an optional table row or data object to reference a node in the tree whose children will be refreshed. If not provided then the root nodes will be refreshed.
|
|
||||||
LinkedTreeTable.prototype.refresh = function(node) {
|
|
||||||
var _this = this;
|
|
||||||
var table = this.$element;
|
|
||||||
var thead = table.find("thead tr");
|
|
||||||
var tbody = table.find("tbody");
|
|
||||||
var selection = this.options.selection;
|
|
||||||
var dataAttr = this.options.dataAttr;
|
|
||||||
var selectionHandler = this.selectionHandler;
|
|
||||||
var params;
|
|
||||||
|
|
||||||
//TODO: Need to identify the top most visible row?
|
|
||||||
//TODO: Otherwise identify the scroll position so we can reset it if necessary?
|
|
||||||
//TODO: Find the ID's of all rows at this tree level or lower that are open so we can re-open them after refreshing?
|
|
||||||
//TODO: Otherwise map the new data by ID to the rows at this tree level so we can update the rows instead of replacing them?
|
|
||||||
|
|
||||||
if(thead.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Empty or Create the table body.
|
|
||||||
if(tbody.length != 0) {
|
|
||||||
//Remove the row selection handler.
|
|
||||||
if(selection == 'row') this.$element.off('click', 'tbody tr', selectionHandler);
|
|
||||||
//Empty the table of data.
|
|
||||||
tbody.empty();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tbody = $("<tbody></tbody>");
|
|
||||||
tbody.appendTo(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(typeof this.options.parameters == 'function') {
|
|
||||||
params = this.options.parameters();
|
|
||||||
|
|
||||||
//Must be an object.
|
|
||||||
if(typeof params != 'object') {
|
|
||||||
params = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(typeof this.options.parameters == 'object') {
|
|
||||||
params = this.options.parameters;
|
|
||||||
}
|
|
||||||
else {params = {};}
|
|
||||||
|
|
||||||
$.getJSON(this.options.url, params, function(data) {
|
|
||||||
var headers = thead.children();
|
|
||||||
var attributes = [];
|
|
||||||
|
|
||||||
//Read the table headers to get the data object keys.
|
|
||||||
for(var headerIndex = 0; headerIndex < headers.length; headerIndex++) {
|
|
||||||
var nextHeader = headers[headerIndex];
|
|
||||||
|
|
||||||
attributes[headerIndex] = $(nextHeader).attr(dataAttr);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Add the table data.
|
|
||||||
for(var dataIndex = 0; dataIndex < data.length; dataIndex++) {
|
|
||||||
var rowData = data[dataIndex];
|
|
||||||
var row = $("<tr></tr>");
|
|
||||||
|
|
||||||
row.appendTo(tbody);
|
|
||||||
//Save the model attached to the table row. Can be retrieved later to get the model sent by the server.
|
|
||||||
row.data("model", rowData);
|
|
||||||
|
|
||||||
for(var attributeIndex = 0; attributeIndex < attributes.length; attributeIndex++) {
|
|
||||||
var attribute = attributes[attributeIndex];
|
|
||||||
var cellData = rowData[attribute];
|
|
||||||
|
|
||||||
row.append("<td>" + cellData + "</td>");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_this.options.postAddRowHandler) {
|
|
||||||
//Call the optional handler after adding the row, passing the jquery row object, and the row data object sent by the server. Allows post processing on the row (adding classes to the row for example).
|
|
||||||
_this.options.postAddRowHandler(row, rowData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Setup the row selection handler.
|
|
||||||
if(selection == 'row') table.on('click', 'tbody tr', selectionHandler);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}(jQuery);
|
|
||||||
2623
public/admin/js/bootstrap-datetimepicker.js
vendored
Normal file
2623
public/admin/js/bootstrap-datetimepicker.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
217
public/admin/js/bootstrap-datetimepicker.min.js
vendored
Normal file
217
public/admin/js/bootstrap-datetimepicker.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -9,28 +9,194 @@ var LinkedTable;
|
|||||||
this.options = $.extend({}, LinkedTable.DEFAULTS, options);
|
this.options = $.extend({}, LinkedTable.DEFAULTS, options);
|
||||||
this.$selectedRow = null;
|
this.$selectedRow = null;
|
||||||
this.selectionHandler = function(event) {
|
this.selectionHandler = function(event) {
|
||||||
$(this).addClass(_this.options.selectionCSS).siblings().removeClass(_this.options.selectionCSS);
|
if(this) {
|
||||||
_this.$selectedRow = $(this);
|
$(this).addClass(_this.options.selectionCSS).siblings().removeClass(_this.options.selectionCSS);
|
||||||
|
_this.$selectedRow = $(this);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_this.$element.find('tr').removeClass(_this.options.selectionCSS);
|
||||||
|
_this.$selectedRow = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Note: We are not currently using events for the selection handling since it is really not necessary. Instead we are using a handler provided by the app code when the table is initialized.
|
||||||
//Create a selection event indicating the table has changed its selection.
|
//Create a selection event indicating the table has changed its selection.
|
||||||
//var e = $.Event('selection.linkedtable', {relatedTarget: _this.$element[0]});
|
//var e = $.Event('selection.linkedtable', {relatedTarget: _this.$element[0]});
|
||||||
//Fire the event.
|
//Fire the event.
|
||||||
//_this.$element.trigger(e);
|
//_this.$element.trigger(e);
|
||||||
|
|
||||||
if(_this.options.selectionChanged) {
|
if(_this.options.selectionChanged) {
|
||||||
_this.options.selectionChanged(_this.$selectedRow, _this.$selectedRow.data("model"));
|
//Notify the handler of the new selection, and the selection's model.
|
||||||
|
_this.options.selectionChanged(_this.$selectedRow, _this.$selectedRow ? _this.$selectedRow.data(_this.options.modelPropName) : null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//Takes a callback function with three parameters:
|
||||||
|
// data: The array of model data returned by the server.
|
||||||
|
// attributes: The array of attributes in column order, one per column.
|
||||||
|
// supportingData: The map of additional data (array of model objects) returned by the server for each supporting query, indexed by the name given to the query when the table was created.
|
||||||
|
this.load = function(callback) {
|
||||||
|
var supportingData = {};
|
||||||
|
var deferreds = [];
|
||||||
|
var params;
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
//Build the parameters for the query for the primary set of data.
|
||||||
|
if(typeof this.options.parameters == 'function') {
|
||||||
|
params = this.options.parameters();
|
||||||
|
|
||||||
|
//Must be an object.
|
||||||
|
if(typeof params != 'object') {
|
||||||
|
params = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(typeof this.options.parameters == 'object') {
|
||||||
|
params = this.options.parameters;
|
||||||
|
}
|
||||||
|
else {params = {};}
|
||||||
|
|
||||||
|
//Load the primary set of data.
|
||||||
|
deferreds.push($.post(this.options.url, params ? {request: JSON.stringify(params)} : {}, 'json'));
|
||||||
|
//deferreds.push($.post({url: this.options.url, data: {request: JSON.stringify(params)}, dataType: 'json', contentType: 'application/json; charset=utf-8'}));
|
||||||
|
//deferreds.push($.ajax({type: 'POST', url: this.options.url, data: {request: JSON.stringify(params)}, dataType: 'json'}));
|
||||||
|
|
||||||
|
//Load all supporting data.
|
||||||
|
for(var supportingDataIndex = 0; supportingDataIndex < this.options.supportingData.length; supportingDataIndex++) {
|
||||||
|
var nextSupportingData = this.options.supportingData[supportingDataIndex];
|
||||||
|
|
||||||
|
//Build the parameters for each supporting set of data.
|
||||||
|
if(typeof nextSupportingData.parameters == 'function') {
|
||||||
|
params = nextSupportingData.parameters();
|
||||||
|
|
||||||
|
//Must be an object.
|
||||||
|
if(typeof params != 'object') {
|
||||||
|
params = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(typeof nextSupportingData.parameters == 'object') {
|
||||||
|
params = nextSupportingData.parameters;
|
||||||
|
}
|
||||||
|
else {params = {};}
|
||||||
|
|
||||||
|
//Load the supporting data.
|
||||||
|
deferreds.push($.post(nextSupportingData.url, {request: JSON.stringify(params)}, 'json'));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Use apply to convert an array of parameters to individual parameters for the $.when(..) function. The success function will receive the results in order passed to when().
|
||||||
|
$.when.apply($, deferreds).then(function() {
|
||||||
|
//Note: If there is only one query, then the argument array contains the results for the one query, otherwise the argument array is an array of result arrays, one for each query.
|
||||||
|
var data = (deferreds.length > 1 ? arguments[0][0] : arguments[0]); //Note: For multiple queries, the result of the first query returns an array of three values: the data (array in this case), the message, and XHR object. We only care about the data.
|
||||||
|
|
||||||
|
if(deferreds.length > 1) {
|
||||||
|
//Save each supporting set of data by name into the supportingData object.
|
||||||
|
for(var argumentIndex = 1; argumentIndex < arguments.length; argumentIndex++) {
|
||||||
|
var supportingResult = arguments[argumentIndex][0]; //We only care about the data. The other two array elements are the status and the XHR object.
|
||||||
|
|
||||||
|
if(_this.options.supportingData[argumentIndex - 1].postProcess) {
|
||||||
|
supportingResult = _this.options.supportingData[argumentIndex - 1].postProcess(supportingResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
supportingData[_this.options.supportingData[argumentIndex - 1].name] = supportingResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callback.call(_this, data, _this.collectAttributes.call(_this), supportingData);
|
||||||
|
}).fail(function(err) {
|
||||||
|
console.error("Unexpected error loading the table data?!? " + err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
//Collects the set of attributes to display, one per column, in column order.
|
||||||
|
this.collectAttributes = function() {
|
||||||
|
var table = this.$element;
|
||||||
|
var thead = table.find("thead tr");
|
||||||
|
var headers = thead.children();
|
||||||
|
var attributes = [];
|
||||||
|
var attrName = this.options.attr;
|
||||||
|
|
||||||
|
//Read the table headers to get the data object keys.
|
||||||
|
for(var headerIndex = 0; headerIndex < headers.length; headerIndex++) {
|
||||||
|
var nextHeader = headers[headerIndex];
|
||||||
|
|
||||||
|
attributes[headerIndex] = $(nextHeader).attr(attrName);
|
||||||
|
|
||||||
|
//Replace the attribute name with the handler function if there is one in the mapping.
|
||||||
|
if(this.options.cellDataHandlers[attributes[headerIndex]]) {
|
||||||
|
attributes[headerIndex] = this.options.cellDataHandlers[attributes[headerIndex]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Creates a new row in the table. Returns the row created. Does NOT attach the row to the table.
|
||||||
|
this.createRow = function(model, attributes, supportingData) {
|
||||||
|
var row = $("<tr></tr>");
|
||||||
|
|
||||||
|
//Save the model attached to the table row. Can be retrieved later to get the model sent by the server.
|
||||||
|
row.data(this.options.modelPropName, model);
|
||||||
|
|
||||||
|
for(var attributeIndex = 0; attributeIndex < attributes.length; attributeIndex++) {
|
||||||
|
var attribute = attributes[attributeIndex];
|
||||||
|
var $cell = $("<td></td>");
|
||||||
|
|
||||||
|
//Fill in the cell's data.
|
||||||
|
this.updateCell($cell, attribute, model, supportingData);
|
||||||
|
//Add the cell to the row.
|
||||||
|
$cell.appendTo(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.options.postAddRowHandler) {
|
||||||
|
//Call the optional handler after adding the row, passing the jquery row object, and the row data object sent by the server. Allows post processing on the row (adding classes to the row for example).
|
||||||
|
this.options.postAddRowHandler(row, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
return row;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.updateRow = function($row, model, attributes, supportingData) {
|
||||||
|
var $cells = $row.children("td");
|
||||||
|
|
||||||
|
//Attach the new model to the row.
|
||||||
|
$row.data(this.options.modelPropName, model);
|
||||||
|
|
||||||
|
//Iterate over the cell data elements and update their values.
|
||||||
|
for(var cellIndex = 0; cellIndex < $cells.length; cellIndex++) {
|
||||||
|
var $cell = $($cells[cellIndex]);
|
||||||
|
|
||||||
|
//Note: There should be exactly one attribute for each cell in the row.
|
||||||
|
this.updateCell($cell, attributes[cellIndex], model, supportingData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.options.postUpdateRowHandler) {
|
||||||
|
//Call the optional handler after adding the row, passing the jquery row object, and the row data object sent by the server. Allows post processing on the row (adding classes to the row for example).
|
||||||
|
this.options.postUpdateRowHandler($row, model);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//Initializes or updates the cell with data from the model.
|
||||||
|
//The attribute can either be an attribute of the model, or a function that takes ($cell, model, supportingData) and returns nothing.
|
||||||
|
this.updateCell = function($cell, attribute, model, supportingData) {
|
||||||
|
if($.isFunction(attribute)) {
|
||||||
|
attribute($cell, model, supportingData);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$cell.text(model[attribute]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
LinkedTable.DEFAULTS = {
|
LinkedTable.DEFAULTS = {
|
||||||
url: '', //The absolute or relative path to use to query the data. Server is expected to respond with a JSON array of objects.
|
url: '', //The absolute or relative path to use to query the data. Server is expected to respond with a JSON array of objects.
|
||||||
attr: 'data-key-name',
|
attr: 'data-key-name', //The attribute name used by the HTML <th></th> tags to specify either the model attribute used to fill the cells for the row, or the function that will update the cell data. The function should take three parameters: $cell, model, supportingData. $cell is the jquery wrapped <td></td> element. Model is the json model sent by the server for this row. SupportingData is a map of query results for supporting queries as setup when defining the table.
|
||||||
|
modelPropName: 'model', //The property name to use when attaching the model to the table row. Not normally changed.
|
||||||
|
idAttr: 'id', //The id attribute for model objects. All model objects must have an id attribute that is unique for the model. TODO: Add the possibility of a function that might generate an id from other attributes of the model.
|
||||||
selectionCSS: 'selected',
|
selectionCSS: 'selected',
|
||||||
selection: 'row', //Currently only row is supported.
|
selection: 'row', //Currently only row is supported.
|
||||||
selectionChanged: undefined, //An optional handler called when the selection changes, and passed the selected element (jquery wrapper for the table row 'tr' HTML element currently selected), and the model associated with the row.
|
selectionChanged: undefined, //An optional handler called when the selection changes, and passed the selected element (jquery wrapper for the table row 'tr' HTML element currently selected), and the model associated with the row.
|
||||||
supportingData: [], //An array of objects, one for each collection of supporting data. Each object must have a 'name', 'url', and optional 'parameters'. The url and parameters are used the same as for the primary query. The name is used to store the results for use in rendering the data. Optional 'postProcess' attribute can be a function that takes the data and returns a modified set of data.
|
supportingData: [], //An array of objects, one for each collection of supporting data. Each object must have a 'name', 'url', and optional 'parameters'. The url and parameters are used the same as for the primary query. The name is used to store the results for use in rendering the data. Optional 'postProcess' attribute can be a function that takes the data and returns a modified set of data.
|
||||||
cellDataHandlers: {}, //An object containing a function for each attribute, where the attribute is the table header object key, and the function is called to convert the primary data object into a cell value. The function will be passed the jquery table data wrapper object for the cell, the primary data object for the row, and the object containing the supporting data returned from running the supporting data queries.
|
cellDataHandlers: {}, //An object containing a function for each attribute, where the attribute is the table header object key, and the function is called to convert the primary data object into a cell value. The function will be passed the jquery table data wrapper object for the cell, the primary data object for the row, and the object containing the supporting data returned from running the supporting data queries.
|
||||||
postAddRowHandler: null, //Optional function that is passed the jquery table row and the data object sent by the server for that row. Allows post processing of the row prior to display.
|
postAddRowHandler: null, //Optional function that is passed the jquery table row and the data object sent by the server for that row. Allows post processing of the row prior to display.
|
||||||
|
postUpdateRowHandler: null, //Optional function that works just like the postAddRowHandler, but is called when a row is updated. This may be the same function as the postRowAddHandler, or not if so desired.
|
||||||
parameters: null //Optional function that returns an object, or an object whose attributes are passed to the URL as parameters.
|
parameters: null //Optional function that returns an object, or an object whose attributes are passed to the URL as parameters.
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -38,19 +204,65 @@ var LinkedTable;
|
|||||||
return this.$selectedRow;
|
return this.$selectedRow;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Refreshes the table data with updated server data. Does not clear the table or rebuild it.
|
||||||
|
LinkedTable.prototype.refresh = function() {
|
||||||
|
//Load the results from the server, then build the table.
|
||||||
|
this.load.call(this, function(data, attributes, supportingData) {
|
||||||
|
var $table = this.$element;
|
||||||
|
var $tbody = $table.find("tbody");
|
||||||
|
var $rows = $tbody.children("tr");
|
||||||
|
var idAttr = this.options.idAttr;
|
||||||
|
//Create a map of model objects by id.
|
||||||
|
var dataMap = data.reduce(function(map, obj) {
|
||||||
|
map[obj[idAttr]] = obj;
|
||||||
|
return map;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
//Iterate over the existing table rows. Find those that have objects in the map and update them. Delete those not in the map. Remove objects from the map as we go.
|
||||||
|
for(var rowIndex = 0; rowIndex < $rows.length; rowIndex++) {
|
||||||
|
var $row = $($rows[rowIndex]);
|
||||||
|
var oldModel = $row.data(this.options.modelPropName);
|
||||||
|
var newModel = dataMap[oldModel[this.options.idAttr]];
|
||||||
|
|
||||||
|
if(newModel) {
|
||||||
|
//Update the table row.
|
||||||
|
this.updateRow($row, newModel, attributes, supportingData);
|
||||||
|
//Remove the model from the map so we know we have already updated its row in the table.
|
||||||
|
delete dataMap[oldModel[this.options.idAttr]];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//Clear the selection if the row is removed.
|
||||||
|
if(this.$selectedRow && $row.is(this.$selectedRow)) {
|
||||||
|
//Clear the selection.
|
||||||
|
this.selectionHandler.call(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove the row from the table.
|
||||||
|
$row.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var keys = Object.keys(dataMap);
|
||||||
|
|
||||||
|
//Add all objects left in the map to the table as new rows.
|
||||||
|
for(var keyIndex = 0; keyIndex < keys.length; keyIndex++) {
|
||||||
|
var key = keys[keyIndex];
|
||||||
|
var model = dataMap[key];
|
||||||
|
var $row = this.createRow(model, attributes, supportingData);
|
||||||
|
|
||||||
|
$row.appendTo($tbody);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
//A function that will clean and rebuild the table displaying all the users.
|
//A function that will clean and rebuild the table displaying all the users.
|
||||||
//Note that each row of the table will have a data element attached to the table row. The key will be "model" and the value will be the object sent by the server.
|
//Note that each row of the table will have a data element attached to the table row. The key will be "model" and the value will be the object sent by the server.
|
||||||
LinkedTable.prototype.refresh = function() {
|
LinkedTable.prototype.build = function() {
|
||||||
var _this = this;
|
|
||||||
var table = this.$element;
|
var table = this.$element;
|
||||||
var thead = table.find("thead tr");
|
var thead = table.find("thead tr");
|
||||||
var tbody = table.find("tbody");
|
var tbody = table.find("tbody");
|
||||||
var selection = this.options.selection;
|
var selection = this.options.selection;
|
||||||
var attr = this.options.attr;
|
|
||||||
var selectionHandler = this.selectionHandler;
|
var selectionHandler = this.selectionHandler;
|
||||||
var params;
|
|
||||||
var deferreds = [];
|
|
||||||
var supportingData = {};
|
|
||||||
|
|
||||||
if(thead.length == 0) {
|
if(thead.length == 0) {
|
||||||
return;
|
return;
|
||||||
@@ -68,112 +280,18 @@ var LinkedTable;
|
|||||||
tbody.appendTo(table);
|
tbody.appendTo(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Build the parameters for the query for the primary set of data.
|
//Load the results from the server, then build the table.
|
||||||
if(typeof this.options.parameters == 'function') {
|
this.load.call(this, function(data, attributes, supportingData) {
|
||||||
params = this.options.parameters();
|
|
||||||
|
|
||||||
//Must be an object.
|
|
||||||
if(typeof params != 'object') {
|
|
||||||
params = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(typeof this.options.parameters == 'object') {
|
|
||||||
params = this.options.parameters;
|
|
||||||
}
|
|
||||||
else {params = {};}
|
|
||||||
|
|
||||||
//Load the primary set of data.
|
|
||||||
deferreds.push($.post(this.options.url, params, 'json'));
|
|
||||||
|
|
||||||
//Load all supporting data.
|
|
||||||
for(var supportingDataIndex = 0; supportingDataIndex < this.options.supportingData.length; supportingDataIndex++) {
|
|
||||||
var nextSupportingData = this.options.supportingData[supportingDataIndex];
|
|
||||||
|
|
||||||
//Build the parameters for each supporting set of data.
|
|
||||||
if(typeof nextSupportingData.parameters == 'function') {
|
|
||||||
params = nextSupportingData.parameters();
|
|
||||||
|
|
||||||
//Must be an object.
|
|
||||||
if(typeof params != 'object') {
|
|
||||||
params = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(typeof nextSupportingData.parameters == 'object') {
|
|
||||||
params = nextSupportingData.parameters;
|
|
||||||
}
|
|
||||||
else {params = {};}
|
|
||||||
|
|
||||||
//Load the supporting data.
|
|
||||||
deferreds.push($.post(nextSupportingData.url, params, 'json'));
|
|
||||||
}
|
|
||||||
|
|
||||||
//Use apply to convert an array of parameters to individual parameters for the $.when(..) function. The success function will receive the results in order passed to when().
|
|
||||||
$.when.apply($, deferreds).then(function() {
|
|
||||||
//Note: If there is only one query, then the argument array contains the results for the one query, otherwise the argument array is an array of result arrays, one for each query.
|
|
||||||
var data = (deferreds.length > 1 ? arguments[0][0] : arguments[0]); //Note: For multiple queries, the result of the first query returns an array of three values: the data (array in this case), the message, and XHR object. We only care about the data.
|
|
||||||
var headers = thead.children();
|
|
||||||
var attributes = [];
|
|
||||||
|
|
||||||
if(deferreds.length > 1) {
|
|
||||||
//Save each supporting set of data by name into the supportingData object.
|
|
||||||
for(var argumentIndex = 1; argumentIndex < arguments.length; argumentIndex++) {
|
|
||||||
var supportingResult = arguments[argumentIndex][0]; //We only care about the data. The other two array elements are the status and the XHR object.
|
|
||||||
|
|
||||||
if(_this.options.supportingData[argumentIndex - 1].postProcess) {
|
|
||||||
supportingResult = _this.options.supportingData[argumentIndex - 1].postProcess(supportingResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
supportingData[_this.options.supportingData[argumentIndex - 1].name] = supportingResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Read the table headers to get the data object keys.
|
|
||||||
for(var headerIndex = 0; headerIndex < headers.length; headerIndex++) {
|
|
||||||
var nextHeader = headers[headerIndex];
|
|
||||||
|
|
||||||
attributes[headerIndex] = $(nextHeader).attr(attr);
|
|
||||||
|
|
||||||
//Replace the attribute name with the handler function if there is one in the mapping.
|
|
||||||
if(_this.options.cellDataHandlers[attributes[headerIndex]]) {
|
|
||||||
attributes[headerIndex] = _this.options.cellDataHandlers[attributes[headerIndex]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Add the table data.
|
//Add the table data.
|
||||||
for(var dataIndex = 0; dataIndex < data.length; dataIndex++) {
|
for(var dataIndex = 0; dataIndex < data.length; dataIndex++) {
|
||||||
var rowData = data[dataIndex];
|
var row = this.createRow.call(this, data[dataIndex], attributes, supportingData);
|
||||||
var row = $("<tr></tr>");
|
|
||||||
|
|
||||||
|
//Add the row to the end of the table.
|
||||||
row.appendTo(tbody);
|
row.appendTo(tbody);
|
||||||
//Save the model attached to the table row. Can be retrieved later to get the model sent by the server.
|
|
||||||
row.data("model", rowData);
|
|
||||||
|
|
||||||
for(var attributeIndex = 0; attributeIndex < attributes.length; attributeIndex++) {
|
|
||||||
var attribute = attributes[attributeIndex];
|
|
||||||
|
|
||||||
if($.isFunction(attribute)) {
|
|
||||||
var cell = $("<td></td>");
|
|
||||||
|
|
||||||
cell.appendTo(row);
|
|
||||||
attribute(cell, rowData, supportingData);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var cellData = rowData[attribute];
|
|
||||||
|
|
||||||
row.append("<td>" + cellData + "</td>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_this.options.postAddRowHandler) {
|
|
||||||
//Call the optional handler after adding the row, passing the jquery row object, and the row data object sent by the server. Allows post processing on the row (adding classes to the row for example).
|
|
||||||
_this.options.postAddRowHandler(row, rowData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Setup the row selection handler.
|
//Setup the row selection handler.
|
||||||
if(selection == 'row') table.on('click', 'tbody tr', selectionHandler);
|
if(selection == 'row') table.on('click', 'tbody tr', selectionHandler);
|
||||||
}).fail(function(err) {
|
|
||||||
console.error("Unexpected error loading the table data?!?");
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}(jQuery);
|
}(jQuery);
|
||||||
4040
public/admin/js/moment.js
Normal file
4040
public/admin/js/moment.js
Normal file
File diff suppressed because it is too large
Load Diff
7
public/admin/js/moment.min.js
vendored
Normal file
7
public/admin/js/moment.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
4
public/admin/js/msgpack5.min.js
vendored
4
public/admin/js/msgpack5.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -479,4 +479,5 @@ sup, sub {
|
|||||||
@require "measures"
|
@require "measures"
|
||||||
@require "categories"
|
@require "categories"
|
||||||
@require "subcategories"
|
@require "subcategories"
|
||||||
@require "items"
|
@require "items"
|
||||||
|
@require "sales"
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<!-- Main Page Content -->
|
<!-- Main Page Content -->
|
||||||
<h1><span class="fa fa-users"></span> Manage Measures</h1>
|
<h1><span class="fa fa-users"></span> Manage Measures</h1>
|
||||||
|
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-12">
|
||||||
<div class="dt-buttons btn-group" style="display: inline-block">
|
<div class="dt-buttons btn-group" style="display: inline-block">
|
||||||
<a id="createButton" class="btn btn-default buttons-create" tabindex="0" href="javaScript:void(0);"><span>New</span></a>
|
<a id="createButton" class="btn btn-default buttons-create" tabindex="0" href="javaScript:void(0);"><span>New</span></a>
|
||||||
<a id="editButton" class="btn btn-default buttons-selected buttons-edit" tabindex="0" href="javaScript:void(0);"><span>Edit</span></a>
|
<a id="editButton" class="btn btn-default buttons-selected buttons-edit" tabindex="0" href="javaScript:void(0);"><span>Edit</span></a>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Postfix</label>
|
<label>Postfix</label>
|
||||||
<input type="text" class="form-control" name="postfix" id="createDialog_PostfixField" tabindex="0">
|
<input type="text" class="form-control" name="postfix" id="DFPostfix" tabindex="0">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
@@ -79,6 +79,31 @@
|
|||||||
var $btnDelete = $page.find("#deleteButton");
|
var $btnDelete = $page.find("#deleteButton");
|
||||||
var $btnRestore = $page.find("#restoreButton");
|
var $btnRestore = $page.find("#restoreButton");
|
||||||
|
|
||||||
|
$btnEdit.disable(true);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
$btnRestore.disable(true);
|
||||||
|
|
||||||
|
var selectionChanged = function($tr, model) {
|
||||||
|
if($tr && model) {
|
||||||
|
$btnEdit.disable(false);
|
||||||
|
|
||||||
|
//If the object was deleted (hidden), then allow it to be restored, otherwise allow the model to be deleted.
|
||||||
|
if(model.deletedAt) {
|
||||||
|
$btnRestore.disable(false);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnRestore.disable(true);
|
||||||
|
$btnDelete.disable(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnEdit.disable(true);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
$btnRestore.disable(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var dataTable = new LinkedTable($page.find('#dataTable'), {
|
var dataTable = new LinkedTable($page.find('#dataTable'), {
|
||||||
url: "data/Measure/readAll",
|
url: "data/Measure/readAll",
|
||||||
attr: "data-key-name",
|
attr: "data-key-name",
|
||||||
@@ -86,35 +111,25 @@
|
|||||||
parameters: function() {
|
parameters: function() {
|
||||||
return {paranoid: !$page.find('#includeDeletedToggle').is(":checked")};
|
return {paranoid: !$page.find('#includeDeletedToggle').is(":checked")};
|
||||||
},
|
},
|
||||||
selectionChanged: function($tr, model) {
|
selectionChanged: selectionChanged,
|
||||||
if($tr && model) {
|
|
||||||
$btnEdit.show();
|
|
||||||
|
|
||||||
//If the object was deleted (hidden), then allow it to be restored, otherwise allow the model to be deleted.
|
|
||||||
if(model.deletedAt) {
|
|
||||||
$btnRestore.show();
|
|
||||||
$btnDelete.hide();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$btnRestore.hide();
|
|
||||||
$btnDelete.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$btnEdit.hide();
|
|
||||||
$btnDelete.hide();
|
|
||||||
$btnRestore.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
postAddRowHandler: function($row, dataObject) {
|
postAddRowHandler: function($row, dataObject) {
|
||||||
if(dataObject.deletedAt) {
|
if(dataObject.deletedAt) {
|
||||||
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
postUpdateRowHandler: function($row, dataObject) {
|
||||||
|
if(dataObject.deletedAt) {
|
||||||
|
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if($row.is(dataTable.getSelectedRow())) {
|
||||||
|
selectionChanged($row, dataObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Call the refresh user table function once initially.
|
//Call the refresh user table function once initially.
|
||||||
dataTable.refresh();
|
dataTable.build();
|
||||||
|
|
||||||
//Refresh the data table if the user toggles the button to show/hide deleted elements.
|
//Refresh the data table if the user toggles the button to show/hide deleted elements.
|
||||||
$page.find('#includeDeletedToggle').on('click', function(event) {
|
$page.find('#includeDeletedToggle').on('click', function(event) {
|
||||||
@@ -153,6 +168,7 @@
|
|||||||
$editorDialog.find(".modal-title").text("Create Measure");
|
$editorDialog.find(".modal-title").text("Create Measure");
|
||||||
//Reset fields to default values.
|
//Reset fields to default values.
|
||||||
$editorDialog.find("#DFName").val("");
|
$editorDialog.find("#DFName").val("");
|
||||||
|
$editorDialog.find("#DFPostfix").val("");
|
||||||
//Open the dialog.
|
//Open the dialog.
|
||||||
$editorDialog.modal();
|
$editorDialog.modal();
|
||||||
});
|
});
|
||||||
@@ -166,6 +182,7 @@
|
|||||||
$editorDialog.find(".modal-title").text("Edit Measure");
|
$editorDialog.find(".modal-title").text("Edit Measure");
|
||||||
//Reset fields to selected values.
|
//Reset fields to selected values.
|
||||||
$editorDialog.find('#DFName').val(dataTable.getSelectedRow().data("model").name);
|
$editorDialog.find('#DFName').val(dataTable.getSelectedRow().data("model").name);
|
||||||
|
$editorDialog.find('#DFPostfix').val(dataTable.getSelectedRow().data("model").postfix);
|
||||||
//Open the dialog.
|
//Open the dialog.
|
||||||
$editorDialog.modal();
|
$editorDialog.modal();
|
||||||
}
|
}
|
||||||
@@ -175,21 +192,14 @@
|
|||||||
var createFunction = function(close) {
|
var createFunction = function(close) {
|
||||||
$editorForm.data('bs.validator').validate(function(isValid) {
|
$editorForm.data('bs.validator').validate(function(isValid) {
|
||||||
if(isValid) {
|
if(isValid) {
|
||||||
try {
|
$.ajax({url: "data/Measure/create", type: "POST", dataType: "json", data: encodeData({
|
||||||
$.post("data/Measure/create", {
|
name: $editorForm.find("#DFName").val()
|
||||||
name: $editorForm.find("#DFName").val()
|
})}).done(function(data) {
|
||||||
}, function(data) {
|
if(close) $editorDialog.modal("hide");
|
||||||
if(data.result == "success") {
|
dataTable.refresh();
|
||||||
if(close) $editorDialog.modal("hide");
|
}).fail(function(data) {
|
||||||
dataTable.refresh();
|
alert("Server call failed.");
|
||||||
}
|
});
|
||||||
else {
|
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
} catch(e) {
|
|
||||||
alert(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -203,22 +213,15 @@
|
|||||||
$editorDialog.find('#DFSave').on('click', function(event) {
|
$editorDialog.find('#DFSave').on('click', function(event) {
|
||||||
$editorForm.data('bs.validator').validate(function(isValid) {
|
$editorForm.data('bs.validator').validate(function(isValid) {
|
||||||
if(isValid) {
|
if(isValid) {
|
||||||
try {
|
$.ajax({url: "data/Measure/edit", type: "POST", dataType: "json", data: encodeData({
|
||||||
$.post("data/Measure/edit", {
|
id: dataTable.getSelectedRow().data("model").id,
|
||||||
id: dataTable.getSelectedRow().data("model").id,
|
name: $editorForm.find("#DFName").val()
|
||||||
name: $editorForm.find("#DFName").val()
|
})}).done(function(data) {
|
||||||
}, function(data) {
|
if(close) $editorDialog.modal("hide");
|
||||||
if(data.result == "success") {
|
dataTable.refresh();
|
||||||
$editorDialog.modal("hide");
|
}).fail(function(data) {
|
||||||
dataTable.refresh();
|
alert("Server call failed.");
|
||||||
}
|
});
|
||||||
else {
|
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
} catch(e) {
|
|
||||||
alert(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -244,15 +247,12 @@
|
|||||||
//Delete the element and close the dialog.
|
//Delete the element and close the dialog.
|
||||||
$deleteDialog.find('#deleteButton').on("click", function(event) {
|
$deleteDialog.find('#deleteButton').on("click", function(event) {
|
||||||
if(dataTable.getSelectedRow() != null) {
|
if(dataTable.getSelectedRow() != null) {
|
||||||
$.post("data/Measure/delete", {where: {id: dataTable.getSelectedRow().data("model").id}}, function(data) {
|
$.ajax({url: "data/Measure/delete", type: "POST", dataType: "json", data: encodeData({where: {id: dataTable.getSelectedRow().data("model").id}})}).done(function(data) {
|
||||||
if(data.result == "success") {
|
$deleteDialog.modal("hide");
|
||||||
$deleteDialog.modal("hide");
|
dataTable.refresh();
|
||||||
dataTable.refresh();
|
}).fail(function(data) {
|
||||||
}
|
alert("Server call failed.");
|
||||||
else {
|
});
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$deleteDialog.find('#DFCancelDelete').on('click', function(event) {
|
$deleteDialog.find('#DFCancelDelete').on('click', function(event) {
|
||||||
|
|||||||
0
public/admin/sales.css
Normal file
0
public/admin/sales.css
Normal file
354
public/admin/sales.html
Normal file
354
public/admin/sales.html
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
<div id="sales" class="page">
|
||||||
|
<div class="col-sm-12 col-sm-offset-0">
|
||||||
|
|
||||||
|
<!-- Main Page Content -->
|
||||||
|
<h1><span class="fa fa-money"></span> Sales</h1>
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="dt-buttons btn-group" style="display: inline-block">
|
||||||
|
<a id="createButton" class="btn btn-default buttons-create" tabindex="0" href="javaScript:void(0);"><span>New</span></a>
|
||||||
|
<a id="editButton" class="btn btn-default buttons-selected buttons-edit" tabindex="0" href="javaScript:void(0);"><span>Edit</span></a>
|
||||||
|
<a id="deleteButton" class="btn btn-default buttons-selected buttons-remove" tabindex="0" href="javaScript:void(0);"><span>Delete</span></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<table id="dataTable" class="table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th data-key-name="date">Date</th>
|
||||||
|
<th data-key-name="item">Item</th>
|
||||||
|
<th data-key-name="amount">Amount</th>
|
||||||
|
<th data-key-name="measure">Measure</th>
|
||||||
|
<th data-key-name="price">Price</th>
|
||||||
|
<th data-key-name="venue">Venue</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- Create/Edit Dialog -->
|
||||||
|
<div id="editorDialog" class="modal fade" role="dialog">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
<h4 class="modal-title"></h4>
|
||||||
|
</div>
|
||||||
|
<form role="form" autocomplete="off">
|
||||||
|
<div class="modal-body">
|
||||||
|
<label for="DFDate">Date</label>
|
||||||
|
<div class="input-group date">
|
||||||
|
<input name="date" id="DFDate" type="text" class="form-control" tabindex="0" placeholder="" required>
|
||||||
|
<span class="input-group-addon">
|
||||||
|
<span class="glyphicon glyphicon-calendar"></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<label for="DFItem">Item</label>
|
||||||
|
<div class="form-group">
|
||||||
|
<select name="item" id="DFItem" class="js-states form-control" style="width: 100%;" required></select>
|
||||||
|
</div>
|
||||||
|
<label for="DFAmount">Amount</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<input name="amount" id="DFAmount" type="number" min="0" step="1" value="1" data-number-to-fixed="2" class="form-control" tabindex="0" required>
|
||||||
|
</div>
|
||||||
|
<label for="DFMeasure">Measure</label>
|
||||||
|
<div class="form-group">
|
||||||
|
<select name="measure" id="DFMeasure" class="js-states form-control" style="width: 100%;" required></select>
|
||||||
|
</div>
|
||||||
|
<label for="DFPrice">Price</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-addon">$</span><input name="price" id="DFPrice" type="number" min="0.00" step="0.50" value="10.00" data-number-to-fixed="2" class="form-control currency" tabindex="0" required>
|
||||||
|
</div>
|
||||||
|
<label for="DFVenue">Venue</label>
|
||||||
|
<div class="form-group">
|
||||||
|
<select name="venue" id="DFVenue" class="js-states form-control" style="width: 100%;" required></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button id="DFSave" type="button" class="btn btn-default btn-primary btn-md" tabindex="0">Save</button>
|
||||||
|
<button id="DFCreate" type="button" class="btn btn-default btn-primary btn-md" tabindex="0">Create</button>
|
||||||
|
<button id="DFCreatePlus" type="button" class="btn btn-primary btn-md" tabindex="0">Create++</button>
|
||||||
|
<button id="DFCancel" type="button" class="btn" data-dismiss="modal" tabindex="0">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Delete Dialog -->
|
||||||
|
<div id="deleteDialog" class="modal fade" role="dialog">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
<h4 class="modal-title">Delete Item</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Are you certain you wish to delete the sale <span id="deleteName"></span>?
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button id="DFDelete" type="button" class="btn btn-warning btn-md" tabindex="0">Delete</button>
|
||||||
|
<button id="DFCancelDelete" type="button" class="btn btn-primary btn-default" data-dismiss="modal" tabindex="1">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script language="JavaScript" type="text/javascript">//# sourceURL=subcategories.html
|
||||||
|
$(function() {
|
||||||
|
var $page = $('#sales');
|
||||||
|
var $btnCreate = $page.find("#createButton");
|
||||||
|
var $btnEdit = $page.find("#editButton");
|
||||||
|
var $btnDelete = $page.find("#deleteButton");
|
||||||
|
var $btnRestore = $page.find("#restoreButton");
|
||||||
|
|
||||||
|
$btnEdit.disable(true);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
$btnRestore.disable(true);
|
||||||
|
|
||||||
|
var selectionChanged = function($tr, model) {
|
||||||
|
if($tr && model) {
|
||||||
|
$btnEdit.disable(false);
|
||||||
|
|
||||||
|
//If the object was deleted (hidden), then allow it to be restored, otherwise allow the model to be deleted.
|
||||||
|
if(model.deletedAt) {
|
||||||
|
$btnRestore.disable(false);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnRestore.disable(true);
|
||||||
|
$btnDelete.disable(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnEdit.disable(true);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
$btnRestore.disable(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var dataTable = new LinkedTable($page.find('#dataTable'), {
|
||||||
|
url: "data/Sale/readAll",
|
||||||
|
attr: "data-key-name",
|
||||||
|
selection: "row",
|
||||||
|
parameters: function() {
|
||||||
|
return {paranoid: !$page.find('#includeDeletedToggle').is(":checked")};
|
||||||
|
},
|
||||||
|
selectionChanged: selectionChanged,
|
||||||
|
supportingData: [{name: "items", url: "data/Item/readAll", parameters: {showDeleted: true}, postProcess: function(data) {
|
||||||
|
var byId;
|
||||||
|
|
||||||
|
//Convert the list into a map by id.
|
||||||
|
byId = data.reduce(function(map, item) {
|
||||||
|
map[item.id] = item;
|
||||||
|
return map;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return byId;
|
||||||
|
}}],
|
||||||
|
cellDataHandlers: {item: function($cell, sale, supportingData) {
|
||||||
|
try {
|
||||||
|
var item = supportingData.items[sale.itemId];
|
||||||
|
|
||||||
|
$cell.html(item.name);
|
||||||
|
}catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
$cell.html("Not Found");
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
postAddRowHandler: function($row, dataObject) {
|
||||||
|
if(dataObject.deletedAt) {
|
||||||
|
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
postUpdateRowHandler: function($row, dataObject) {
|
||||||
|
if(dataObject.deletedAt) {
|
||||||
|
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if($row.is(dataTable.getSelectedRow())) {
|
||||||
|
selectionChanged($row, dataObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Call the refresh user table function once initially.
|
||||||
|
dataTable.build();
|
||||||
|
|
||||||
|
//Refresh the data table if the user toggles the button to show/hide deleted elements.
|
||||||
|
$page.find('#includeDeletedToggle').on('click', function(event) {
|
||||||
|
dataTable.refresh();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//+++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
// ++++++++++++ Create/Edit Dialogs ++++++++++++
|
||||||
|
|
||||||
|
var $editorDialog = $page.find('#editorDialog');
|
||||||
|
var $deleteDialog = $page.find('#deleteDialog');
|
||||||
|
var $editorForm = $editorDialog.find('form');
|
||||||
|
var queries = [
|
||||||
|
$.get("data/Item/readAll", {request: JSON.stringify({paranoid: false, order: ['name', ['name']]})}),
|
||||||
|
$.get("data/Measure/readAll", {request: JSON.stringify({paranoid: false})}),
|
||||||
|
$.get("data/Venue/readAll", {request: JSON.stringify({paranoid: false})})
|
||||||
|
];
|
||||||
|
|
||||||
|
//Update the dialog drop downs when the queries finish.
|
||||||
|
$.when.apply($, queries).then(function(query1, query2) {
|
||||||
|
var items = query1[0];
|
||||||
|
var itemsData = [];
|
||||||
|
var measures = query2[0];
|
||||||
|
var measuresData = [];
|
||||||
|
var venues = query2[0];
|
||||||
|
var venueData = [];
|
||||||
|
|
||||||
|
//Collect the data for the drop down controls in the form they need (array of id/text pairs).
|
||||||
|
for(var i = 0; i < items.length; i++) {
|
||||||
|
var next = items[i];
|
||||||
|
|
||||||
|
itemsData.push({id: '' + next.id, text: next.name});
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i = 0; i < measures.length; i++) {
|
||||||
|
var next = measures[i];
|
||||||
|
|
||||||
|
measuresData.push({id: '' + next.id, text: next.name});
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i = 0; i < venues.length; i++) {
|
||||||
|
var next = venues[i];
|
||||||
|
|
||||||
|
venueData.push({id: '' + next.id, text: next.name});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Initialize the data for the dropdown.
|
||||||
|
$editorForm.find("#DFItems").select2({data: itemsData}).focus(function() {$(this).select2('focus')});
|
||||||
|
$editorForm.find("#DFMeasures").select2({data: measuresData}).focus(function() {$(this).select2('focus')});
|
||||||
|
//Initialize the validator
|
||||||
|
$editorForm.validator();
|
||||||
|
});
|
||||||
|
|
||||||
|
//Handle opening the create dialog.
|
||||||
|
$btnCreate.on("click", function(event) {
|
||||||
|
//Configure the dialog to create a new element.
|
||||||
|
$editorDialog.find("#DFCreate, #DFCreatePlus").show();
|
||||||
|
$editorDialog.find("#DFSave").hide();
|
||||||
|
$editorDialog.find(".modal-title").text("Create Sale");
|
||||||
|
//Reset fields to default values.
|
||||||
|
$editorDialog.find("#DFAmount").val("1");
|
||||||
|
$editorDialog.find("#DFPrice").val("");
|
||||||
|
//Open the dialog.
|
||||||
|
$editorDialog.modal();
|
||||||
|
});
|
||||||
|
//Handle opening the edit dialog.
|
||||||
|
$btnEdit.on("click", function(event) {
|
||||||
|
//debugger;
|
||||||
|
if(dataTable.getSelectedRow() != null) {
|
||||||
|
//Configure the dialog to edit an existing element.
|
||||||
|
$editorDialog.find("#DFCreate, #DFCreatePlus").hide();
|
||||||
|
$editorDialog.find("#DFSave").show();
|
||||||
|
$editorDialog.find(".modal-title").text("Edit Sale");
|
||||||
|
//Reset fields to selected values.
|
||||||
|
$editorDialog.find('#DFDate').val(dataTable.getSelectedRow().data("model").date);
|
||||||
|
$editorDialog.find('#DFPrice').val(dataTable.getSelectedRow().data("model").price);
|
||||||
|
$editorDialog.find('#DFAmount').val(dataTable.getSelectedRow().data("model").amount);
|
||||||
|
$editorDialog.find('#DFItem').val(dataTable.getSelectedRow().data("model").itemId).trigger("change");
|
||||||
|
$editorDialog.find('#DFVenue').val(dataTable.getSelectedRow().data("model").venueId).trigger("change");
|
||||||
|
$editorDialog.find('#DFMeasure').val(dataTable.getSelectedRow().data("model").measureId).trigger("change");
|
||||||
|
//Open the dialog.
|
||||||
|
$editorDialog.modal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Handle the Create Button being clicked.
|
||||||
|
var createFunction = function(close) {
|
||||||
|
$editorForm.data('bs.validator').validate(function(isValid) {
|
||||||
|
if(isValid) {
|
||||||
|
$.ajax({url: "data/Sale/create", type: "POST", dataType: "json", data: encodeData({
|
||||||
|
date: $editorForm.find("#DFDate").val(),
|
||||||
|
price: parseFloat($editorForm.find("#DFPrice").val()),
|
||||||
|
amount: parseFloat($editorForm.find("#DFAmount").val()),
|
||||||
|
itemId: parseInt($editorForm.find("#DFItem").val()),
|
||||||
|
venueId: parseInt($editorForm.find("#DFVenue").val()),
|
||||||
|
measureId: parseInt($editorForm.find("#DFMeasure").val())
|
||||||
|
})}).done(function(data) {
|
||||||
|
if(close) $editorDialog.modal("hide");
|
||||||
|
dataTable.refresh();
|
||||||
|
}).fail(function(data) {
|
||||||
|
alert("Server call failed.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
$editorDialog.find('#DFCreatePlus').on('click', function(event) {
|
||||||
|
createFunction(false);
|
||||||
|
});
|
||||||
|
$editorDialog.find('#DFCreate').on('click', function(event) {
|
||||||
|
createFunction(true);
|
||||||
|
});
|
||||||
|
//Handle the Save Button being clicked.
|
||||||
|
$editorDialog.find('#DFSave').on('click', function(event) {
|
||||||
|
$editorForm.data('bs.validator').validate(function(isValid) {
|
||||||
|
if(isValid) {
|
||||||
|
try {
|
||||||
|
$.post("data/Sale/edit", {
|
||||||
|
id: dataTable.getSelectedRow().data("model").id,
|
||||||
|
date: $editorForm.find("#DFDate").val(),
|
||||||
|
price: parseFloat($editorForm.find("#DFPrice").val()),
|
||||||
|
amount: parseFloat($editorForm.find("#DFAmount").val()),
|
||||||
|
itemId: parseInt($editorForm.find("#DFItem").val()),
|
||||||
|
venueId: parseInt($editorForm.find("#DFVenue").val()),
|
||||||
|
measureId: parseInt($editorForm.find("#DFMeasure").val())
|
||||||
|
}, function(data) {
|
||||||
|
if(data.result == "success") {
|
||||||
|
$editorDialog.modal("hide");
|
||||||
|
dataTable.refresh();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert(data.result);
|
||||||
|
}
|
||||||
|
}, "json");
|
||||||
|
} catch(e) {
|
||||||
|
alert(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$editorDialog.find('#DFCancel').on('click', function(event) {
|
||||||
|
$editorDialog.modal('hide');
|
||||||
|
});
|
||||||
|
//Set the initial focus control.
|
||||||
|
$editorDialog.on('shown.bs.modal', function() {
|
||||||
|
$editorDialog.find('#DFName').focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
//++++++++++++++++++++++++++++++++++++++
|
||||||
|
// ++++++++++ Delete Dialog +++++++++++
|
||||||
|
|
||||||
|
//Open the dialog.
|
||||||
|
$btnDelete.on("click", function(event) {
|
||||||
|
//debugger;
|
||||||
|
if(dataTable.getSelectedRow() != null) {
|
||||||
|
$deleteDialog.find("#deleteName").html(dataTable.getSelectedRow().data("model").name);
|
||||||
|
$deleteDialog.modal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//Delete the element and close the dialog.
|
||||||
|
$deleteDialog.find('#deleteButton').on("click", function(event) {
|
||||||
|
if(dataTable.getSelectedRow() != null) {
|
||||||
|
$.post("data/Sale/delete", {where: {id: dataTable.getSelectedRow().data("model").id}}, function(data) {
|
||||||
|
if(data.result == "success") {
|
||||||
|
$deleteDialog.modal("hide");
|
||||||
|
dataTable.refresh();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert(data.result);
|
||||||
|
}
|
||||||
|
}, "json");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$deleteDialog.find('#DFCancelDelete').on('click', function(event) {
|
||||||
|
$deleteDialog.modal('hide');
|
||||||
|
});
|
||||||
|
//Set the initial focus control.
|
||||||
|
$editorDialog.on('shown.bs.modal', function() {
|
||||||
|
$deleteDialog.find('#DFCancelDelete').focus();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
3
public/admin/sales.styl
Normal file
3
public/admin/sales.styl
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#sales {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<!-- Main Page Content -->
|
<!-- Main Page Content -->
|
||||||
<h1><span class="fa fa-users"></span> Manage Subcategories</h1>
|
<h1><span class="fa fa-users"></span> Manage Subcategories</h1>
|
||||||
|
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-12">
|
||||||
<div class="dt-buttons btn-group" style="display: inline-block">
|
<div class="dt-buttons btn-group" style="display: inline-block">
|
||||||
<a id="createButton" class="btn btn-default buttons-create" tabindex="0" href="javaScript:void(0);"><span>New</span></a>
|
<a id="createButton" class="btn btn-default buttons-create" tabindex="0" href="javaScript:void(0);"><span>New</span></a>
|
||||||
<a id="editButton" class="btn btn-default buttons-selected buttons-edit" tabindex="0" href="javaScript:void(0);"><span>Edit</span></a>
|
<a id="editButton" class="btn btn-default buttons-selected buttons-edit" tabindex="0" href="javaScript:void(0);"><span>Edit</span></a>
|
||||||
@@ -79,6 +79,31 @@
|
|||||||
var $btnDelete = $page.find("#deleteButton");
|
var $btnDelete = $page.find("#deleteButton");
|
||||||
var $btnRestore = $page.find("#restoreButton");
|
var $btnRestore = $page.find("#restoreButton");
|
||||||
|
|
||||||
|
$btnEdit.disable(true);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
$btnRestore.disable(true);
|
||||||
|
|
||||||
|
var selectionChanged = function($tr, model) {
|
||||||
|
if($tr && model) {
|
||||||
|
$btnEdit.disable(false);
|
||||||
|
|
||||||
|
//If the object was deleted (hidden), then allow it to be restored, otherwise allow the model to be deleted.
|
||||||
|
if(model.deletedAt) {
|
||||||
|
$btnRestore.disable(false);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnRestore.disable(true);
|
||||||
|
$btnDelete.disable(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnEdit.disable(true);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
$btnRestore.disable(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var dataTable = new LinkedTable($page.find('#dataTable'), {
|
var dataTable = new LinkedTable($page.find('#dataTable'), {
|
||||||
url: "data/Subcategory/readAll",
|
url: "data/Subcategory/readAll",
|
||||||
attr: "data-key-name",
|
attr: "data-key-name",
|
||||||
@@ -86,26 +111,7 @@
|
|||||||
parameters: function() {
|
parameters: function() {
|
||||||
return {paranoid: !$page.find('#includeDeletedToggle').is(":checked")};
|
return {paranoid: !$page.find('#includeDeletedToggle').is(":checked")};
|
||||||
},
|
},
|
||||||
selectionChanged: function($tr, model) {
|
selectionChanged: selectionChanged,
|
||||||
if($tr && model) {
|
|
||||||
$btnEdit.show();
|
|
||||||
|
|
||||||
//If the object was deleted (hidden), then allow it to be restored, otherwise allow the model to be deleted.
|
|
||||||
if(model.deletedAt) {
|
|
||||||
$btnRestore.show();
|
|
||||||
$btnDelete.hide();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$btnRestore.hide();
|
|
||||||
$btnDelete.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$btnEdit.hide();
|
|
||||||
$btnDelete.hide();
|
|
||||||
$btnRestore.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
supportingData: [{name: "categories", url: "data/Category/readAll", parameters: {showDeleted: true}, postProcess: function(data) {
|
supportingData: [{name: "categories", url: "data/Category/readAll", parameters: {showDeleted: true}, postProcess: function(data) {
|
||||||
var byId;
|
var byId;
|
||||||
|
|
||||||
@@ -115,9 +121,6 @@
|
|||||||
return map;
|
return map;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
//Save the categories by id for use when setting the editor dialog's dropdown selection.
|
|
||||||
categoriesById = byId;
|
|
||||||
|
|
||||||
return byId;
|
return byId;
|
||||||
}}],
|
}}],
|
||||||
cellDataHandlers: {category: function($cell, subcategory, supportingData) {
|
cellDataHandlers: {category: function($cell, subcategory, supportingData) {
|
||||||
@@ -134,11 +137,20 @@
|
|||||||
if(dataObject.deletedAt) {
|
if(dataObject.deletedAt) {
|
||||||
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
postUpdateRowHandler: function($row, dataObject) {
|
||||||
|
if(dataObject.deletedAt) {
|
||||||
|
$("td:first", $row).prepend("<span class='glyphicon glyphicon-remove-circle' style='margin-right: 10px;' aria-hidden='true'></span>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if($row.is(dataTable.getSelectedRow())) {
|
||||||
|
selectionChanged($row, dataObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Call the refresh user table function once initially.
|
//Call the refresh user table function once initially.
|
||||||
dataTable.refresh();
|
dataTable.build();
|
||||||
|
|
||||||
//Refresh the data table if the user toggles the button to show/hide deleted elements.
|
//Refresh the data table if the user toggles the button to show/hide deleted elements.
|
||||||
$page.find('#includeDeletedToggle').on('click', function(event) {
|
$page.find('#includeDeletedToggle').on('click', function(event) {
|
||||||
@@ -165,11 +177,11 @@
|
|||||||
var $editorDialog = $page.find('#editorDialog');
|
var $editorDialog = $page.find('#editorDialog');
|
||||||
var $deleteDialog = $page.find('#deleteDialog');
|
var $deleteDialog = $page.find('#deleteDialog');
|
||||||
var $editorForm = $editorDialog.find('form');
|
var $editorForm = $editorDialog.find('form');
|
||||||
var queries = [$.get("data/Category/readAll", {order: ['name', ['name']]})];
|
var queries = [$.get("data/Category/readAll", {request: JSON.stringify({order: ['name', ['name']]})})];
|
||||||
|
|
||||||
//Update the dialog drop downs when the queries finish.
|
//Update the dialog drop downs when the queries finish.
|
||||||
$.when.apply($, queries).then(function(query1) {
|
$.when.apply($, queries).then(function(query1) {
|
||||||
var categories = query1[0];
|
var categories = query1;
|
||||||
var categoriesData = [];
|
var categoriesData = [];
|
||||||
|
|
||||||
//Iterate over the categories and their subcategories to build the tree of data for the dropdown.
|
//Iterate over the categories and their subcategories to build the tree of data for the dropdown.
|
||||||
@@ -206,7 +218,7 @@
|
|||||||
$editorDialog.find(".modal-title").text("Edit Subcategory");
|
$editorDialog.find(".modal-title").text("Edit Subcategory");
|
||||||
//Reset fields to selected values.
|
//Reset fields to selected values.
|
||||||
$editorDialog.find('#DFName').val(dataTable.getSelectedRow().data("model").name);
|
$editorDialog.find('#DFName').val(dataTable.getSelectedRow().data("model").name);
|
||||||
$editorDialog.find('#DFCategory').val(dataTable.getSelectedRow().data("model").categoryId);
|
$editorDialog.find('#DFCategory').val(dataTable.getSelectedRow().data("model").categoryId).trigger("change");
|
||||||
//Open the dialog.
|
//Open the dialog.
|
||||||
$editorDialog.modal();
|
$editorDialog.modal();
|
||||||
}
|
}
|
||||||
@@ -216,22 +228,15 @@
|
|||||||
var createFunction = function(close) {
|
var createFunction = function(close) {
|
||||||
$editorForm.data('bs.validator').validate(function(isValid) {
|
$editorForm.data('bs.validator').validate(function(isValid) {
|
||||||
if(isValid) {
|
if(isValid) {
|
||||||
try {
|
$.ajax({url: "data/Subcategory/create", type: "POST", dataType: "json", data: encodeData({
|
||||||
$.post("data/Subcategory/create", {
|
name: $editorForm.find("#DFName").val(),
|
||||||
name: $editorForm.find("#DFName").val(),
|
categoryId: parseInt($editorForm.find("#DFCategory").val())
|
||||||
categoryId: parseInt($editorForm.find("#DFCategory").val())
|
})}).done(function(data) {
|
||||||
}, function(data) {
|
if(close) $editorDialog.modal("hide");
|
||||||
if(data.result == "success") {
|
dataTable.refresh();
|
||||||
if(close) $editorDialog.modal("hide");
|
}).fail(function(data) {
|
||||||
dataTable.refresh();
|
alert("Server call failed.");
|
||||||
}
|
});
|
||||||
else {
|
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
} catch(e) {
|
|
||||||
alert(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -245,23 +250,16 @@
|
|||||||
$editorDialog.find('#DFSave').on('click', function(event) {
|
$editorDialog.find('#DFSave').on('click', function(event) {
|
||||||
$editorForm.data('bs.validator').validate(function(isValid) {
|
$editorForm.data('bs.validator').validate(function(isValid) {
|
||||||
if(isValid) {
|
if(isValid) {
|
||||||
try {
|
$.ajax({url: "data/Subcategory/edit", type: "POST", dataType: "json", data: encodeData({
|
||||||
$.post("data/Subcategory/edit", {
|
id: dataTable.getSelectedRow().data("model").id,
|
||||||
id: dataTable.getSelectedRow().data("model").id,
|
name: $editorForm.find("#DFName").val(),
|
||||||
name: $editorForm.find("#DFName").val(),
|
categoryId: parseInt($editorForm.find("#DFCategory").val())
|
||||||
categoryId: parseInt($editorForm.find("#DFCategory").val())
|
})}).done(function(data) {
|
||||||
}, function(data) {
|
if(close) $editorDialog.modal("hide");
|
||||||
if(data.result == "success") {
|
dataTable.refresh();
|
||||||
$editorDialog.modal("hide");
|
}).fail(function(data) {
|
||||||
dataTable.refresh();
|
alert("Server call failed.");
|
||||||
}
|
});
|
||||||
else {
|
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
} catch(e) {
|
|
||||||
alert(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -287,15 +285,12 @@
|
|||||||
//Delete the element and close the dialog.
|
//Delete the element and close the dialog.
|
||||||
$deleteDialog.find('#deleteButton').on("click", function(event) {
|
$deleteDialog.find('#deleteButton').on("click", function(event) {
|
||||||
if(dataTable.getSelectedRow() != null) {
|
if(dataTable.getSelectedRow() != null) {
|
||||||
$.post("data/Subcategory/delete", {where: {id: dataTable.getSelectedRow().data("model").id}}, function(data) {
|
$.ajax({url: "data/Subcategory/delete", type: "POST", dataType: "json", data: encodeData({where: {id: dataTable.getSelectedRow().data("model").id}})}).done(function(data) {
|
||||||
if(data.result == "success") {
|
$deleteDialog.modal("hide");
|
||||||
$deleteDialog.modal("hide");
|
dataTable.refresh();
|
||||||
dataTable.refresh();
|
}).fail(function(data) {
|
||||||
}
|
alert("Server call failed.");
|
||||||
else {
|
});
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$deleteDialog.find('#DFCancelDelete').on('click', function(event) {
|
$deleteDialog.find('#DFCancelDelete').on('click', function(event) {
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
<!-- Main Page Content -->
|
<!-- Main Page Content -->
|
||||||
<h1><span class="fa fa-users"></span> Manage Users</h1>
|
<h1><span class="fa fa-users"></span> Manage Users</h1>
|
||||||
|
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-12">
|
||||||
<div class="dt-buttons btn-group">
|
<div class="dt-buttons btn-group">
|
||||||
<a id="createButton" class="btn btn-default buttons-create" tabindex="0" href="javaScript:void(0);"><span>New</span></a>
|
<a id="createButton" class="btn btn-default buttons-create" tabindex="0" href="javaScript:void(0);"><span>New</span></a>
|
||||||
<a id="changeLoginButton" class="btn btn-default buttons-selected buttons-edit" style="visibility: hidden; display: none;" tabindex="0" href="javaScript:void(0);"><span>Change Login</span></a>
|
<a id="changeLoginButton" class="btn btn-default buttons-selected buttons-edit" tabindex="0" href="javaScript:void(0);"><span>Change Login</span></a>
|
||||||
<a id="resetPasswordButton" class="btn btn-default buttons-selected buttons-edit" style="visibility: hidden; display: none;" tabindex="0" href="javaScript:void(0);"><span>Reset Password</span></a>
|
<a id="resetPasswordButton" class="btn btn-default buttons-selected buttons-edit" tabindex="0" href="javaScript:void(0);"><span>Reset Password</span></a>
|
||||||
<a id="deleteButton" class="btn btn-default buttons-selected buttons-remove" style="visibility: hidden; display: none;" tabindex="0" href="javaScript:void(0);"><span>Delete</span></a>
|
<a id="deleteButton" class="btn btn-default buttons-selected buttons-remove" tabindex="0" href="javaScript:void(0);"><span>Delete</span></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<table id="dataTable" class="table table-striped table-hover">
|
<table id="dataTable" class="table table-striped table-hover">
|
||||||
@@ -32,11 +32,11 @@
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Login</label>
|
<label>Login</label>
|
||||||
<input name="login" id="DFLogin" type="text" class="form-control" tabindex="0">
|
<input name="login" id="DFLogin" type="text" class="form-control" tabindex="0" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Password</label>
|
<label>Password</label>
|
||||||
<input name="password" id="DFPassword" type="password" class="form-control" tabindex="0">
|
<input name="password" id="DFPassword" type="password" class="form-control" tabindex="0" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
@@ -59,12 +59,12 @@
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Password</label>
|
<label>Password</label>
|
||||||
<input name="password" id="DFResetPassword" type="password" class="form-control" tabindex="0">
|
<input name="password" id="DFResetPassword" type="password" class="form-control" tabindex="0" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button id="DFResetPasswordSave" type="button" class="btn btn-warning btn-md" tabindex="0">Save</button>
|
<button id="DFResetPasswordSave" type="button" class="btn btn-default btn-warning btn-md" tabindex="0">Save</button>
|
||||||
<button id="DFResetPasswordCancel" type="button" class="btn btn-default" data-dismiss="modal" tabindex="0">Cancel</button>
|
<button id="DFResetPasswordCancel" type="button" class="btn" data-dismiss="modal" tabindex="0">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -81,12 +81,12 @@
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Login</label>
|
<label>Login</label>
|
||||||
<input name="login" id="DFChangeLogin" type="text" class="form-control" tabindex="0">
|
<input name="login" id="DFChangeLogin" type="text" class="form-control" tabindex="0" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button id="DFChangeLoginSave" type="button" class="btn btn-warning btn-md" tabindex="0">Save</button>
|
<button id="DFChangeLoginSave" type="button" class="btn btn-default btn-warning btn-md" tabindex="0">Save</button>
|
||||||
<button id="DFChangeLoginCancel" type="button" class="btn btn-default" data-dismiss="modal" tabindex="0">Cancel</button>
|
<button id="DFChangeLoginCancel" type="button" class="btn" data-dismiss="modal" tabindex="0">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -104,8 +104,8 @@
|
|||||||
Are you certain you wish to delete the user <span id="deleteUserDialogUserName"></span>?
|
Are you certain you wish to delete the user <span id="deleteUserDialogUserName"></span>?
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button id="DFDeleteSave" type="button" class="btn btn-warning btn-md" tabindex="0">Delete</button>
|
<button id="DFDelete" type="button" class="btn btn-default btn-warning btn-md" tabindex="0">Delete</button>
|
||||||
<button id="DFDeleteCancel" type="button" class="btn btn-default" data-dismiss="modal" tabindex="1">Cancel</button>
|
<button id="DFDeleteCancel" type="button" class="btn" data-dismiss="modal" tabindex="1">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -123,50 +123,62 @@
|
|||||||
var $changeLoginDialog = $page.find('#changeLoginDialog');
|
var $changeLoginDialog = $page.find('#changeLoginDialog');
|
||||||
var $deleteUserDialog = $page.find('#deleteUserDialog');
|
var $deleteUserDialog = $page.find('#deleteUserDialog');
|
||||||
|
|
||||||
|
var $createUserForm = $createUserDialog.find('form');
|
||||||
|
var $resetPasswordForm = $resetPasswordDialog.find('form');
|
||||||
|
var $changeLoginForm = $changeLoginDialog.find('form');
|
||||||
|
|
||||||
|
$btnChangeLogin.disable(true);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
$btnResetPassword.disable(true);
|
||||||
|
|
||||||
|
var selectionChanged = function($tr, model) {
|
||||||
|
if($tr && model) {
|
||||||
|
$btnChangeLogin.disable(false);
|
||||||
|
$btnResetPassword.disable(false);
|
||||||
|
$btnDelete.disable(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnChangeLogin.disable(true);
|
||||||
|
$btnResetPassword.disable(true);
|
||||||
|
$btnDelete.disable(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var dataTable = new LinkedTable($page.find('#dataTable'), {
|
var dataTable = new LinkedTable($page.find('#dataTable'), {
|
||||||
url: "data/User/readAll",
|
url: "data/User/readAll",
|
||||||
attr: "data-key-name",
|
attr: "data-key-name",
|
||||||
selection: "row",
|
selection: "row",
|
||||||
selectionChanged: function($tr, model) {
|
selectionChanged: selectionChanged
|
||||||
if($tr && model) {
|
|
||||||
$btnChangeLogin.show();
|
|
||||||
$btnResetPassword.show();
|
|
||||||
$btnDelete.show();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$btnChangeLogin.hide();
|
|
||||||
$btnResetPassword.hide();
|
|
||||||
$btnDelete.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//Call the refresh user table function once initially.
|
//Call the refresh user table function once initially.
|
||||||
dataTable.refresh();
|
dataTable.build();
|
||||||
|
|
||||||
//----------------------------
|
//----------------------------
|
||||||
//---- Create User Dialog ----
|
//---- Create User Dialog ----
|
||||||
|
|
||||||
|
//Initialize the validator
|
||||||
|
$createUserForm.validator();
|
||||||
|
|
||||||
$btnCreate.on("click", function(event) {
|
$btnCreate.on("click", function(event) {
|
||||||
$createUserDialog.modal();
|
$createUserDialog.modal();
|
||||||
});
|
});
|
||||||
$createUserDialog.find("#DFCreateSave").on("click", function(event) {
|
$createUserDialog.find("#DFCreateSave").on("click", function(event) {
|
||||||
try {
|
$createUserForm.data('bs.validator').validate(function(isValid) {
|
||||||
$.post("data/User/create", {
|
if(isValid) {
|
||||||
login: $createUserDialog.find("#loginDialogLogin").val(),
|
$.ajax({
|
||||||
password: $createUserDialog.find("#loginDialogPassword").val()
|
url: "data/User/create", type: "POST", dataType: "json", data: encodeData({
|
||||||
}, function(data) {
|
login: $createUserDialog.find("#DFLogin").val(),
|
||||||
if(data.result == "success") {
|
password: $createUserDialog.find("#DFPassword").val()
|
||||||
|
})
|
||||||
|
}).done(function(data) {
|
||||||
$createUserDialog.modal("hide");
|
$createUserDialog.modal("hide");
|
||||||
dataTable.refresh();
|
dataTable.refresh();
|
||||||
}
|
}).fail(function(data) {
|
||||||
else {
|
alert("Server call failed.");
|
||||||
alert(data.result);
|
});
|
||||||
}
|
}
|
||||||
}, "json");
|
});
|
||||||
} catch(e) {
|
|
||||||
alert(e);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
$createUserDialog.find("#DFCreateSave").on("click", function(event) {
|
$createUserDialog.find("#DFCreateSave").on("click", function(event) {
|
||||||
$createUserDialog.modal('hide');
|
$createUserDialog.modal('hide');
|
||||||
@@ -175,6 +187,77 @@
|
|||||||
$createUserDialog.find('#DFLogin').focus();
|
$createUserDialog.find('#DFLogin').focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//------------------------------
|
||||||
|
//----- Change Login Dialog ----
|
||||||
|
|
||||||
|
//Initialize the validator
|
||||||
|
$changeLoginForm.validator();
|
||||||
|
|
||||||
|
$btnChangeLogin.on("click", function(event) {
|
||||||
|
if(dataTable.getSelectedRow() != null) {
|
||||||
|
$changeLoginDialog.find('#changeLoginDialogLogin').val(dataTable.getSelectedRow().data("model").login);
|
||||||
|
$changeLoginDialog.modal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$changeLoginDialog.find("#DFChangeLoginSave").on("click", function(event) {
|
||||||
|
$changeLoginForm.data('bs.validator').validate(function(isValid) {
|
||||||
|
if(isValid) {
|
||||||
|
$.ajax({
|
||||||
|
url: "data/User/update", type: "POST", dataType: "json", data: encodeData({
|
||||||
|
id: dataTable.getSelectedRow().data("model").id,
|
||||||
|
login: $changeLoginDialog("#DFChangeLogin").val()
|
||||||
|
})
|
||||||
|
}).done(function(data) {
|
||||||
|
$changeLoginDialog.modal("hide");
|
||||||
|
dataTable.refresh();
|
||||||
|
}).fail(function(data) {
|
||||||
|
alert("Server call failed.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$changeLoginDialog.find("#DFChangeLoginCancel").on("click", function(event) {
|
||||||
|
$changeLoginDialog.modal('hide');
|
||||||
|
});
|
||||||
|
$changeLoginDialog.on('shown.bs.modal', function() {
|
||||||
|
$changeLoginDialog.find('#DFChangeLogin').focus().select();
|
||||||
|
});
|
||||||
|
|
||||||
|
//-------------------------------
|
||||||
|
//---- Reset Password Dialog ----
|
||||||
|
|
||||||
|
//Initialize the validator
|
||||||
|
$resetPasswordForm.validator();
|
||||||
|
|
||||||
|
$btnResetPassword.on("click", function(event) {
|
||||||
|
if(dataTable.getSelectedRow() != null) {
|
||||||
|
$resetPasswordDialog.modal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$resetPasswordDialog.find("#DFResetPasswordSave").on("click", function(event) {
|
||||||
|
$resetPasswordForm.data('bs.validator').validate(function(isValid) {
|
||||||
|
if(isValid) {
|
||||||
|
$.ajax({
|
||||||
|
url: "data/User/update", type: "POST", dataType: "json", data: encodeData({
|
||||||
|
id: dataTable.getSelectedRow().data("model").id,
|
||||||
|
password: $resetPasswordDialog.find("#DFResetPassword").val()
|
||||||
|
})
|
||||||
|
}).done(function(data) {
|
||||||
|
$resetPasswordDialog.modal("hide");
|
||||||
|
dataTable.refresh();
|
||||||
|
}).fail(function(data) {
|
||||||
|
alert("Server call failed.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$resetPasswordDialog.find("#DFResetPasswordCancel").on("click", function(event) {
|
||||||
|
$resetPasswordDialog.modal('hide');
|
||||||
|
});
|
||||||
|
$resetPasswordDialog.on('shown.bs.modal', function() {
|
||||||
|
$resetPasswordDialog.find('#DFResetPassword').focus();
|
||||||
|
});
|
||||||
|
|
||||||
//----------------------------
|
//----------------------------
|
||||||
//---- Delete User Dialog ----
|
//---- Delete User Dialog ----
|
||||||
|
|
||||||
@@ -188,17 +271,12 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
$deleteUserDialog.find("#DFDelete").on("click", function(event) {
|
$deleteUserDialog.find("#DFDelete").on("click", function(event) {
|
||||||
if(dataTable.getSelectedRow() != null) {
|
$.ajax({url: "data/User/delete", type: "POST", dataType: "json", data: encodeData({where: {id: dataTable.getSelectedRow().data("model").id}})}).done(function(data) {
|
||||||
$.post("data/User/delete", {where: {id: dataTable.getSelectedRow().data("model").id}}, function(data) {
|
$deleteUserDialog.modal("hide");
|
||||||
if(data.result == "success") {
|
dataTable.refresh();
|
||||||
$deleteUserDialog.modal("hide");
|
}).fail(function(data) {
|
||||||
dataTable.refresh();
|
alert("Server call failed.");
|
||||||
}
|
});
|
||||||
else {
|
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
$deleteUserDialog.find("#DFDeleteCancel").on("click", function(event) {
|
$deleteUserDialog.find("#DFDeleteCancel").on("click", function(event) {
|
||||||
$deleteUserDialog.modal('hide');
|
$deleteUserDialog.modal('hide');
|
||||||
@@ -206,69 +284,6 @@
|
|||||||
$deleteUserDialog.on('shown.bs.modal', function() {
|
$deleteUserDialog.on('shown.bs.modal', function() {
|
||||||
$deleteUserDialog.find('#DFDeleteCancel').focus();
|
$deleteUserDialog.find('#DFDeleteCancel').focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
//------------------------------
|
|
||||||
//----- Change Login Dialog ----
|
|
||||||
|
|
||||||
$btnChangeLogin.on("click", function(event) {
|
|
||||||
if(dataTable.getSelectedRow() != null) {
|
|
||||||
$changeLoginDialog.find('#changeLoginDialogLogin').val(dataTable.getSelectedRow().data("model").login);
|
|
||||||
$changeLoginDialog.modal();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$changeLoginDialog.find("#DFChangeLoginSave").on("click", function(event) {
|
|
||||||
if(dataTable.getSelectedRow() != null) {
|
|
||||||
$.post("data/User/update", {
|
|
||||||
id: dataTable.getSelectedRow().data("model").id,
|
|
||||||
login: $changeLoginDialog("#DFChangeLogin").val()
|
|
||||||
}, function(data) {
|
|
||||||
if(data.result == "success") {
|
|
||||||
$changeLoginDialog.modal("hide");
|
|
||||||
dataTable.refresh();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$changeLoginDialog.find("#DFChangeLoginCancel").on("click", function(event) {
|
|
||||||
$changeLoginDialog.modal('hide');
|
|
||||||
});
|
|
||||||
$changeLoginDialog.on('shown.bs.modal', function() {
|
|
||||||
$changeLoginDialog.find('#DFChangeLogin').focus().select();
|
|
||||||
});
|
|
||||||
|
|
||||||
//-------------------------------
|
|
||||||
//---- Reset Password Dialog ----
|
|
||||||
|
|
||||||
$btnResetPassword.on("click", function(event) {
|
|
||||||
if(dataTable.getSelectedRow() != null) {
|
|
||||||
$resetPasswordDialog.modal();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$resetPasswordDialog.find("#DFResetPasswordSave").on("click", function(event) {
|
|
||||||
if(dataTable.getSelectedRow() != null) {
|
|
||||||
$.post("data/User/update", {
|
|
||||||
id: dataTable.getSelectedRow().data("model").id,
|
|
||||||
password: $resetPasswordDialog.find("#DFResetPassword").val()
|
|
||||||
}, function(data) {
|
|
||||||
if(data.result == "success") {
|
|
||||||
$resetPasswordDialog.modal("hide");
|
|
||||||
dataTable.refresh();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alert(data.result);
|
|
||||||
}
|
|
||||||
}, "json");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$resetPasswordDialog.find("#DFResetPasswordCancel").on("click", function(event) {
|
|
||||||
$resetPasswordDialog.modal('hide');
|
|
||||||
});
|
|
||||||
$resetPasswordDialog.on('shown.bs.modal', function() {
|
|
||||||
$resetPasswordDialog.find('#DFResetPassword').focus();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
#venues {
|
#venues {
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user