Using event in jQuery custom function - javascript

I'm making a popup system and I'm having some issues with using event as an attribute in my custom function. Here is my code:
var openLayoutPopup = function(event){
event.preventDefault();
var target = $(event.target);
var flexible_field = target.closest('.acf-field-flexible-content').attr('data-key');
var popup = $('.'+flexible_field);
var overlay = $('.bbh-popup-overlay');
popup.addClass('open').fadeIn();
overlay.fadeIn();
}
$('.my-class').click(openLayoutPopup(event));
But my console gives me the following error saying event isn't defined:
ReferenceError: event is not defined
I've used event.target before and event.which, but only for unnamed functions.
Additionally, I have another similar function, in which I need to pass event and a secondary boolean parameter:
function closeLayoutPopup(event, openLayout){
event.preventDefault();
var popup = $(event.target).closest('.bbh-popup');
var overlay = $('.bbh-popup-overlay');
popup.removeClass('open').fadeOut();
overlay.fadeOut();
if(open == true){
var dataLayout = target.attr('data-layout');
acf.fields.flexible_content.add(dataLayout);
}
}
Similarly I'm confused about how to pass the parameters in that one.
EDIT:
What I was trying to do explained shortly is having a button open a popup. Popup has two buttons, one to close popup and one to add layout to page and close afterwards. Issue was me calling functions wrong, and not realizing my solution was illogical.
I fixed the click events thanks to #Raibaz. Then I added to closeLayoutPopup to the addLayout function instead of combining them:
/*==============================================
= Function - Close popup =
==============================================*/
function closeLayoutPopup(event){
event.preventDefault();
var popup = $(event.target).closest('.bbh-popup');
var overlay = $('.bbh-popup-overlay');
popup.removeClass('open').fadeOut();
overlay.fadeOut();
}
/*=============================================
= Function - Open popup =
=============================================*/
var openLayoutPopup = function(event){
event.preventDefault();
var target = $(event.target);
var flexible_field = target.closest('.acf-field-flexible-content').attr('data-key');
var popup = $('.'+flexible_field);
var overlay = $('.bbh-popup-overlay');
popup.addClass('open').fadeIn();
overlay.fadeIn();
}
/*=============================================
= Function - Add Layout =
=============================================*/
var addLayout = function(event){
event.preventDefault();
var target = $(event.target);
var dataLayout = target.attr('data-layout');
acf.fields.flexible_content.add(dataLayout);
closeLayoutPopup();
}
/*---------- add section click - open popup ----------*/
$('.acf-field-flexible-content .acf-flexible-content > .acf-actions a.acf-button').on('click',openLayoutPopup);
/*---------- Close button click ----------*/
$('.layout-picker-close').on('click', closeLayoutPopup);
/*---------- Add layout ----------*/
$('.bbh-popup a.add-layout-button').on('click', addLayout);

I'm assuming you want to open the layout popup when clicking on elements with the my-class class, so your code should be something like this:
$('.my-class').on('click', openLayoutPopup);
The event parameter will be passed to the function when invoking the openLayoutPopup callback function.
You can have a look at the documentation for jQuery.on for reference.
As for the other function, instead of passing a second boolean parameter to the click event handler you could use a custom CSS class or a data attribute to indicate that there is an open popup, so your openLayoutPopup function could contain something like this:
$('body').addClass('has-popup')
and in your closeLayoutPopup you could just check if the class is present to determine if there is an open popup, and eventually remove it when closing the popup.

Related

Binding listener to a dynamically created element

