How to get the event invoking div with jquery - javascript

I have a couple of divs that when clicked opens a fancybox with a textfield that takes a message and then saves the form. This does not work when I want to reuse it, ie using the same function and code for multiple forms. It always pretends to the be first button. And for every time I use it the number of time it runs the callback function increases. Does anyone know what I did wrong? I tried adding the each(), but it did not help.
I'm sorry for the brief explanation, it is a lot clearer when looking at the code (note: I use console.log for the output): http://jsfiddle.net/EvYvc/11/
Basically: I wan't to know what element invoked the click function and get it's attributes.

Couple of changes,
You need to bind the click handler outside beforeShow
I don't think you can identify which reason_submit2 link is clicked inside beforeShow
Alternatively, I defined 2 var's and a click handler for the link which will store the name and form and that will be used later in fancyConfirm_ok
Complete code:
$(function() {
var r2sName = '', r2sForm = '';
$(".reason_submit2").fancybox({
openEffect: 'none',
closeEffect: 'none',
'modal': true
}).click(function () {
var $this = $(this);
r2sName = $this.data("name");
r2sForm = $this.data("form");
});
jQuery(".fancyConfirm_ok").click(function() {
$.fancybox.close();
console.log('form : ' + r2sForm);
console.log('name : ' + r2sName);
console.log('message : ' + $("[name=reason2]").val());
$($(".reason_submit2").data("form")).append($("<input>").attr("type", "hidden").attr("name", "reason").val($("#reason").val()));
$($(".reason_submit2").data("form")).append($("<input>").attr("type", "hidden").attr("name", $(".reason_submit2").data("name")));
//document.forms[$(".reason_submit2").data("form")].submit();
});
});
DEMO
Other trick is to add a class to clicked link inside click handler and use that class to get the name and form inside fancyConfirm_ok, but personally I feel this is better.

I’m no expert in the FancyForm plugin. but I think you are binding the click event multiple times since you are binding it inside the beforeShow handler.
Try binding the click event on it’s own instead:
http://jsfiddle.net/h8sVY/
$(".reason_submit2").each(function() {
$(this).fancybox({
openEffect: 'none',
closeEffect: 'none',
'modal': true
});
});
$(".fancyConfirm_ok").click(function() {
$.fancybox.close();
// etc...
});
​

Related

Triggered click don't work propertly [duplicate]

