diff --git a/public/sihnon-framework.js b/public/sihnon-framework.js new file mode 100644 index 0000000..ab8a205 --- /dev/null +++ b/public/sihnon-framework.js @@ -0,0 +1,537 @@ +/** + * Sihnon Framework JS Library + * + * Written by Ben Roberts + * Homepage: https://benroberts.net/projects/sihnon-framework/ + * Code: https://github.com/optiz0r/sihnon-js-lib/ + * + * Dependencies: + * - Bootstrap-*.js + * + * Released under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License + * http://creativecommons.org/licenses/by-nc-sa/3.0/ + */ + +/** + * Sihnon Framework object + * + * Entry point for all base framework code + */ +var sf = { + + /** + * Initialises the library + * + */ + init: function() { + + // Initialise all modules + modules = [ + 'utility', + 'ajax', + 'ui', + 'page', + 'actions', + ]; + + for (var module in modules) { + sf[module].init(); + } + + }, + + /** + * Utility module + * + * Contains simple and one-off functions that aren't worth grouping into full modules + */ + utility: { + + /** + * Initialise the module + */ + init: function() { + + }, + + /** + * Returns conditional if set to a value, else returns alternative + * + * @param conditional Value to test and return if set + * @param alternative Value to return if conditional is not set + * @returns + */ + orelse: function(conditional, alternative) { + if (typeof conditional != 'undefined') { + return conditional; + } else { + return alternative; + } + }, + + }, + + /** + * Code for making and handling AJAX requests + */ + ajax: { + + /** + * Initialise the module + */ + init: function() { + + }, + + /** + * Launch a simple AJAX GET request + * + * Makes an AJAX request to the specified URL and calls one of the given + * functions on completion. Default callbacks are executed if not provided. + * + * See also: sf.ajax.success, sf.ajax.failure + * + * @param url URL to request + * @param success Callback to execute on success + * @param failure Callback to execute on failure + */ + get: function(url, success, failure) { + $.ajax({ + url: url, + type: "GET", + dataType: "json", + success: sf.utility.orelse(success, sf.ajax.success), + error: sf.utility.orelse(failure, sf.ajax.failure), + }); + }, + + /** + * Launch a simple AJAX POST request + * + * Makes an AJAX request to the specified URL and calls one of the given + * functions on completion. Default callbacks are executed if not provided. + * + * See also: sf.ajax.success, sf.ajax.failure + * + * @param url URL to request + * @param data Data to send with the request + * @param success Callback to execute on success + * @param failure Callback to execute on failure + */ + post: function(url, data, success, failure) { + $.ajax({ + url: url, + type: "POST", + dataType: "json", + data: data, + success: sf.utility.orelse(success, sf.ajax.success), + error: sf.utility.orelse(failure, sf.ajax.failure), + }); + }, + + /** + * Default success handler + * + * Function that will be called for every successful AJAX request if no custom + * handler is defined. + * + * @param d Data returned from the request + * @param s Status of the request + * @param x XHttpRequest object used for the request + */ + success: function(d, s, x) { + + // Replace any requested parts of the page + sf.page.update(d.page_replacements); + + // Show any requested dialog + sf.ui.dialog.prepare(d.dialog); + + // Trigger any actions + sf.actions.triggerAll(d.actions); + }, + + failure: function(x, s, e) { + console.log("Ajax Failure: " + s, e); + console.log(x.responseText); + }, + + }, + + /** + * User Interface module + * + * Code for manipulating UI elements + */ + ui: { + + /** + * Initialise the module + */ + init: function() { + sf.ui.dialog.init(); + }, + + /** + * Submodule for customising and displaying the app dialog + */ + dialog: { + + /** + * Initialise the submodule + */ + init: function() { + // Permanently configure the X to close the dialog + $("#dialog-header-close").click(sf.dialog.close); + }, + + /** + * Prepare a dialog and optionally show it. + * + * Parameters should be an object which may contain any of the following fields: + * var parameters = { + * show: bool, // Show the dialog immediately after configuring + * title: string, // Title to display in the dialog header + * content: string, // Body of the dialog as HTML + * buttons: { // Configuration for the buttons in the dialog footer, see below + * type: ok|okcancel|yesno, // Type of buttons to display in the footer + * params: mixed, // Any data to be passed directly to the action handlers + * actions: { + * ok: string, // Action handler to be assigned to the OK button + * cancel: string, // Action handler to be assigned to the Cancel button + * yes: string, // Action handler to be assigned to the Yes button + * no: string, // Action handler to be assigned to the No button + * } + * } + * } + * + * var buttons = { + * type: ok|okcancel|yesno + * } + * + * + * @param p Parameters for configuring the dialog + */ + prepare: function(p) { + if ( ! p) { + return; + } + + if (p.buttons) { + switch (p.buttons.type) { + case 'ok': + $("#dialog-footer-ok-ok").click( + function() { + sf.actions.trigger(p.buttons.actions.ok, p.buttons.params); + } + ); + $("#dialog-footer-ok").show(); + break; + case 'okcancel': + $("#dialog-footer-okcancel-ok").click(function() { + sf.actions.trigger(p.buttons.actions.ok, p.buttons.params); + }); + $("#dialog-footer-okcancel-cancel").click(function() { + sf.actions.trigger(p.buttons.actions.cancel, p.buttons.params); + }); + $("#dialog-footer-okcancel").show(); + break; + case 'yesno': + $("#dialog-footer-yesno-yes").click( + function() { + sf.actions.trigger(p.buttons.actions.yes, p.buttons.params); + } + ); + $("#dialog-footer-yesno-no").click( + function() { + sf.actions.trigger(p.buttons.actions.no, p.buttons.params); + } + ); + $("#dialog-footer-yesno").show(); + break; + } + } + + if (p.title) { + $('#dialog-header-title').html(p.title); + } + + if (p.content) { + $('#dialog-body').html(p.content); + } + + if (p.show) { + sf.ui.dialog.show(); + } + }, + + /** + * Immediately show a pre-configured dialog + * + */ + show: function() { + $("#dialog").modal({ + show: true, + backdrop: true, + keyboard: true, + }); + }, + + /** + * Close the dialog and reset to default values + * + * The content and title will be removed, all buttons hidden + * and all action handlers removed. + * + */ + close: function() { + // Hide the dialog + $("#dialog").modal({ + show: false, + }); + + // Remove the dialog content + $("#dialog-body").html(''); + + // Hide all buttons + $(".dialog-footer-buttonset").hide(); + // Strip all event handlers + $(".dialog-footer-buttonset input[type='button']").unbind('click'); + }, + + /** + * Use the built-in dialog to display an error message + * + * Prepares the dialog with a pre-defined format using the details provided. + * The dialog is immediately shown with an OK button that cancels the dialog and + * takes no further action + * + * @param title Title for the error dialog + * @param content Content for the dialog + * @param messages An optional list of messages to be reported on the dialog, e.g. reasons for the failure described by content. + */ + error: function(title, content, messages) { + var formatted_content = $('
').append($('

').text('content')); + if (messages) { + var formatted_messages = $('