In the course of development of JS, faced with such a situation. My code:
Object.prototype.show = function () {
$('span[data-search]').on('click', function (evt) {
var data_search = $(this).data('search');
$('body').on('shown.bs.modal', '.modal', function () {
$(this).find('button.synConfirm').on('click', function(){
console.log(data_search); // Not see variable
});
});
}):
});
Ie if you click on the span opens a modal window (Bootstrap 3). Then when you click on the button in the modal window, I should have access to the variable data-search announced in the beginning of the method, but I do not have access to it ...
Question: Why? After I identified her to call console.log (), .. How do I get it?
Related
I use a jQuery window libray https://github.com/humaan/Modaal
which triggers events this way $("class of element").modaal({arg1, arg2,...});
--- I updated my question here to make it more general and used an iframe / Html instead of an external svg ---
To trigger an element e.g. in an external Html which is loaded within an iframe, I applied the following code to the iframe:
<iframe src="External.html" id="mainContent" onload="access()"></iframe>
which calls this function:
function access() {
var html = document.getElementById("mainContent").contentDocument.getElementById("IDofDIVelement");
html.addEventListener('click', function() {clicker();});
}
function clicker()
{
// console.log('hooray!');
$("#mainContent").contents().find("IDofDIVelement").modaal({});
//return false;
}
Actually it will only work on every second click. Any idea what I did not consider properly?
Best
You do not need to wait windows loading but iframe only:
$(function() {
$("#mainContent").bind("load",function(){
var myIframeElement = $(this).contents().find(".modaal");
myIframeElement.modaal({
content_source: '#iframe-content',
type: 'inline',
});
});
});
The reason why it did not work was that the iframe was not completely loaded, while jQuery tried to attach the function. As $(document).ready(function(){} did not work, the workaround was to initialize it with
$( window ).on( "load",function() {
$("#mainContent").contents().find("IDofDIVelement").modaal({});
});
This worked properly to attach the functionallity to an element within the iframe.
Actually modaal will vanish the envent handler after the overlay was opened and closed again.
So maybe someone wants to trigger an iframe element for modaal, too, here is a setup which would solve this issue.
(It can be optimised by #SvenLiivaks answer):
$(window).on("load", function() {
reload();
});
function reload() {
var length = $("#iframeID").contents().find("#IDofDIVelement").length;
// The following check will return 1, as the iframe exists.
if (length == 0) {
setTimeout(function() { reload() }, 500);
} else {
$("#iframeID").contents().find("#IDofDIVelement").modaal({
content_source: '#modalwrapper',
overlay_close: true,
after_close: function reattach() {
reload();
}
});
}
}
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 4 years ago.
Trying to call the closeOpenNavDropdowns function within my toggleDropdownNavState function, but nothing is running and I am not getting errors. I've checked the compiled code and it's there.
EDIT: trying to call the fn like this.closeOpenNavDropdowns(); gives me Uncaught TypeError: this.closeOpenNavDropdowns is not a function
const aboutDropdownNav = {
setup() {
$('.nav__main__about-dropdown--js').click(this.toggleDropdownNavState);
// Handlers for when user clicks outside the dropdown to close
$(document).click(function(event) {
if ($('body').hasClass('about-dropdown--open') && !$(event.target).parents('.about-us-dropdown').length) {
$('body').removeClass('about-dropdown--open');
}
})
},
toggleDropdownNavState(e) {
e.stopPropagation();
e.preventDefault();
$('body').toggleClass('about-dropdown--open');
this.closeOpenNavDropdowns;
},
closeOpenNavDropdowns() {
console.log('closeOpenNavDropdowns in aboutDropdown.js');
$('body').removeClass('solutions-dropdown--open'); //close solution dropdown if its open
}
}
module.exports = aboutDropdownNav;
and the above code is called by this other file:
var aboutDropdownNav = require('./nav-about-dropdown');
module.exports = function() {
// About Dropdown Nav
aboutDropdownNav.setup();
}
The toggleDropdownNavState function is attached to an eventListener. Inside an event handler function, this is a reference to the event's current target. That's why closeOpenNavDropdowns is not a function in the object referenced by this.
There are many ways to solve that issue. One of them is to use Function.prototype.bind to force the binding between the closeOpenNavDropdowns function and your object.
const aboutDropdownNav = {
setup: function() {
$('.nav__main__about-dropdown--js').click(this.toggleDropdownNavState.bind(this));
// Handlers for when user clicks outside the dropdown to close
$(document).click(function(event) {
if ($('body').hasClass('about-dropdown--open') && !$(event.target).parents('.about-us-dropdown').length) {
$('body').removeClass('about-dropdown--open');
}
})
},
toggleDropdownNavState : function(e) {
e.stopPropagation();
e.preventDefault();
$('body').toggleClass('about-dropdown--open');
this.closeOpenNavDropdowns();
},
closeOpenNavDropdowns : function() {
console.log('closeOpenNavDropdowns in aboutDropdown.js');
$('body').removeClass('solutions-dropdown--open'); //close solution dropdown if its open
}
}
aboutDropdownNav.setup();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input class="nav__main__about-dropdown--js" value="Click"/>
The context, when calling this.toggleDropdownNavState is wrong, bind it to the proper context.
$('.nav__main__about-dropdown--js').click(this.toggleDropdownNavState.bind(this));
And you are missing the brackets () to call the function, you just referencing the function.
toggleDropdownNavState(e) {
e.stopPropagation();
e.preventDefault();
$('body').toggleClass('about-dropdown--open');
this.closeOpenNavDropdowns();
},
I am using MVC Razor - The overall goal is to create a "print view" pop-up page.
The print view button is on the parent page, when clicked, an ajax event is fired which will populate an empty div with the contents that are to be included in the print preview:
//from the view
#Ajax.ActionLink("prntPreview", "Display", new { ID = Model.Detail.ID }, new AjaxOptions { UpdateTargetId = "modal" }, new { #class = "btnPreview" })
then, using JavasScript/jQuery I clone the contents of that newly populated div and create a new window with the contents:
//in the scripts file
$('.btnPreview').on('click', function () {
$(document).ajaxStop(function () {
var pageData = $('#modal').html();
setTimeout( //add a slight delay
function () {
PopupPrint(pageData);
}, 300);
});
});
function PopupPrint(data) {
var mywindow = window.open('', '', 'height=500,width=800,resizable,scrollbars');
mywindow.document.write(data);
mywindow.focus();
//do some other stuff here
}
This is where I run into difficulty. The first time I click, everything is working as expected - however, if you do not navigate away from the parent page and try to use the print preview button a second time, the popup will be created twice, then three times etc. with each additional click.
I think that the problem is because each time the .btnPreview is clicked, a new $(document).ajaxStop event is being created, causing the event to fire multiple times.
I have tried to create the ajaxStop as a named function which is declared outside the scope of the click event and then clear it but this produces the same result:
var evnt = "";
$('.btnPreview').on('click', function () {
evnt =
$(document).ajaxStop(function () {
var pageData = $('#modal').html();
setTimeout( //add a slight delay
function () {
PopupPrint(pageData);
evnt = "";
}, 300);
});
});
I also have other ajaxStop events initialised so don't want to completely unbind the ajaxStop event. Is it possible to get the name or something from each ajax event so that I can clear just that event or similar?
You can prevent adding additional triggers by checking with a variable outside of scope like this:
(function() {
var alreadyAdded = false;
$('.btnPreview').on('click', function() {
if (!alreadyAdded) {
$('.eventTrigger').click(function() {
console.log('printing!');
});
alreadyAdded = true;
}
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="btnPreview">Add Event</button>
<button class="eventTrigger">Trigger</button>
Please note that the variable and function are encapsulated in a self-executing anonymous function and do not pollute global space.
The output of the sample can be seen in the developer console. If you remove the if-check then every click on the "Add Event" button produces an additional print statement on the "Trigger" button each time it is clicked (which is your problem). With the if, there will ever only be one event on the trigger button.
There were 2 issues which I needed to address.
The answer is to unbind the ajax event after it has checked that the request had completed and to unbind and reattach the button click trigger.
This is how I did it:
//in the scripts file
$('.btnPreview').off('click').on('click', function () {
$(document).ajaxComplete(function (e) {
var pageData = $('#modal').html();
setTimeout( //add a slight delay
function () {
PopupPrint(pageData);
}, 300);
$(this).off(e);
});
});
I unbound the click event by adding .off('click') before the .on. this is what stopped it popping up multiple times.
The other issue was that anytime any ajax event completed (triggered by something else) that would also create the popup - to get around that, I added $(this).unbind(e); to the end of the code block which removed the ajaxComplete binding which was being triggered each time any ajax event completed.
I'm getting the following error that is saying my e.preventDefault(); ---> "e." undefined is not a function when clicking <button class='url_qry_add' onclick='url_qry_add(this);'>. The function itself is defined before the end of my </body> and I have only invoked jQuery once.
The function structure is as follows:
var url_qry_add = function ( e ) {
e.preventDefault();
...
};
It used to be:
$( "ul.url_qry" ).on( "click", "li .url_qry_add", function ( e ) {
e.preventDefault();
...
});
But subsequent buttons added dynamically afterwards were not being picked up.
So I've been trying to figure out how to go about it and decided I should try converting the problem function to a named "invokable" function and putting the call in manually with the onclick='..' into the buttons that exist before and after dynamic creation.
Like I say, the error must be in the way I've created the function or the way I'm calling it. The error can't be to do with the order of files and I have not accidentally nested the function within another function or a document.ready.
What am I doing wrong?
<button class='url_qry_add' onclick='url_qry_add(event);'>
var url_qry_add = function (e) {
console.log(typeof e.preventDefault); // function
};
Update:
I'll try clarify how it works "internally", when we add attributes to function url_qry_add "inside" it looks like this:
document.querySelector('.url_qry_add').addEventListener('click', function (event) {
(function (event) {
url_qry_add(event, this, $(this));
}).call(event.target, event);
});
var url_qry_add = function (event, element, $jElement) {
console.log(event);
console.log(element);
console.log($jElement);
};
Hence, we have variable "event" (event object, where we have method preventDefault and so on), and "this" (current element). I hope that this explanation will help you understand where we get variable "event".
I create two button,
Open Button is Open the Child window.
Close Button is to close the Child Window.
Both button located at the parent window.
Here is the sample code
$("#to-open").click(function () {
var popUp = window.open( _contextPath + "open.jsp","Child", "width=500, height=300").focus();
});
$("#to-close").click(function () {
// No sure how to get the popUp object
//popUp.close();
});
Now I having difficulty on close window.
I cannot pass the var popUp to the closing window function.
Any advice or clue?
Thank
Simply declare the popUp variable in outer scope:
var popUp;
$("#to-open").click(function () {
popUp = window.open( _contextPath + "open.jsp","Child", "width=500, height=300").focus();
});
$("#to-close").click(function () {
if (popUp)
popUp.close();
});
The simplest approach is to put your window object in the global object.
var popUp;
$("#to-open").click(function () {
window.popUp = window.open( _contextPath + "open.jsp","Child", "width=500, height=300").focus();
});
This gets ugly though and it is considered best practice to not clutter up your global.
What would be cleaner is something like this
<button id="to-open">
</button>
<button id="to-close">
</button>
$(document).ready(function () {
var popUp = 0;
$("#to-open").click(function () {
popUp++;
});
$("#to-close").click(function () {
alert(popUp);
});
});