2 Commits

Author SHA1 Message Date
21cd43c4cb Add selectall checkbox handling 2012-04-28 23:21:31 +01:00
49e8206aff Merge commit 'release-0.1.0' into develop 2012-01-22 01:15:11 +00:00

View File

@@ -1,34 +1,34 @@
/**
* 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 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
*/
* Sihnon Framework object
*
* Entry point for all base framework code
*/
var sf = {
/**
* Library version
*
*/
* Library version
*
*/
version: '0.1.0',
/**
* Initialises the library
*
*/
* Initialises the library
*
*/
init: function() {
// Initialise all modules
@@ -47,26 +47,26 @@ var sf = {
},
/**
* Utility module
*
* Contains simple and one-off functions that aren't worth grouping into full modules
*/
* Utility module
*
* Contains simple and one-off functions that aren't worth grouping into full modules
*/
utility: {
/**
* Initialise the module
*/
* 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
*/
* 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;
@@ -78,29 +78,29 @@ var sf = {
},
/**
* Code for making and handling AJAX requests
*/
* Code for making and handling AJAX requests
*/
ajax: {
/**
* Initialise the module
*/
* 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
*/
* 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,
@@ -112,18 +112,18 @@ var sf = {
},
/**
* 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
*/
* 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,
@@ -136,15 +136,15 @@ var sf = {
},
/**
* 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
*/
* 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
@@ -165,59 +165,60 @@ var sf = {
},
/**
* User Interface module
*
* Code for manipulating UI elements
*/
* User Interface module
*
* Code for manipulating UI elements
*/
ui: {
/**
* Initialise the module
*/
* Initialise the module
*/
init: function() {
sf.ui.dialog.init();
sf.ui.selectall.init();
},
/**
* Submodule for customising and displaying the app dialog
*/
* Submodule for customising and displaying the app dialog
*/
dialog: {
/**
* Initialise the submodule
*/
* Initialise the submodule
*/
init: function() {
// Permanently configure the X to close the dialog
$("#dialog-header-close").click(sf.ui.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 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;
@@ -272,9 +273,9 @@ var sf = {
},
/**
* Immediately show a pre-configured dialog
*
*/
* Immediately show a pre-configured dialog
*
*/
show: function() {
$("#dialog").modal({
show: true,
@@ -284,12 +285,12 @@ var sf = {
},
/**
* Close the dialog and reset to default values
*
* The content and title will be removed, all buttons hidden
* and all action handlers removed.
*
*/
* 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({
@@ -306,16 +307,16 @@ var sf = {
},
/**
* 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.
*/
* 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 = $('<div>').append($('<p>').text('content'));
if (messages) {
@@ -341,54 +342,86 @@ var sf = {
},
},
/**
* Submodule for handling select-all checkbox groups
*/
selectall: {
init: function() {
// Enable select all/none for checkboxes
$('input[type=checkbox].select-all').click(sf.ui.selectall.updateChildren);
// Enable update of the select-all checkbox as the children are manually changed
$('input[type=checkbox].select-all').each(function() {
$('input[type=checkbox][data-select-all="' + $(this).attr('id') + '"]').click(sf.ui.selectall.updateParent);
});
},
updateChildren: function(parent_id, children) {
$('input[type=checkbox][data-select-all="'+$(this).attr('id')+'"]')
.attr('checked', $(this).attr('checked') == 'checked')
.trigger('change');
},
updateParent: function() {
var parent = $('#' + $(this).attr('data-select-all'));
var children = $('input[type=checkbox][data-select-all="' + parent.attr('id') + '"]');
if (children.filter(':checked').length != children.length) {
parent.attr('checked', false);
} else if (children.not(':checked').length == 0) {
parent.attr('checked', true);
}
},
},
},
/**
* Page module
*
* Code for updating page content
*/
* Page module
*
* Code for updating page content
*/
page: {
/**
* List of callbacks to be executed on a new section of a page
*
* Used for setting up any behaviour on new page elements, such as when a page is
* first loaded, or replaced by an ajax call.
*
* Callbacks should have the form:
* function(d){}
* where d is the top level dom element being updated.
*
* New callbacks can be registered with addUpdateCallback() passing a unique name
* which can be used for later removing a callback if desired.
*/
* List of callbacks to be executed on a new section of a page
*
* Used for setting up any behaviour on new page elements, such as when a page is
* first loaded, or replaced by an ajax call.
*
* Callbacks should have the form:
* function(d){}
* where d is the top level dom element being updated.
*
* New callbacks can be registered with addUpdateCallback() passing a unique name
* which can be used for later removing a callback if desired.
*/
update_callbacks: {
},
/**
* Initialise module
*/
* Initialise module
*/
init: function() {
},
/**
* Updates all given subsets of the page
*
* Takes an object defining the replacements to be made and updates the page
*
* Object should use a DOM ID as the key, and replacement content should sit under a content key, e.g.:
*
* replacements = {
* page_content: {
* content: 'This will replace the entire page!',
* },
* }
*
* @param replacements Object containing replacements to make
*/
* Updates all given subsets of the page
*
* Takes an object defining the replacements to be made and updates the page
*
* Object should use a DOM ID as the key, and replacement content should sit under a content key, e.g.:
*
* replacements = {
* page_content: {
* content: 'This will replace the entire page!',
* },
* }
*
* @param replacements Object containing replacements to make
*/
update: function(replacements) {
for ( var id in replacements) {
$("#" + id).html(replacements[id].content);
@@ -397,13 +430,13 @@ var sf = {
},
/**
* Update a subset of the page content with any global events
*
* Called when the element d has been updated and callbacks need to be applied to
* the new content.
*
* @param elements ID or DOM element of the new content on which events need to be applied
*/
* Update a subset of the page content with any global events
*
* Called when the element d has been updated and callbacks need to be applied to
* the new content.
*
* @param elements ID or DOM element of the new content on which events need to be applied
*/
updateEvents: function(d) {
for (var c in sf.page.update_callbacks) {
sf.page.update_callbacks[c](d);
@@ -411,29 +444,29 @@ var sf = {
},
/**
* Add new page update callback
*
* Defines a new function to be run when part of the page is updated.
* This function will replace any previous callback registered with the same name.
*
* See also: sf.page.update_callbacks
*
* @param name Unique name of the callback for later retrieval
* @param callback Function to call
*/
* Add new page update callback
*
* Defines a new function to be run when part of the page is updated.
* This function will replace any previous callback registered with the same name.
*
* See also: sf.page.update_callbacks
*
* @param name Unique name of the callback for later retrieval
* @param callback Function to call
*/
addCallback: function(name, callback) {
sf.page.update_callbacks[name] = callback;
},
/**
* Remove a page update callback
*
* Removes a previously defined callback from the list of page update callbacks.
*
* See also: sf.page.update_callbacks
*
* @param name Unique name of the callback to be removed
*/
* Remove a page update callback
*
* Removes a previously defined callback from the list of page update callbacks.
*
* See also: sf.page.update_callbacks
*
* @param name Unique name of the callback to be removed
*/
removeCallback: function(name) {
if (sf.page.update_callback[name]) {
delete sf.page.update_callbacks[name];
@@ -443,27 +476,27 @@ var sf = {
},
/**
* Actions module
*
* Defines a list of named callbacks which can be executed from a non-trusted source
* such as an ajax response without requiring code evaluation.
*/
* Actions module
*
* Defines a list of named callbacks which can be executed from a non-trusted source
* such as an ajax response without requiring code evaluation.
*/
actions: {
/**
* List of named callbacks that can be executed
*
* Callbacks should have the form:
* function(params){}
* where params is an action-specific list of parameters passed as an object.
* The callback should return a boolean to indicate success.
*
* New callbacks can be registered with addAction() passing a unique name
* which can be used for later removing an action if desired with removeAction().
*
* Actions can be triggered manually using the trigger() method. A list of actions
* can be triggered in one go using triggerAll().
*/
* List of named callbacks that can be executed
*
* Callbacks should have the form:
* function(params){}
* where params is an action-specific list of parameters passed as an object.
* The callback should return a boolean to indicate success.
*
* New callbacks can be registered with addAction() passing a unique name
* which can be used for later removing an action if desired with removeAction().
*
* Actions can be triggered manually using the trigger() method. A list of actions
* can be triggered in one go using triggerAll().
*/
callbacks: {
'close-dialog': function(params) {
@@ -473,21 +506,21 @@ var sf = {
},
/**
* Initialise the module
*/
* Initialise the module
*/
init: function() {
},
/**
* Execute a named action
*
* Runs one or more named actions with the list of parameters provided
* All actions are run with the same parameters.
*
* @param names Names of the action(s) to execute
* @param params Object containing action specific parameters
*/
* Execute a named action
*
* Runs one or more named actions with the list of parameters provided
* All actions are run with the same parameters.
*
* @param names Names of the action(s) to execute
* @param params Object containing action specific parameters
*/
trigger: function(names, params) {
if ( ! (names instanceof Array)) {
names = [names];
@@ -501,10 +534,10 @@ var sf = {
},
/**
* Executes all given actions
*
* @param actions Object containing names of all actions to execute with associated parameters
*/
* Executes all given actions
*
* @param actions Object containing names of all actions to execute with associated parameters
*/
triggerAll: function(actions) {
for (var action in actions) {
sf.actions.trigger(action, actions[action]);
@@ -512,25 +545,25 @@ var sf = {
},
/**
* Adds a new named action
*
* Defines a new named action to be run when manually triggered.
* This function will replace any previous action registered with the same name.
*
* See also: sf.actions.callbacks
*
* @param name Name of the new action
* @param callback Function to execute when this callback is triggered
*/
* Adds a new named action
*
* Defines a new named action to be run when manually triggered.
* This function will replace any previous action registered with the same name.
*
* See also: sf.actions.callbacks
*
* @param name Name of the new action
* @param callback Function to execute when this callback is triggered
*/
addAction: function(name, callback) {
sf.actions.callbacks[name] = callback;
},
/**
* Removes a previously registered named action
*
* @param name Name of the action to remove
*/
* Removes a previously registered named action
*
* @param name Name of the action to remove
*/
removeAction: function(name) {
if (sf.actions.callbacks[name]) {
delete sf.actions.callbacks[name];