645 lines
24 KiB
JavaScript
645 lines
24 KiB
JavaScript
|
|
/*
|
|
* AdminPanels.js was created solely for this theme.
|
|
* Author: AdminDesigns.com
|
|
*
|
|
*/
|
|
;
|
|
(function($, window, document, undefined) {
|
|
|
|
// Plugin definition.
|
|
$.fn.adminpanel = function(options) {
|
|
|
|
// Default plugin options.
|
|
var defaults = {
|
|
grid: '.admin-grid',
|
|
draggable: false,
|
|
mobile: false,
|
|
preserveGrid: false,
|
|
onPanel: function() {
|
|
console.log('callback:', 'onPanel');
|
|
},
|
|
onStart: function() {
|
|
console.log('callback:', 'onStart');
|
|
},
|
|
onSave: function() {
|
|
console.log('callback:', 'onSave');
|
|
},
|
|
onDrop: function() {
|
|
// An "onSave" callback will also be called if
|
|
// the drop also changes the elements DOM position
|
|
console.log('callback:', 'onDrop');
|
|
},
|
|
onFinish: function() {
|
|
console.log('callback:', 'onFinish');
|
|
},
|
|
};
|
|
|
|
// Extend default options.
|
|
var options = $.extend({}, defaults, options);
|
|
|
|
// Variables.
|
|
var plugin = $(this);
|
|
var pluginID = plugin.attr('id');
|
|
var pluginGrid = options.grid;
|
|
var dragSetting = options.draggable;
|
|
var mobileSetting = options.mobile;
|
|
var preserveSetting = options.preserveGrid;
|
|
var panels = plugin.find('.panel');
|
|
|
|
// HTML5 LocalStorage Keys
|
|
var settingsKey = 'panel-settings_' + location.pathname;
|
|
var positionsKey = 'panel-positions_' + location.pathname;
|
|
|
|
// HTML5 LocalStorage Gets
|
|
var settingsGet = localStorage.getItem(settingsKey);
|
|
var positionsGet = localStorage.getItem(positionsKey);
|
|
|
|
// Control Menu Click Handler
|
|
$('.panel').on('click', '.panel-controls > a', function(e) {
|
|
e.preventDefault();
|
|
|
|
// if a panel is being dragged disable menu clicks
|
|
if ($('body.ui-drag-active').length) {
|
|
return;
|
|
}
|
|
|
|
// determine appropriate event response
|
|
methods.controlHandlers.call(this, options);
|
|
});
|
|
|
|
var methods = {
|
|
init: function(options) {
|
|
var This = $(this);
|
|
|
|
// onStart callback
|
|
if (typeof options.onStart == 'function') {
|
|
options.onStart();
|
|
}
|
|
|
|
// Check onload to see if positions key is empty
|
|
if (!positionsGet) {
|
|
localStorage.setItem(positionsKey, methods.findPositions());
|
|
} else {
|
|
methods.setPositions();
|
|
}
|
|
|
|
// Check onload to see if settings key is empty
|
|
if (!settingsGet) {
|
|
localStorage.setItem(settingsKey, methods.modifySettings());
|
|
}
|
|
|
|
// Helper function that adds unique ID's to grid elements
|
|
$(pluginGrid).each(function(i, e) {
|
|
$(e).attr('id', 'grid-' + i);
|
|
});
|
|
|
|
// Check if empty columns should be preserved using an invisible panel
|
|
if (preserveSetting) {
|
|
var Panel = "<div class='panel preserve-grid'></div>";
|
|
$(pluginGrid).each(function(i, e) {
|
|
$(e).append(Panel);
|
|
});
|
|
}
|
|
|
|
// Prep admin panel/container prior to menu creation
|
|
methods.createControls(options);
|
|
|
|
// Create Mobile Menus
|
|
methods.createMobileControls(options);
|
|
|
|
// Loop through settings key and apply options to panels
|
|
methods.applySettings();
|
|
|
|
if (dragSetting === true) {
|
|
// Activate jQuery sortable on declared grids/panels
|
|
plugin.sortable({
|
|
items: plugin.find('.panel:not(".sort-disable")'),
|
|
connectWith: pluginGrid,
|
|
cursor: 'default',
|
|
revert: 250,
|
|
handle: '.panel-heading',
|
|
opacity: 1,
|
|
delay: 100,
|
|
tolerance: "pointer",
|
|
scroll: true,
|
|
placeholder: 'panel-placeholder',
|
|
forcePlaceholderSize: true,
|
|
forceHelperSize: true,
|
|
start: function(e, ui) {
|
|
$('body').addClass('ui-drag-active');
|
|
ui.placeholder.height(ui.helper.outerHeight() - 4);
|
|
},
|
|
beforeStop: function() {
|
|
// onMove callback
|
|
if (typeof options.onDrop == 'function') {
|
|
options.onDrop();
|
|
}
|
|
},
|
|
stop: function() {
|
|
$('body').removeClass('ui-drag-active');
|
|
},
|
|
update: function(event, ui) {
|
|
// toggle loading indicator
|
|
methods.toggleLoader();
|
|
|
|
// store the positions of the plugins */
|
|
methods.updatePositions(options);
|
|
}
|
|
});
|
|
}
|
|
|
|
// onFinish callback
|
|
if (typeof options.onFinish == 'function') {
|
|
options.onFinish();
|
|
}
|
|
},
|
|
createMobileControls: function(options) {
|
|
|
|
var controls = panels.find('.panel-controls');
|
|
|
|
var arr = {};
|
|
|
|
$.each(controls, function(i, e) {
|
|
var This = $(e);
|
|
var ID = $(e).parents('.panel').attr('id');
|
|
|
|
var controlW = This.width();
|
|
var titleW = This.siblings('.panel-title').width();
|
|
var headingW = This.parent('.panel-heading').width();
|
|
var mobile = (controlW + titleW);
|
|
arr[ID] = mobile;
|
|
});
|
|
console.log(arr)
|
|
|
|
$.each(arr, function(i, e) {
|
|
|
|
var This = $('#' + i);
|
|
var headingW = This.width() - 75;
|
|
var controls = This.find('.panel-controls');
|
|
|
|
if (mobileSetting === true || headingW < e) {
|
|
This.addClass('mobile-controls');
|
|
var options = {
|
|
html: true,
|
|
placement: "left",
|
|
content: function(e) {
|
|
var Content = $(this).clone();
|
|
return Content;
|
|
},
|
|
template: '<div data-popover-id="'+i+'" class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
|
|
}
|
|
controls.popover(options);
|
|
} else {
|
|
controls.removeClass('mobile-controls');
|
|
}
|
|
});
|
|
|
|
// Toggle mobile controls menu open on click
|
|
$('.mobile-controls .panel-heading > .panel-controls').on('click', function() {
|
|
$(this).toggleClass('panel-controls-open');
|
|
});
|
|
|
|
},
|
|
applySettings: function(options) {
|
|
|
|
// Variables.
|
|
var obj = this;
|
|
var localSettings = localStorage.getItem(settingsKey);
|
|
var parseSettings = JSON.parse(localSettings);
|
|
|
|
// Possible panel colors
|
|
var panelColors = "panel-primary panel-success panel-info panel-warning panel-danger panel-alert panel-system panel-dark panel-default";
|
|
|
|
// Pull localstorage obj, parse the data, and then loop
|
|
// through each panel and apply its given settings
|
|
$.each(parseSettings, function(i, e) {
|
|
|
|
$.each(e, function(i, e) {
|
|
var panelID = e['id'];
|
|
var panelTitle = e['title'];
|
|
var panelCollapsed = e['collapsed'];
|
|
var panelHidden = e['hidden'];
|
|
var panelColor = e['color'];
|
|
var Target = $('#' + panelID);
|
|
|
|
if (panelTitle) {
|
|
Target.children('.panel-heading').find('.panel-title').text(panelTitle);
|
|
}
|
|
if (panelCollapsed === 1) {
|
|
Target.addClass('panel-collapsed')
|
|
.children('.panel-body, .panel-menu, .panel-footer').hide();
|
|
}
|
|
if (panelColor) {
|
|
Target.removeClass(panelColors).addClass(panelColor).attr('data-panel-color', panelColor);
|
|
}
|
|
if (panelHidden === 1) {
|
|
Target.addClass('panel-hidden').hide().remove();
|
|
}
|
|
});
|
|
});
|
|
},
|
|
createControls: function(options) {
|
|
|
|
// List of available panel controls
|
|
var panelControls = '<span class="panel-controls"></span>';
|
|
var panelTitle = '<a href="#" class="panel-control-title"></a>';
|
|
var panelColor = '<a href="#" class="panel-control-color"></a>';
|
|
var panelCollapse = '<a href="#" class="panel-control-collapse"></a>';
|
|
var panelFullscreen = '<a href="#" class="panel-control-fullscreen"></a>';
|
|
var panelRemove = '<a href="#" class="panel-control-remove"></a>';
|
|
var panelCallback = '<a href="#" class="panel-control-callback"></a>';
|
|
var panelDock = '<a href="#" class="panel-control-dockable" data-toggle="popover" data-content="panelDockContent();"></a>';
|
|
var panelExpose = '<a href="#" class="panel-control-expose"></a>';
|
|
var panelLoader = '<a href="#" class="panel-control-loader"></a>';
|
|
|
|
panels.each(function(i, e) {
|
|
|
|
var This = $(e);
|
|
|
|
// Create panel menu container
|
|
var panelHeader = This.children('.panel-heading');
|
|
$(panelControls).appendTo(panelHeader);
|
|
|
|
// Check panel for settings specific attr. Use this
|
|
// value to determine if menu item should be displayed
|
|
var title = This.attr('data-panel-title');
|
|
var color = This.attr('data-panel-color');
|
|
var collapse = This.attr('data-panel-collapse');
|
|
var fullscreen = This.attr('data-panel-fullscreen');
|
|
var remove = This.attr('data-panel-remove');
|
|
var callback = This.attr('data-panel-callback');
|
|
var paneldock = This.attr('data-panel-dockable');
|
|
var expose = This.attr('data-panel-expose');
|
|
var loader = This.attr('data-panel-loader');
|
|
|
|
// attach loading indicator like any other button
|
|
if (!loader) {
|
|
// Create button
|
|
var panelMenu = panelHeader.find('.panel-controls');
|
|
$(panelLoader).appendTo(panelMenu);
|
|
}
|
|
// Upcoming feature, not currently implemented
|
|
if (expose) {
|
|
// Create button
|
|
var panelMenu = panelHeader.find('.panel-controls');
|
|
$(panelExpose).appendTo(panelMenu);
|
|
}
|
|
// Upcoming feature, not currently implemented
|
|
if (paneldock) {
|
|
// Create button
|
|
var panelMenu = panelHeader.find('.panel-controls');
|
|
$(panelDock).appendTo(panelMenu);
|
|
}
|
|
// callback attr must be set true, else icon hidden
|
|
if (callback) {
|
|
// Create button
|
|
var panelMenu = panelHeader.find('.panel-controls');
|
|
$(panelCallback).appendTo(panelMenu);
|
|
}
|
|
if (!remove) {
|
|
// Create button
|
|
var panelMenu = panelHeader.find('.panel-controls');
|
|
$(panelRemove).appendTo(panelMenu);
|
|
}
|
|
if (!title) {
|
|
// Create button
|
|
var panelMenu = panelHeader.find('.panel-controls');
|
|
$(panelTitle).appendTo(panelMenu);
|
|
}
|
|
if (!color) {
|
|
var panelMenu = panelHeader.find('.panel-controls');
|
|
$(panelColor).appendTo(panelMenu);
|
|
}
|
|
if (!collapse) {
|
|
// Create button
|
|
var panelMenu = panelHeader.find('.panel-controls');
|
|
$(panelCollapse).appendTo(panelMenu);
|
|
}
|
|
if (!fullscreen) {
|
|
// Create button
|
|
var panelMenu = panelHeader.find('.panel-controls');
|
|
$(panelFullscreen).appendTo(panelMenu);
|
|
}
|
|
|
|
});
|
|
},
|
|
controlHandlers: function(e) {
|
|
|
|
var This = $(this);
|
|
|
|
// Control button indentifiers
|
|
var action = This.attr('class');
|
|
var panel = This.parents('.panel');
|
|
|
|
// Panel header variables
|
|
var panelHeading = panel.children('.panel-heading');
|
|
var panelTitle = panel.find('.panel-title');
|
|
|
|
// Edit Title definition
|
|
var panelEditTitle = function() {
|
|
|
|
// function for toggling the editbox menu
|
|
var toggleBox = function() {
|
|
var panelEditBox = panel.find('.panel-editbox');
|
|
panelEditBox.slideToggle('fast', function() {
|
|
panel.toggleClass('panel-editbox-open');
|
|
|
|
// Save settings to key if editbox is being closed
|
|
if (!panel.hasClass('panel-editbox-open')) {
|
|
panelTitle.text(panelEditBox.children('input').val());
|
|
methods.updateSettings(options);
|
|
}
|
|
});
|
|
};
|
|
|
|
// If editbox not found, create one and attach handlers
|
|
if (!panel.find('.panel-editbox').length) {
|
|
var editBox = '<div class="panel-editbox"><input type="text" class="form-control" value="' + panelTitle.text() + '"></div>';
|
|
panelHeading.after(editBox);
|
|
|
|
// New editbox container
|
|
var panelEditBox = panel.find('.panel-editbox');
|
|
|
|
// Update panel title on key up
|
|
panelEditBox.children('input').on('keyup', function() {
|
|
panelTitle.text(panelEditBox.children('input').val());
|
|
});
|
|
|
|
// Save panel title on enter key press
|
|
panelEditBox.children('input').on('keypress', function(e) {
|
|
if (e.which == 13) {
|
|
toggleBox();
|
|
}
|
|
});
|
|
|
|
// Toggle editbox
|
|
toggleBox();
|
|
} else {
|
|
// If found simply toggle the menu
|
|
toggleBox();
|
|
}
|
|
};
|
|
|
|
// Panel color definition
|
|
var panelColor = function() {
|
|
|
|
// Create an editbox if one is not found
|
|
if (!panel.find('.panel-colorbox').length) {
|
|
var colorBox = '<div class="panel-colorbox"> <span class="bg-white" data-panel-color="panel-default"></span> <span class="bg-primary" data-panel-color="panel-primary"></span> <span class="bg-info" data-panel-color="panel-info"></span> <span class="bg-success" data-panel-color="panel-success"></span> <span class="bg-warning" data-panel-color="panel-warning"></span> <span class="bg-danger" data-panel-color="panel-danger"></span> <span class="bg-alert" data-panel-color="panel-alert"></span> <span class="bg-system" data-panel-color="panel-system"></span> <span class="bg-dark" data-panel-color="panel-dark"></span> </div>'
|
|
panelHeading.after(colorBox);
|
|
}
|
|
|
|
// Editbox container
|
|
var panelColorBox = panel.find('.panel-colorbox');
|
|
|
|
// Update panel contextual color on click
|
|
panelColorBox.on('click', '> span', function(e) {
|
|
var dataColor = $(this).data('panel-color');
|
|
var altColors = 'panel-primary panel-info panel-success panel-warning panel-danger panel-alert panel-system panel-dark panel-default panel-white';
|
|
panel.removeClass(altColors).addClass(dataColor).data('panel-color', dataColor)
|
|
methods.updateSettings(options);
|
|
});
|
|
|
|
// Toggle elements visability and '.panel-editbox' class
|
|
// If the box is being closed update settings key
|
|
panelColorBox.slideToggle('fast', function() {
|
|
panel.toggleClass('panel-colorbox-open');
|
|
});
|
|
|
|
};
|
|
|
|
// Collapse definition
|
|
var panelCollapse = function() {
|
|
|
|
// Toggle class
|
|
panel.toggleClass('panel-collapsed');
|
|
|
|
// Toggle elements visability
|
|
panel.children('.panel-body, .panel-menu, .panel-footer').slideToggle('fast', function() {
|
|
methods.updateSettings(options);
|
|
});
|
|
};
|
|
|
|
// Fullscreen definition
|
|
var panelFullscreen = function() {
|
|
// If fullscreen mode is active, remove class and enable panel sorting
|
|
if ($('body.panel-fullscreen-active').length) {
|
|
$('body').removeClass('panel-fullscreen-active');
|
|
panel.removeClass('panel-fullscreen');
|
|
if (dragSetting === true) {
|
|
plugin.sortable("enable");
|
|
}
|
|
}
|
|
// if not active add fullscreen classes and disable panel sorting
|
|
else {
|
|
$('body').addClass('panel-fullscreen-active');
|
|
panel.addClass('panel-fullscreen');
|
|
if (dragSetting === true) {
|
|
plugin.sortable("disable");
|
|
}
|
|
}
|
|
|
|
// Hide any open mobile menus or popovers
|
|
$('.panel-controls').removeClass('panel-controls-open');
|
|
$('.popover').popover('hide');
|
|
|
|
// Trigger a global window resize to resize any plugins
|
|
// the fullscreened content might contain.
|
|
setTimeout(function() {
|
|
$(window).trigger('resize');
|
|
}, 100);
|
|
};
|
|
|
|
// Remove definition
|
|
var panelRemove = function() {
|
|
|
|
// check for Bootbox plugin - should be in core
|
|
if (bootbox.confirm) {
|
|
bootbox.confirm("Are You Sure?!", function(e) {
|
|
|
|
// e returns true if user clicks "accept"
|
|
// false if "cancel" or dismiss icon are clicked
|
|
if (e) {
|
|
// Timeout simply gives the user a second for the modal to
|
|
// fade away so they can visibly see the panel disappear
|
|
setTimeout(function() {
|
|
panel.addClass('panel-removed').hide();
|
|
methods.updateSettings(options);
|
|
}, 200);
|
|
}
|
|
|
|
});
|
|
} else {
|
|
panel.addClass('panel-removed').hide();
|
|
methods.updateSettings(options);
|
|
}
|
|
};
|
|
|
|
// Remove definition
|
|
var panelCallback = function() {
|
|
if (typeof options.onPanel == 'function') {
|
|
options.onPanel();
|
|
}
|
|
};
|
|
|
|
// Expose.js definition
|
|
var panelExpose = function() {
|
|
// Code removed, feature will be added to next update
|
|
// once all of the dynamic/responsive aspects of resizing
|
|
// an exposed panel are worked out
|
|
};
|
|
|
|
// Responses
|
|
if ($(this).hasClass('panel-control-collapse')) {
|
|
panelCollapse();
|
|
}
|
|
if ($(this).hasClass('panel-control-title')) {
|
|
panelEditTitle();
|
|
}
|
|
if ($(this).hasClass('panel-control-color')) {
|
|
panelColor();
|
|
}
|
|
if ($(this).hasClass('panel-control-fullscreen')) {
|
|
panelFullscreen();
|
|
}
|
|
if ($(this).hasClass('panel-control-remove')) {
|
|
panelRemove();
|
|
}
|
|
if ($(this).hasClass('panel-control-callback')) {
|
|
panelCallback();
|
|
}
|
|
if ($(this).hasClass('panel-control-expose')) {
|
|
panelExpose();
|
|
}
|
|
if ($(this).hasClass('panel-control-dockable')) {
|
|
return
|
|
}
|
|
if ($(this).hasClass('panel-control-loader')) {
|
|
return;
|
|
}
|
|
|
|
// Toggle Loader indicator in response to action
|
|
methods.toggleLoader.call(this);
|
|
|
|
},
|
|
toggleLoader: function(options) {
|
|
var This = $(this);
|
|
var panel = This.parents('.panel');
|
|
|
|
// Add loader to panel
|
|
panel.addClass('panel-loader-active');
|
|
|
|
// Remove loader after specified duration
|
|
setTimeout(function() {
|
|
panel.removeClass('panel-loader-active');
|
|
}, 650);
|
|
|
|
},
|
|
modifySettings: function(options) {
|
|
|
|
// Settings obj
|
|
var settingsArr = [];
|
|
|
|
// Determine settings of each panel.
|
|
panels.each(function(i, e) {
|
|
|
|
var This = $(e);
|
|
var panelObj = {};
|
|
|
|
// Settings variables.
|
|
var panelID = This.attr('id');
|
|
var panelTitle = This.children('.panel-heading').find('.panel-title').text();
|
|
var panelCollapsed = (This.hasClass('panel-collapsed') ? 1 : 0);
|
|
var panelHidden = (This.is(':hidden') ? 1 : 0);
|
|
var panelColor = This.data('panel-color');
|
|
|
|
panelObj['id'] = This.attr('id');
|
|
panelObj['title'] = This.children('.panel-heading').find('.panel-title').text();
|
|
panelObj['collapsed'] = (This.hasClass('panel-collapsed') ? 1 : 0);
|
|
panelObj['hidden'] = (This.is(':hidden') ? 1 : 0);
|
|
panelObj['color'] = (panelColor ? panelColor : null);
|
|
|
|
settingsArr.push({
|
|
'panel': panelObj
|
|
});
|
|
});
|
|
|
|
var checkedSettings = JSON.stringify(settingsArr);
|
|
|
|
// Log Results
|
|
// console.log('Key contains: ', checkedSettings);
|
|
|
|
// return panel positions array
|
|
return checkedSettings;
|
|
},
|
|
findPositions: function(options) {
|
|
|
|
var grids = plugin.find(pluginGrid);
|
|
var gridsArr = [];
|
|
|
|
// Determine panels present.
|
|
grids.each(function(index, ele) {
|
|
|
|
var panels = $(ele).find('.panel');
|
|
var panelArr = [];
|
|
|
|
$(ele).attr('id', 'grid-' + index);
|
|
|
|
panels.each(function(i, e) {
|
|
var panelID = $(e).attr('id');
|
|
panelArr.push(panelID);
|
|
});
|
|
|
|
gridsArr[index] = panelArr;
|
|
});
|
|
|
|
var checkedPosition = JSON.stringify(gridsArr);
|
|
|
|
// return panel positions array
|
|
return checkedPosition;
|
|
|
|
},
|
|
setPositions: function(options) {
|
|
|
|
// Variables
|
|
var obj = this;
|
|
var localPositions = localStorage.getItem(positionsKey);
|
|
var parsePosition = JSON.parse(localPositions);
|
|
|
|
// Pull localstorage obj, parse the data, and then loop
|
|
// through each panel and set its position
|
|
$(pluginGrid).each(function(i, e) {
|
|
var rowID = $(e)
|
|
$.each(parsePosition[i], function(i, ele) {
|
|
$('#' + ele).appendTo(rowID);
|
|
});
|
|
});
|
|
},
|
|
updatePositions: function(options) {
|
|
localStorage.setItem(positionsKey, methods.findPositions());
|
|
|
|
// onSave callback
|
|
if (typeof options.onSave == 'function') {
|
|
options.onSave();
|
|
}
|
|
},
|
|
updateSettings: function(options) {
|
|
localStorage.setItem(settingsKey, methods.modifySettings());
|
|
|
|
// onSave callback
|
|
if (typeof options.onSave == 'function') {
|
|
options.onSave();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Plugin implementation
|
|
return this.each(function() {
|
|
methods.init.call(plugin, options);
|
|
});
|
|
|
|
};
|
|
|
|
})(jQuery, window, document);
|