I am using bootstrap's list group to create a row of tabs. When someone clicks on an element in a table, it dynamically creates a new tab and appends it to that list group.
var newtext = "#"+ticket+" - "+parele.find("td:nth-child(3) strong").html();
var closebtn = $("<button>").addClass("close ml-2 mr-n2 newlyaddedclose").html("×");
var newdiv = $("<div>").addClass("d-flex justify-content-between").append(newtext).append(closebtn);
var newa = $("<a>").addClass("list-group-item list-group-item-action").attr("data-toggle","list").attr("href","#ticket"+ticket).attr("id","ticket"+ticket+"-tab").append(newdiv);
$("#ticketpanel").append(newa);
The problem I am having is the newly created close button. I need to bind a function that identifies when that is clicked to handle closing that tab, but it doesn't seem to be working. In my example here, I added the "newlyaddedclose" class to help identify the new element temporarily and I added the following code below to bind a function that is defined at the top of my script tag:
$(".newlyaddedclose").on("click",".close",closebtn).removeClass("newlyaddedclose");
This still doesn't work. When I inspect the close button element, console shows this error: Framework Event Listeners API Errors:
event listener's handler isn't a function or empt
Am I making this harder than it needs to be, or what am I doing wrong? I can simple put at the end of this element creation this:
$(".close").click(function() { ... });
But doing this starts to double up and triple up etc, those events on already created tabs.
EDIT:
Here is my entire block of script to clear up any confusion.
$(function() {
function closebtn() {
alert("Close button clicked...");
}
$(".ticket-line").click(function() {
var parele = $(this);
var ticket = parele.data("tnum");
// Check to see if ticket is already open in tabs
if($("#ticket"+ticket).length == 0) {
// Create tab on ticket panel
var newtext = "#"+ticket+" - "+parele.find("td:nth-child(3) strong").html();
var closebtn = $("<button>").addClass("close ml-2 mr-n2 newlyaddedclose").html("×");
var newdiv = $("<div>").addClass("d-flex justify-content-between").append(newtext).append(closebtn);
var newa = $("<a>").addClass("list-group-item list-group-item-action").attr("data-toggle","list").attr("href","#ticket"+ticket).attr("id","ticket"+ticket+"-tab").append(newdiv);
$("#ticketpanel").append(newa);
$(".newlyaddedclose").on("click",".close",closebtn).removeClass("newlyaddedclose");
// Create DIV with content
var newdata = $("<div>").addClass("tab-pane").attr("id","ticket"+ticket);
$("#ticket-tabs").append(newdata);
$("#ticket"+ticket+"-tab").tab("show");
} else {
// Ticket is already open, switch to it instead
$("#ticket"+ticket+"-tab").tab("show");
}
});
})
The error is clearly stating you are binding a non function to the event listener. So the error is saying that closeBtn is not a function. Your code, you defined closeBtn as the button you are trying to attach the event too. So change closeBtn in the click event listener to the name of the function you are actually trying to call. If it is the same function name, rename something.
Your problem:
var closeBtn = 1;
if (1===1) {
var closeBtn = 2;
console.log(closeBtn);
}
console.log(closeBtn);
It is unclear why you are selecting the element you just added. You can just attach the event when you create the button, no need to look up the element.
var closebtn = $("<button>")...
closeBtn.on("click", function (){
console.log('clicked', closeBtn);
});
Or use event delegation so any element you add will trigger the function.
$("#ticketpanel").on("click", ".close", function () {
const closeBtn = $(this);
console.log('clicked', closeBtn);
});

How to add one click event handler for two different buttons without using jQuery?

When a user opens a modal, there are two ways of closing it, one by pressing the 'x' in the top right corner of the box, or by pressing the cancel button. The two buttons are both in the same class name modal-hide but also have id's of modal-close and modal-cancel.
var cancel = document.getElementById('modal-cancel');
var close = document.getElementById('modal-close');
cancel.onclick = function () {
//close window
}
close.onlick = function () {
//close window
}
What is the best way to implement an event handler so that I don't have to write two different onclick functions that do the same thing?
I do not want to use jQuery for this at all!
First of all, don't use event properties! Use addEventListener (MDN) as a modern standard instead. Then you should define a separate handler function (let's say onClick) to bind it with your elements:
var cancelElt = document.getElementById('modal-cancel');
var closeElt = document.getElementById('modal-close');
var onClick = function () {
alert('Hello!');
};
cancelElt.addEventListener('click', onClick);
closeElt.addEventListener('click', onClick);
Simply use named instead of anonymous functions. I use addEventListener below instead of onclick.
var cancel = document.getElementById('modal-cancel');
var close = document.getElementById('modal-close');
var clickFunction = function() {
// close modal
}
cancel.addEventListener('click', clickFunction, false);
close.addEventListener('click', clickFunction, false);
A solution that basically is one line.
Array.prototype.forEach.call(document.querySelectorAll("#modal-cancel, #modal-close"), function(element) {
element.addEventListener("click", function() {
//close window
}, false);
});

Angular Stopping event propagation

