/** * ProcessWire Panels * * Alternative to modal windows. Creates iframe panels that load URLs. * Clicking outside the panel closes it. By default, panels load the requested * URL on mouseover of the a.pw-panel toggle link, unless the pw-panel-reload * class is specified (in which case it loads on click). * * Copyright 2016 by Ryan Cramer * License: MPL 2.0 * * REQUIREMENTS * ============ * Include the panel.js and panel.css files in the request. * jQuery is required. jQuery UI is strongly recommended but not required. * So far tested only in PW admin themes, but should work outside them too. * * BASIC USAGE * =========== * Give any link a "pw-panel" class and it will open in a left-side panel: * * Click to open panel * * If clickable element is not an tag, give "data-href" attr containing the URL the panel should open: * * Click to open panel * * To make a panel open on the right rather than the left, append "pw-panel-right" to the class attribute. * * . * * * */ var pwPanels = { /** * Quantity of panels initialized * */ qty: 0, /** * Initialize pwPanels, to be called at document.ready * */ init: function() { var url = window.location.href; if(url.indexOf('pw_panel=1') > -1) { // initialize inside of a panel $(document).on('mouseover', 'a', function() { // make links target the parent window var $a = $(this); var target = $a.attr('target'); if(typeof target == "undefined" || target.length == 0) { $a.attr('target', '_parent'); } }); } else if(url.indexOf('pw_panel=2') > -1) { // don't initialize anything (.pw-panel-links class option) } else { // initialize a page with panels in it $('.pw-panel').each(function() { var $toggler = $(this); pwPanels.addPanel($toggler); }); } }, /** * Add a new panel * * @param toggler Element that toggles the panel * */ addPanel: function($toggler) { var panelURL = $toggler.attr('data-href'); var panelID = $toggler.attr('data-panel-id'); var panelContainerID = 'pw-panel-container-' + (++pwPanels.qty); // allow for use of data-href or href attribute that references URL to load in panel if(typeof panelURL == 'undefined' || !panelURL.length) panelURL = $toggler.attr('href'); if(typeof panelURL != 'undefined' && panelURL.length) { panelURL += (panelURL.indexOf('?') > -1 ? '&' : '?') + 'modal=panel&pw_panel='; if($toggler !== null && $toggler.hasClass('pw-panel-links')) { panelURL += '2'; // don't update target of links in panel } else { panelURL += '1'; // update target of links in panel } } var $icon = $('') .attr('class', 'pw-panel-icon fa fa-angle-double-left'); var $span = $('').attr('class', 'ui-button-text') .append($icon); var $btn = $('') .attr('class', 'pw-panel-button pw-panel-button-closed ui-button ui-state-default') .attr('href', panelURL) .on('click', pwPanels.buttonClickEvent) .on('mouseover', pwPanels.buttonMouseoverEvent) .on('mouseut', pwPanels.buttonMouseoutEvent) .append($span); var $panel = $('
') .attr('id', panelContainerID) .attr('class', 'pw-panel-container pw-panel-container-closed') .append($btn); $('body').append($panel); if(typeof panelID != 'undefined' && panelID.length) { // loading an in-page element rather than a URL $('#' + panelID).hide().addClass('pw-panel-element'); // class assigned to in-page element $panel.addClass('pw-panel-container-element').attr('data-panel-id', panelID); } // panel toggler if($toggler !== null) { pwPanels.initToggler($toggler, $btn, $panel); } else { $panel.addClass('pw-panel-left'); } }, /** * Initialize the toggler element, plus $btn and $panel with options from toggler element * * @param $toggler * @param $btn * @param $panel * */ initToggler: function($toggler, $btn, $panel) { var panelSide = $toggler.hasClass('pw-panel-right') ? 'right' : 'left'; var text = $toggler.attr('data-tab-text'); var icon = $toggler.attr('data-tab-icon'); var offset = $toggler.attr('data-tab-offset'); var panelWidth = $toggler.attr('data-panel-width'); var btnPos = panelSide == 'right' ? 'left' : 'right'; var btnExtraPx = 1; $panel.addClass('pw-panel-tab pw-panel-' + panelSide); $panel.attr('data-href', $btn.attr('href')); if($toggler.hasClass('pw-panel-reload')) $panel.addClass('pw-panel-reload'); if(typeof offset != "undefined") { offset = parseInt(offset); if(offset > -1) { // positive number indicates offset from top $btn.css('top', offset + 'px'); } else { // negative number indicates offset from bottom $btn.css('top', 'auto'); $btn.css('bottom', Math.abs(offset) + 'px'); } } if(typeof text != "undefined" && text.length) { $btn.children('.ui-button-text').text(text); $btn.addClass('pw-panel-button-text'); btnExtraPx = 7; //$btn.css(btnPos, (-1 * ($btn.height() + 7)) + 'px'); //$btn.css('top', parseInt($btn.css('top')) + ($btn.width()) + 'px'); } if(typeof icon != "undefined" && icon.length) { var $icon = $('').addClass('fa fa-fw fa-' + icon); var $text = $btn.children('.ui-button-text'); if($btn.hasClass('pw-panel-button-text')) { $text.prepend($icon); } else { $text.empty().append($icon); $btn.css(btnPos, (-1 * ($btn.outerWidth())) + 'px'); } } if(typeof panelWidth != 'undefined' && panelWidth.length) { $panel.css('width', panelWidth) $panel.css(panelSide, '-' + panelWidth); } if(panelSide == 'right') { // align button to right edge //$btn.css('left', (-1 * (btnExtraPx + $btn.height())) + 'px'); } else { // align button to left edge $btn.css('right', (-1 * (btnExtraPx + $btn.height())) + 'px'); } if(!$toggler.hasClass('pw-panel-tab')) { // if toggler doesn't specify that a tab/button should show, hide our $btn element $btn.addClass('pw-panel-button-hidden'); } // delegate events from toggler to pw-panel-button $toggler.click(function() { $btn.click(); return false; }).on('mouseover', function() { $btn.mouseover(); }).on('mouseout', function() { $btn.mouseout(); }); }, /** * Populate the panel content (iframe if using URL) and return it * */ initPanelContent: function($panel) { var $content = $panel.find('.pw-panel-content'); var panelID = $panel.attr('data-panel-id'); if($content.length) { return $content; } else if(typeof panelID != "undefined") { var $panelTarget = $('#' + panelID); // var $btn = $panel.find('.pw-panel-button').addClass(panelID + '-pw-panel-button'); // if needed for external trigger if($panelTarget.length) { $content = $('
').addClass('pw-panel-content').css('overflow', 'auto'); $panel.append($content); $content.append($panelTarget); $panelTarget.show(); $panelTarget.trigger('pw-panel-init'); } } else { $content = $('