;(function($) { /* Popup Menu plugin ** author Chris Muster ** created 04/12/2017 ** updated 08/05/2020 ** description - A plugin that, when called on an element, returns and attaches a customisable popup menu ** */ class Popup { constructor(options,elem) { var self = this; var defaultPopupMenu = `
`; this.defaultOptions = { content : defaultPopupMenu, //this option MUST be set when new options passed through, or only the default menu will show position : "top", //where the popup will show by default- top. Other options: right, bottom, or left theme : "popupTheme", //Menu Element theme. Defaults to popupTheme, but custom class can be set instead style : "", //Popup Menu Style. Default no style, will revert to default colours. Other options: Blue, Red, Green, Custom animation : "standard", //Standard animation by default. Other options: flip, grow, bounce event : "click", //Default set to "click", can also be set to hover hideOnClick : true, //When true, clicking off the menu closes it. When false, only clicking on the menu closes it zIndex : 100, //Individual z-index can be set for each menu for layering if necessary //function to handle actions when clicking on popup menu icons. MUST be set when options are passed through or an error or default menu actions will occur popItemClick: function(globalthis) { //Default actions var twentyEightSpaces = ` `; var twentyFourSpaces = ` `; var eightSpaces = ` `; var sixteenSpaces = ` `; var content; var container = $(event.target).attr("id"); switch (container) { case "faInfo": content = { type : "info", heading : "Information", text : `To set a new menu when calling .popup() on an element, you must set a variable that holds a string with the html for that menu, then pass that variable through as the "content" part of the options. For example:
var myMenu = '<div>\
${twentyEightSpaces}<a href="#''><i id="faInfo" class="fa fa-info"></i></a>\
${twentyFourSpaces}</div>';
would create a menu with one item, and just add more '<a>' tags with icons inside the '<div>' tags to add more menu items.
Then add it to the content when calling the popup:
$("#myPopUp").popup({
${eightSpaces}content: myMenu,
${eightSpaces}popItemClick(globalthis) {
${sixteenSpaces}...new actions here...
${eightSpaces}}
});
You must set new actions in the "popItemClick" function for your menu in the options you pass or it will throw an error.
` } globalthis.alertBox(content); break; case "faQuest": content = { type : "info", heading : "Question", text : `Why is this being shown?
Because you need to set a popup menu of your own (and the popItemClick() function) or you get this default menu.
If you set the popup menu but don't change the popItemClick() function, you will get an error.
Click the "i" button for more info.
` } globalthis.alertBox(content); break; case "faLink": window.open("http://example.com/"); break; default: content = { type : "danger", heading : "Error", text : `Error! You have set a new menu without changing the 'popItemClick' function. The 'popItemClick' function must be set to new menu actions.
` } globalthis.alertBox(content); } } } this.elem = elem; this.$elem = $(elem); this.options = $.extend({}, this.defaultOptions, options); if (!this.$elem.hasClass(this.options.theme)) { this.$elem.addClass(this.options.theme); } this.init(); } init() { this.popup = $('') .addClass('pop-' + this.options.position) .addClass('popupTheme' + this.options.style) .append('') .appendTo('body').css("opacity", 0).hide(); this.setContent(); this.setTriggers(); } setContent() { var self = this; var location = this.popup.find(".pop-items"); var content; if ((this.options.position == 'top') || (this.options.position == 'bottom')) { content = $(this.options.content).find("a").addClass("pop-item"); location.html(content); this.popup.find("i").first().addClass("leftBorder"); this.popup.find("i").last().addClass("rightBorder"); } else if ((this.options.position == 'left') || (this.options.position == 'right')) { content = $(this.options.content).find("a").addClass("pop-item").addClass('item-side'); location.html(content); this.popup.find("i").first().addClass("topBorder"); this.popup.find("i").last().addClass("bottomBorder"); } //popItemClick callback**************************************** location.find('.pop-item').on('click', function(event) { event.preventDefault(); self.options.popItemClick.call(this, self); }); } setTriggers() { var self = this; if (this.options.event === 'click') { this.$elem.on('click', function(event) { event.preventDefault(); if (self.$elem.hasClass('pressed')) { self.pophide(); } else { self.popshow(); } }); } if (this.options.event === 'hover') { this.$elem.on('mouseenter', function(event) { setTimeout(function() { self.popshow(); self.popup = $(self.popup[0]); }, 250); }); $(this.popup).on('mouseleave', function(event) { setTimeout(function() { self.pophide(); }, 1000); }); } if (this.options.hideOnClick === true) { $('html').on('click.popup', function(event) { if (event.target != self.elem && self.$elem.has(event.target).length === 0 && self.popup.has(event.target).length === 0 && self.popup.is(":visible")) { self.pophide(); } }); } } pophide() { var self = this; var animation = {opacity: 0}; this.$elem.removeClass('pressed'); switch (this.options.position) { case 'top': animation.top = '+=20'; break; case 'left': animation.left = '+=20'; break; case 'right': animation.left = '-=20'; break; case 'bottom': animation.top = '-=20'; break; } this.popup.animate(animation, 200, function() { self.popup.hide(); }); } popshow() { this.$elem.addClass('pressed'); this.setPosition(); this.popup.show().css({opacity: 1}).addClass('animate-' + this.options.animation); } setPosition() { var self = this; this.coords = this.$elem.offset(); var x = this.coords.left; var y = this.coords.top; var popWidth = this.popup.width(); var popHeight = this.popup.height(); var adjLeft = popWidth / 2; var adjTop = popHeight / 2; this.testy = $('') .css({display: 'inline-block', margin: '0px', padding: '0px'}) .appendTo('body'); var measure = this.$elem.clone().css({padding: "0px", margin: "0px"}); var loc = this.testy; loc.html(measure); var textWidth = this.testy.width(); var textHeight = this.testy.height(); this.testy.remove(); var adjMenuWidth = textWidth / 2; var adjMenuHeight = textHeight / 2; var up = y - (popHeight + 7); var down = y + textHeight; if (this.popup.hasClass('pop-top')){ this.popup.css({ top : up + "px", left : (x - adjLeft + adjMenuWidth + 5) + "px", right: "auto", 'z-index': this.options.zIndex }); } if (this.popup.hasClass('pop-bottom')) { this.popup.css({ top : (down + 7) + "px", left : (x - adjLeft + adjMenuWidth + 5) + "px", right: "auto", 'z-index': this.options.zIndex }); } if (this.popup.hasClass('pop-left')) { this.popup.css({ top : (y - adjTop + adjMenuHeight + 5) + "px", left : (x - popWidth - 2) + "px", right: "auto", 'z-index': this.options.zIndex}); } if (this.popup.hasClass('pop-right')) { this.popup.css({ top : (y - adjTop + adjMenuHeight + 5) + "px", left : (x + textWidth + 12) + "px", right: "auto", 'z-index': this.options.zIndex}); } } alertBox(content) { var self = this; var myAlert = `