This is an extension of my previous post here. I got everything working but I have 1 issue. When I start the intro the dropdown opens up exactly like I want, however when I click on the buttons inside the intro window (next, previous) then the dropdown closes. If I navigate the intro using my arrow keys it stays open. So how do I get the dropdown to stay open even if I'm using the intro window buttons to navigate the intro.
Here's the js portion for reference:
MainCtrl.prototype.startHelp = function() {
var _this = this;
_this.$timeout(function () {
angular.element('#drop-down').click();
}, 0, false);
_this.CallMe();
};
well you can try adding following to those buttons click event handler functions:
function onClickedNext(event) {
...
event.preventDefault();
event.stopPropagation();
}
This may be too late. But I achieved this by modifying intro.js code. Just stop the click event propagation inside "nextTooltipButton" defined in intro.js file.
Change the onclick listner function from this :
//next button
var nextTooltipButton = document.createElement('a');
nextTooltipButton.onclick = function() {
if (self._introItems.length - 1 != self._currentStep) {
_nextStep.call(self);
}
};
to :
//next button
var nextTooltipButton = document.createElement('a');
nextTooltipButton.onclick = function() {
if (self._introItems.length - 1 != self._currentStep) {
_nextStep.call(self);
var e = window.event;
e.stopPropagation();
}
};
Works for me on Chrome browser version 56.0.2924.87. As of today this code snippet is here.
We need no other changes in angular side.

How to make "modal conformation" functionality in this function call?

When i m calling this below function in script, i will get a popup dialog box to do some instructions.
Here is my sample code:
function updateStatus(instrxnID){
exporter.fn.childWindow({
instrxnID : instrxnID,
url:'pgks/fund/update/view.page'
},'pgks','Popup',{top:100,height:459,width:884,left:200});
}
exporter.fn.childWindow will call the below function to open popup'
childWindow : function(elements,path,title,setting){
setting = setting != undefined ? setting : {top:100,height:300,width:400,left:200};
var keys = exporter.fn.keys(elements);
var offset = "width="+setting.width+",height="+setting.height+",top="+setting.top+",left="+setting.left;
myWin = open("", "displayWindow", offset+",scrollbars=no,status=no,dependent=yes,directories=no,menubar=no,personalbar=no");
myWin.document.open();
myWin.document.write("<html><head>");
myWin.document.write("</head><body><form name='form' action='"+elements.url+"' type='post'>");
for ( var a = 0; a < keys.length; a++) {
myWin.document.write('<input type="hidden" name="'+keys[a]+'" value="'+elements[keys[a]]+'">');
}
myWin.document.write("</form><script type='text/javascript'>form.method=\'post\';form.submit();</script></body></html>");
myWin.document.close();
}
After finishing those instruction ,i should return to the main page or parent page of this popup.
Note: By clicking background page or another link, this modal should not disapper.
Example: i need to attain something like this example
Attach either a click handler to your submit buttons, or a submit handler to the form. In this handler hide (display: none;) your popup or, if you're using a window object for your pop up, call .close() on the instance.
EDIT:
$(".my-button").on("click", function() {
myWin.close();
});

Preventing javascript callback from being called on parent div

I'm working on a userscript which is supposed to be cross-browser compatible which might explain why I'm not doing things the normal way. The script displays a floating div named box which is a jQuery object. The click function looks like this:
box.click(function(event) {
set_visible(false);
});
The set_visible function just does a box.fadeOut(500);
Inside the parent div I create a menu not using jQuery but plain old javaScript using an array of functions like so (I tried rewriting this function using jQuery but had some issues getting the array functions to work):
function doGMMenu() {
if( !GM_falsifiedMenuCom.length ) { return; }
var mdiv = document.createElement('div');
for( var i = 0; GM_falsifiedMenuCom[i]; i++) {
var bing;
mdiv.appendChild(bing = document.createElement('a'));
bing.setAttribute('href','#');
bing.onclick = new Function('GM_falsifiedMenuCom['+i+'][1](arguments[0]); return false;');
bing.appendChild(document.createTextNode(GM_falsifiedMenuCom[i][0]));
if (i+1<GM_falsifiedMenuCom.length)
mdiv.appendChild(document.createTextNode('\u00A0\u00A0|\u00A0\u00A0'));
}
status.contents().append(mdiv);
}
Here's an example of the first array function which displays an options menu:
function() { DisplaySlideMenu(true); }
My problem is that when I click on the link, the options menu displays, but the parent divs box.click function is also called which hides it when I don't want to. When the anchor .onclick function is added you can see that the last entry is return false; but that doesn't prevent the .click event from propagating up to the parent div. Is there any way to prevent this from happening?
box.click(function(event) {
event.stopImmediatePropagation();
event.stopPropagation();
set_visible(false);
});

Categories

Resources