I'm having a hard time understand how to simulate a mouse click using JQuery. Can someone please inform me as to what i'm doing wrong.
HTML:
<a id="bar" href="http://stackoverflow.com" target="_blank">Don't click me!</a>
<span id="foo">Click me!</span>
jQuery:
jQuery('#foo').on('click', function(){
jQuery('#bar').trigger('click');
});
Demo: FIDDLE
when I click on button #foo I want to simulate a click on #bar however when I attempt this, nothing happens. I also tried jQuery(document).ready(function(){...}) but without success.
You need to use jQuery('#bar')[0].click(); to simulate a mouse click on the actual DOM element (not the jQuery object), instead of using the .trigger() jQuery method.
Note: DOM Level 2 .click() doesn't work on some elements in Safari. You will need to use a workaround.
http://api.jquery.com/click/
You just need to put a small timeout event before doing .click()
like this :
setTimeout(function(){ $('#btn').click()}, 100);
This is JQuery behavior. I'm not sure why it works this way, it only triggers the onClick function on the link.
Try:
jQuery(document).ready(function() {
jQuery('#foo').on('click', function() {
jQuery('#bar')[0].click();
});
});
See my demo: http://jsfiddle.net/8AVau/1/
jQuery(document).ready(function(){
jQuery('#foo').on('click', function(){
jQuery('#bar').simulateClick('click');
});
});
jQuery.fn.simulateClick = function() {
return this.each(function() {
if('createEvent' in document) {
var doc = this.ownerDocument,
evt = doc.createEvent('MouseEvents');
evt.initMouseEvent('click', true, true, doc.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
this.dispatchEvent(evt);
} else {
this.click(); // IE Boss!
}
});
}
May be useful:
The code that calls the Trigger should go after the event is called.
For example, I have some code that I want to be executed when #expense_tickets value is changed, and also, when page is reload
$(function() {
$("#expense_tickets").change(function() {
// code that I want to be executed when #expense_tickets value is changed, and also, when page is reload
});
// now we trigger the change event
$("#expense_tickets").trigger("change");
})
jQuery's .trigger('click'); will only cause an event to trigger on this event, it will not trigger the default browser action as well.
You can simulate the same functionality with the following JavaScript:
jQuery('#foo').on('click', function(){
var bar = jQuery('#bar');
var href = bar.attr('href');
if(bar.attr("target") === "_blank")
{
window.open(href);
}else{
window.location = href;
}
});
Try this that works for me:
$('#bar').mousedown();
Technically not an answer to this, but a good use of the accepted answer (https://stackoverflow.com/a/20928975/82028) to create next and prev buttons for the tabs on jQuery ACF fields:
$('.next').click(function () {
$('#primary li.active').next().find('.acf-tab-button')[0].click();
});
$('.prev').click(function () {
$('#primary li.active').prev().find('.acf-tab-button')[0].click();
});
I have tried top two answers, it doesn't worked for me until I removed "display:none" from my file input elements.
Then I reverted back to .trigger() it also worked at safari for windows.
So conclusion, Don't use display:none; to hide your file input , you may use opacity:0 instead.
Just use this:
$(function() {
$('#watchButton').trigger('click');
});
You can't simulate a click event with javascript.
jQuery .trigger() function only fires an event named "click" on the element, which you can capture with .on() jQuery method.

Change event action based on other event

Is there a generally accepted method to change the action of a JavaScript event?
The following seems clean, but doesn't work as the first event is bound to #link when the page is rendered, and nothing changes when the class changes. Does it sound like I understand this correctly?
$('#change-to-option-1').click(function(){$('#link').attr('class','option-1');});
$('#change-to-option-2').click(function(){$('#link').attr('class','option-2');});
$('.option-1').click(function(){alert('option 1');});
$('.option-2').click(function(){alert('option 2');});
Option 1
Option 2
Click Me
Or should I have one event, and put logic in it based on the element's class (or maybe data()) instead as shown?
$('#link').click(function(){
if( ('#link').attr('class')=='option-1') {alert('option 1');}
else{alert('option 2');}
});
Or is there a generally more accepted approach?
If you want to make an event trigger for an element after changing its class/any identity that you used to bind the event initially. Then you have to go for event delegation.
$(document).on("click", ".option-1", function(){ alert('option 1'); });
You can expect the code to be optimized if you use any closest static parent of .option-1 instead of document
I would not recommend and prefer hardcoding anything. So here's a solution which would take care of what you are trying to do.
$('#change-to-option-1,#change-to-option-2').click(function(){
$('#link').attr('class',this.id.split('-')[2] + '-' + this.id.split('-')[3]);
});
$('#link').on('click',$(this).attr("class"), function()
{
alert($(this).attr("class"));
});
Working example : https://jsfiddle.net/DinoMyte/39fvpstq/
If you plan to introduce more anchor links with a similar id structure :
$('[id^=change-to-option-]').click(function(){
$('#link').attr('class',this.id.split('-')[2] + '-' + this.id.split('-')[3]);
});
$('#link').on('click',$(this).attr("class"), function()
{
alert($(this).attr("class"));
});
Working example : https://jsfiddle.net/DinoMyte/39fvpstq/1/
If you wish to put everything in one event block :
$('#change-to-option-1,#change-to-option-2').click(function(){
$('#link').unbind('click');
$('#link').attr('class',this.id.split('-')[2] + '-' + this.id.split('-')[3]).on('click',$(this).attr("class"), function()
{ alert($(this).attr("class"));
});
});
Example : https://jsfiddle.net/DinoMyte/39fvpstq/2/

How to add and show a Bootstrap tooltip inside a jQuery click function?

I am trying to add and display a Bootstrap 3 tooltip from within a click function in jQuery.
It works well when I'm using an anonymous function for the click handler, but if I try to place the code into a named function I get the error TypeError: undefined is not a function (evaluating '$button.tooltip(...
The contents of the JS file is below. This is loaded after both jQuery and bootstrap.min.js.
$(function() {
function confirmClick(event) {
event.preventDefault();
$button = event.target;
console.log($button);
$button.tooltip({
title: 'Are you sure?',
trigger: 'manual',
}).tooltip('show');
$button.unbind('click');
}
$('.btn-confirm').click(confirmClick);
})
Ultimately, I'm looking to use setTimeout to re-add the click handler and hide the tooltip after X seconds.
The end behavior will be the user clicking on the button, a tooltip appearing asking "Are you sure?" and if they click again before X seconds the link is followed. If not, the tooltip is hidden and the same action is prepared for the next click.
I've also tried adding the tooltip using wither a manual or click trigger and then manipulating it from within the confirmClick() function, but any attempt to hit .tooltip from within a named click function seems to fail.
You need to wrap your target with jQuery selector to use .tooltip().
Do $button = $(event.target); instead of $button = event.target;.
Prepend your variable with $ if, and only if, your variable stores a jQuery object.

Javascript Popup won't close after adding it dynamically

I was running some test popups by putting them into the HTML file manually and the JS function that I had to close them worked fine. However, when I add the popups dynamically, the closing function breaks and they are unable to be removed.
Here is the JS function that tells all popups in the .popup class to close when the .close button is clicked. The code also contains a hover function to switch the images out for the close button when the user hovers over it, that is also broken.
$('.popup').on('click', '.close', function() {
$(this).closest('.popup').remove(); //or .hide() if you just want to hide the popup
});
$('img.close').hover(function () {
this.src = '/engine/themes/img/popup.close.hover.png';
}, function () {
this.src = '/engine/themes/img/popup.close.idle.png';
});
And here is my method of adding it to the DOM
var popupID = 'popup1';
// Create popup div
var popupHTML = '<div id="'+popupID+'" class="popup">'+
'<div class="toolbar"><div id="title">Please Wait</div>'+
'<img class="close" src="/engine/themes/img/popup.close.idle.png" alt="Close" title="Close" />'+
'</div><p class="text">Loading...<p></div>';
$('body').append(popupHTML);
$.ajax({
url: pageURL,
cache: false,
success: function(data) {
var matches, pageTitle;
matches = data.match(/<title>(.*?)<\/title>/);
pageTitle = 'MERKD.COM';
if ( typeof matches !== 'undefined' && matches != null ) {
pageTitle = matches[1];
}
$('#'+popupID).html(strReplace('Loading...', data, $('#'+popupID).html()));
$('#'+popupID).html(strReplace('Please Wait', pageTitle, $('#'+popupID).html()));
} // end success call
}); // end ajax function
Note at the bottom I use a manually-written replacing method instead of just using $('#popup1 p').html('some text'); because when I do it that, it shows the text retrieved in data twice, anyone know why that is?
I'm lost as to why this stopped working when I added the popups dynamically, but surely I'm just overlooking something, because I also can't figure out why the text retrieved in data is displayed twice when I do a regular .html() or .text() jQuery call.
Try this:
var hovered;
$(document).on('mouseenter','img.close',function () {
hovered = this;
this.src = '/engine/themes/img/popup.close.hover.png';
});
$(document).on('mouseleave','img.close',function () {
hovered.src = '/engine/themes/img/popup.close.idle.png';
});
Event handlers are bound only to the selected elements and they must exist already on the page at the time the code loads. Otherwise, to correct that, you can use event delegation and add the event handler to "something" that was already there, document is always a safe card.
Read more about .on()
EDIT:
I corrected my code, I actually realized that .on() and hover don't work together, so I adapted to a mouseenter & mouseleave instead. You can not use .hover() here anyway since you need to use delegation.
From jQuery's documentation:
Deprecated in jQuery 1.8, removed in 1.9: The name "hover" used as a shorthand for the string "mouseenter mouseleave". It attaches a single event handler for those two events, and the handler must examine event.type to determine whether the event is mouseenter or mouseleave. Do not confuse the "hover" pseudo-event-name with the .hover() method, which accepts one or two functions.

How to set the focus for a particular field in a Bootstrap modal, once it appears

I've seen a couple of questions in regards to bootstrap modals, but none exactly like this, so I'll go ahead.
I have a modal that I call onclick like so...
$(".modal-link").click(function(event){
$("#modal-content").modal('show');
});
This works fine, but when I show the modal I want to focus on the first input element... In may case the first input element has an id of #photo_name.
So I tried
$(".modal-link").click(function(event){
$("#modal-content").modal('show');
$("input#photo_name").focus();
});
But this was to no avail. Lastly, I tried binding to the 'show' event but even so, the input won't focus. Lastly just for testing, as I had a suspiscion this is about the js loading order, I put in a setTimeout just to see if I delay a second, will the focus work, and yes, it works! But this method is obviously crap. Is there some way to have the same effect as below without using a setTimeout?
$("#modal-content").on('show', function(event){
window.setTimeout(function(){
$(event.currentTarget).find('input#photo_name').first().focus()
}, 0500);
});
Try this
Here is the old DEMO:
EDIT:
(Here is a working DEMO with Bootstrap 3 and jQuery 1.8.3)
$(document).ready(function() {
$('#modal-content').modal('show');
$('#modal-content').on('shown', function() {
$("#txtname").focus();
})
});
Starting bootstrap 3 need to use shown.bs.modal event:
$('#modal-content').on('shown.bs.modal', function() {
$("#txtname").focus();
})
Just wanted to say that Bootstrap 3 handles this a bit differently. The event name is "shown.bs.modal".
$('#themodal').on('shown.bs.modal', function () {
$("#txtname").focus();
});
or put the focus on the first visible input like this:
.modal('show').on('shown.bs.modal', function ()
{
$('input:visible:first').focus();
})
http://getbootstrap.com/javascript/#modals
I am using this in my layout to capture all modals and focus on the first input
$('.modal').on('shown', function() {
$(this).find('input').focus();
});
I had the same problem with bootstrap 3, focus when i click the link, but not when trigger the event with javascript.
The solution:
$('#myModal').on('shown.bs.modal', function () {
setTimeout(function(){
$('#inputId').focus();
}, 100);
});
Probably it´s something about the animation!
I had problem to catch "shown.bs.modal" event.. And this is my solution which works perfect..
Instead simple on():
$('#modal').on 'shown.bs.modal', ->
Use on() with delegated element:
$('body').on 'shown.bs.modal', '#modal', ->
Seems it is because modal animation is enabled (fade in class of the dialog), after calling .modal('show'), the dialog is not immediately visible, so it can't get focus at this time.
I can think of two ways to solve this problem:
Remove fade from class, so the dialog is immediately visible after calling .modal('show'). You can see http://codebins.com/bin/4ldqp7x/4 for demo. (Sorry #keyur, I mistakenly edited and saved as new version of your example)
Call focus() in shown event like what #keyur wrote.
I've created a dynamic way to call each event automatically. It perfect to focus a field, because it call the event just once, removing it after use.
function modalEvents() {
var modal = $('#modal');
var events = ['show', 'shown', 'hide', 'hidden'];
$(events).each(function (index, event) {
modal.on(event + '.bs.modal', function (e) {
var callback = modal.data(event + '-callback');
if (typeof callback != 'undefined') {
callback.call();
modal.removeData(event + '-callback');
}
});
});
}
You just need to call modalEvents() on document ready.
Use:
$('#modal').data('show-callback', function() {
$("input#photo_name").focus();
});
So, you can use the same modal to load what you want without worry about remove events every time.
I had the same problem with the bootstrap 3 and solved like this:
$('#myModal').on('shown.bs.modal', function (e) {
$(this).find('input[type=text]:visible:first').focus();
})
$('#myModal').modal('show').trigger('shown');
Bootstrap has added a loaded event.
https://getbootstrap.com/docs/3.3/javascript/#modals
capture the 'loaded.bs.modal' event on the modal
$('#mymodal').on('loaded.bs.modal', function(e) {
// do cool stuff here all day… no need to change bootstrap
})
Bootstrap modal show event
$('#modal-content').on('show.bs.modal', function() {
$("#txtname").focus();
})
A little cleaner and more modular solution might be:
$(document).ready(function(){
$('.modal').success(function() {
$('input:text:visible:first').focus();
});
});
Or using your ID as an example instead:
$(document).ready(function(){
$('#modal-content').modal('show').success(function() {
$('input:text:visible:first').focus();
});
});
Hope that helps..

Categories

Resources