Skip to content

Instantly share code, notes, and snippets.

@patrickatwsrn
Last active May 10, 2021 15:01
Show Gist options
  • Save patrickatwsrn/c75280efbc9e062d4b42b2e97edca391 to your computer and use it in GitHub Desktop.
Save patrickatwsrn/c75280efbc9e062d4b42b2e97edca391 to your computer and use it in GitHub Desktop.
Add breakpoint navagation buttons to your website if you are logged into the modx manager

Bootstrap Breakpoints Toolbar for MODX

Usage

  • If you are using modx, you can store this code inside a chunk and add the chunk to the bottom of a template

Restrict Access

If you want access to the toolbar in some way, you can use an output filter to check for a loggin

[[[[!+modx.user.id:userinfo=`username`:is=`admin`:then=`$bootstrap_breakpoints`:else=``]]]]

You use MODX

If you are using this script inside MODX, this script will update the link to your edit page automatically if you use it inside a chunk.

var editURL = "[[++site_url]]manager/?a=resource/update&id=[[*id]]";

You don't use MODX?

Pitty, but set editURL to or build somthing to fit your needs.

[[!+modx.user.id:userinfo=`username`:is=`pepebe`:then=``:else=``]]
<script>
var buttons = {
xs: {
minWidth: "0"
,onClass: "d-block d-sm-none"
,offClass: "d-none d-sm-block"
}
,sm: {
minWidth: "576px"
,onClass: "d-none d-sm-block d-md-none"
,offClass: "d-sm-none d-md-block"
}
,md: {
minWidth: "768px"
,onClass: "d-none d-md-block d-lg-none"
,offClass: "d-md-none d-lg-block"
}
,lg: {
minWidth: "992px"
,onClass: "d-none d-lg-block d-xl-none"
,offClass: "d-lg-none d-xl-block"
}
,xl: {
minWidth: "1200px"
,onClass: "d-none d-xl-block d-xxl-none"
,offClass: "d-xl-none d-xxl-block"
}
,xxl: {
minWidth: ""
,onClass: "d-none d-xxl-block"
,offClass: "d-xxl-none"
}
}
function addBreakpointsToolbar(){
console.log('addBreakpointsToolbar()');
var html = ''
+ ' <div id="breakpointToolbar" style="position: fixed; bottom: 10px; left: 10px;">'
+ ' <div class="btn-toolbar" role="toolbar" aria-label="Trigger bootstrap breakpoints">'
+ ' <div class="btn-group" role="group" aria-label="Presets">'
+ ' </div>'
+ ' </div>'
+ ' </div>';
$("body").append(html);
}
function addOpenNewWindow(){
console.log('addOpenNewWindow()');
var html = ''
+ ' <div id="openNewWindow" class="btn-group btn-group-sm me-1" role="group">'
+ ' <button type="button" class="btn btn-secondary">Open in new Window</button>'
+ ' </div>';
$("#breakpointToolbar > .btn-toolbar > .btn-group").append(html);
}
function addToggleBreakpoints(){
console.log('addToggleBreakpoints()');
var html = ''
+ ' <div id="toggleBreakpoints" class="btn-group btn-group-sm me-1" role="group">'
+ ' <button type="button" name="max" class="btn btn-secondary">max</button>'
+ ' </div>';
$("#breakpointToolbar > .btn-toolbar > .btn-group").append(html);
}
function addEditManagerLink(editURL){
console.log('addEditManagerLink()');
var html = ''
+ ' <div id="editManagerLink" class="btn-group btn-group-sm me-1" role="group">'
+ ' <a class="btn btn-secondary" title="Edit Page" href="' + editURL + '" target="_editPage">'
+ ' <i class="fa fa-pencil" aria-hidden="true"></i>'
+ ' </a>'
+ ' </div>'
$('#breakpointToolbar > .btn-toolbar > .btn-group').prepend(html);
}
function createButtons(buttons,editURL) {
var toggleButtons = "";
for (var key in buttons) {
console.log(key);
var onClass = buttons[key]['onClass'];
var offClass = buttons[key]['offClass'];
console.log('onClass: ' + onClass);
console.log('offClass: ' + offClass);
var btnPair = "";
var btnOn = "<button type='button' name='" + key + "' class='btn btn-primary " + onClass + "'>" + key + "</button>";
var btnOff = "<button type='button' name='" + key + "' class='btn btn-secondary " + offClass + "'>" + key + "</button>";
btnPair = btnOn + btnOff;
toggleButtons += btnPair;
}
$("#toggleBreakpoints").prepend(toggleButtons);
}
function updateBreakpointClass(){
// add current breakpoint to html class attribute
var activeButton = $('#toggleBreakpoints button.btn-primary').not(':hidden');
var activeBreakpoint = $(activeButton).attr('name');
console.log('currentBreakpoint: ' + activeBreakpoint);
$('html').removeClass('xs sm md lg xl xxl').addClass(activeBreakpoint);
}
function updateButtons(buttons){
//console.log('fn:updateButtons');
// add pixel sizes to button elements and remove buttons that are not covered
$('#toggleBreakpoints button').each(function(){
let breakpoint = $(this).attr('name');
if(breakpoint in buttons){
minWidth = buttons[breakpoint]['minWidth'];
$(this).attr('title', 'min-width: ' + minWidth.trim());
var width = parseInt(buttons[breakpoint]['minWidth']);
var height = window.screen.availHeight;
$(this).attr('data-width', width )
$(this).attr('data-height', height )
}
else if(breakpoint == 'max'){
// do nothing
}
else {
$(this).remove();
}
});
}
function calculateBreakpoints(buttons){
/* grab computed styles from body element
* :root {
* --breakpoint-xs: 0;
* --breakpoint-sm: 576px;
* --breakpoint-md: 768px;
* --breakpoint-lg: 992px;
* --breakpoint-xl: 1200px;
* --beakpoint-xxl: 1400px;
* }
*
* if breakpoint can't be found, fall back to generic breakpoints.
* */
let style = getComputedStyle(document.body)
// Note: Currently xxl is not present in many bootstrap versions.
// You might want to change the value from empty to 1400px
breakpointInRoot = false;
// build object including all --breakpoint-xx styles
for (var key in buttons) {
breakpoint = style.getPropertyValue('--breakpoint-' + key);
if(breakpoint !== ""){
breakpointInRoot = true;
buttons[key]['minWidth'] = breakpoint.trim();
}
else {
console.log("Breakpoint " + key + " not found. Using default: " + buttons[key]['minWidth']);
// delete buttons[key];
}
}
if(breakpointInRoot == false){
console.log("Couldn't find breakpoints inside root element. Using default breakpoints")
}
return buttons;
}
$(function() {
var editURL = "[[++site_url]]manager/?a=resource/update&id=[[*id]]";
var initialWidth = window.screen.availWidth + 40;
var halfWidth = initialWidth / 2;
var left = halfWidth;
var windowName = 'MODXDebug';
var windowFeatures = "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + left + ",width=" + halfWidth;
// Important: Resizing a window is not possible if other windows (tabs) are present
if(window.name != windowName){
addBreakpointsToolbar();
if(editURL !== false){
addEditManagerLink(editURL);
}
addOpenNewWindow();
$('#openNewWindow button').on('click', function() {
var windowUrl = "[[++site_url]][[~[[*id]]]]";
var windowObjectReference = window.open(windowUrl , windowName , windowFeatures);
window.close();
});
}
else {
calculateBreakpoints(buttons);
addBreakpointsToolbar();
addToggleBreakpoints();
createButtons(buttons,editURL);
if(editURL !== false){
addEditManagerLink(editURL);
}
updateButtons(buttons);
updateBreakpointClass();
window.addEventListener('resize', updateBreakpointClass );
$('#toggleBreakpoints button').on('click',function(e){
e.stopImmediatePropagation();
var name = $(this).attr('name');
var windowOuterWidth = window.outerWidth;
var bodyClientWidth = document.body.clientWidth;
var toolbarWidth = windowOuterWidth - bodyClientWidth;
if(name == 'max'){
var width = window.screen.availWidth;
var height = window.screen.availHeight;
window.resizeTo( width ,height );
}
else if($(this).attr('data-width') >= 0) {
var width = $(this).attr('data-width');
if(width < 320){ width = 320; }
console.log('width = ' + width);
var height = $(this).attr('data-height');
newWidth = parseInt(width) + parseInt(toolbarWidth);
console.log('newWidth = ' + newWidth);
// note moving the window to the top right corner is hopelessly broken in FF
// https://bugzilla.mozilla.org/buglist.cgi?quicksearch=moveTo
var offset = parseInt(window.screen.availWidth) - newWidth;
console.log('offset = ' + offset);
offset = 0;
window.moveTo(offset, 0);
window.resizeTo( newWidth ,height );
}
else { }
})
}
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment