.append link will not fire onclick function - javascript

I've searched around I cannot find the answer to this. In my code, a link is created inside of a div and given an onclick value to pass an argument to a function. I cannot figure out why it will not fire.
var imgCount = 0;
var curImg;
function resetImg(target) {
alert(target);
}
$(".add").click(function () {
imgCount = imgCount + 1;
curImg = "theImg" + imgCount;
//Here we add the remove link
$('#links')
.append('Call Function');
$('.dynamic').css('display', 'block');
});
Here's the fiddle:
http://jsfiddle.net/stewarjs/4UV7A/
I've tried using .click() when creating the link, but the argument being passed needs to be unique to each link. I've tried grabbing $(this).attr("id") but the value comes back undefined.
Thanks for any and all help.
Jeff

Rather than try to mangle HTML into JavaScript, I suggest you use the jQuery methods already available to you.
$('#links')
.append($("<a>").attr('href', '#').on('click', function () { resetImg(curImg);
}).addClass('dynamic').text('Call Function'));
http://jsfiddle.net/ExplosionPIlls/4UV7A/1/

remove javascript: from onclick, it should like like this: onclick="resetImg(\'' + curImg + '\');"

There's always a way to get rid of onclick handlers. Here's how I'd do it:
var image_count = 0;
$('#links').on('click', '.dynamic', function(e) {
e.preventDefault()
alert($(this).data('image'));
});
$('.add').click(function () {
$('<a />', {
'href': '#',
'data-image': 'theImg' + (++image_count),
'class': 'dynamic',
'text': 'Call function'
}).appendTo('#links');
});
Demo: http://jsfiddle.net/4UV7A/4/

Related

How can I loop variables with Jquery

I'm new with Javascript and Jquery and I'm facing a small problem.
I'm trying to make sure that if a given link exists, hovering over this link will bring up a popup with the fadeToggle().
So I wrote this code that works:
if ($('.link-1')) {
$('.link-1').mouseover(function () {
$('.popup-1').fadeToggle();
})
.mouseout(function () {
$('.popup-1').fadeToggle();
})
}
But, instead of repeating it ten times, I wanted to write a loop, like this:
var number = 0;
while (number < 10) {
var popup = '.popup-' + number;
var link = '.link-' + number;
if ($(link)) {
$(link).mouseover(function () {
$(popup).fadeToggle();
})
.mouseout(function () {
$(popup).fadeToggle();
})
}
number++;
}
But it does not work. Could you help me please ?
I thank you in advance !
Based on your comments, I'd recommend this approach.
Add a data attribute to each link that corresponds with the popup you want to fire. This will look something like this:
<a href='#' class='link-1' data-popup='popup-1'> Link </a>
Then add a hover event to ALL links, that performs an action if it has the data type:
//hover event on all links(assumes anchor tags)
$('a').mouseover(function () {
if ($(this).attr('data-popup')) {
let popup = '.' + $(this).attr('data-popup');
$(`${popup}`).fadeToggle();
}})
.mouseout(function () {
if ($(this).attr('data-popup')) {
let popup = '.' + $(this).attr('data-popup');
$(`${popup}`).fadeToggle();
}})
You could also make this a single line function using .hover instead of .mouseover and .mouseout if it fits your use case
**refactoring process is added here:
//start with the original function
$('a').hover(function () {
if ($(this).attr('data-popup')) {
let popup = '.' + $(this).attr('data-popup');
$(`${popup}`).fadeToggle();
}})
//consolidate the enter and exit events using .hover()
$('a').hover(function () {
if ($(this).attr('data-popup')) {
let popup = '.' + $(this).attr('data-popup');
$(`${popup}`).fadeToggle();
}})
//remove the if statement, because the function firing without a pop up won't result in any effect
$('a').hover(function () {
let popup = '.' + $(this).attr('data-popup');
$(`${popup}`).fadeToggle();
})
//substitute the variable directly into the jquery tag
$('a').hover(function () {
$(`'.${$(this).attr('data-popup')}`).fadeToggle();
})
// use an ES6 arrow function to make this a one line function
$('a').hover(() => $(`.${$(this).attr('data-popup')}`).fadeToggle())
//as is, this function won't work, because the arrow function binds the "this" keyword differently.
//Event handlers have an optional parameter that is an event JSON object, so we pass that into the function.
//Because it is a parameter, and is used as a variable we can call event "e" for short
//target is a property of the JSON object 'event' that indicates what specific element is triggering the event
// You can console log "e" to see what other values are baked into the event
$('a').hover((e) => $(`.${$(e.target).attr('data-popup')}`).fadeToggle())
//lastly, because we are using an anonymous arrow function with only one parameter, we can omit the parenthesis around the paremeter
$('a').hover(e => $(`.${$(e.target).attr('data-popup')}`).fadeToggle())
The end result is the one liner below!
$('a').hover(e => $(`.${$(e.target).attr('data-popup')}`).fadeToggle())
Additional info on data attributes can be found here:
https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
welcome to the web community :-)
My jQuery skills are a bit rusty, but I recall, that there is an Attribute Contains Selector, which you could combine with .each() like so:
$('[class*="link-"]').each(function (index, link) {
$('[class="popup-"' + index + '"]').each(function (_, popup) {
$(link)
.mouseover(function () {
$(popup).fadeToggle();
})
.mouseout(function () {
$(popup).fadeToggle();
})
}
}
The second index is not interesting, that's why I named the argument „_”.
Let me know, whether it still works
If your objects are in order from link-1 to link-10, you can try this method
Loop object that has class "link-[number]" using each function
save number using index + 1
give action to object that have been hovered
so the code will be like this:
$('[class*="link-"]').each(function (index) {
var number = index + 1; //index start from 0, so it need to add + 1
$(this)
.mouseover(function () {
$('[class="popup-' + number+ '"]').fadeToggle();
})
.mouseout(function () {
$('[class="popup-' + number+ '"]').fadeToggle();
})
});
But if your object are not in order from link-1 to link-10, I recommend to use custom data attribute in your HTML code.
Example:
<a class="link-1" data-number="1">test 1</a>
<div class="popup-1" style="display:none">
test 1 popup
</div>
Then change number variable to this code:
var number = $(this).attr("data-number");
It will more save.
Hope it helps.

Bind an event on a jquery generated element

My code is like this:
$('.flag-icon-dz').click(function() {
var lang = 'Arab';
var $frame = $('.goog-te-menu-frame:first');
if (!$frame.size()) {
console.log("Error: Could not find Google translate frame.");
return false;
}
$frame.contents().find('.goog-te-menu2-item span.text:contains(' + lang + ')').get(0).click();
$("li.ql-item.linkid188546").after("<li class='ql-item linkid18854777 closegoogle'><a href='#' class='btn-primary' target='_self'><i class='icon closegoogle ls-lang-frr' aria-hidden='true'></i></a></li>").fadeIn(500);
$('li.ql-item.linkid188546').fadeOut(500);
return false;
});
$('.closegoogle').click(function() {
$('.skiptranslate').contents().find('.goog-close-link > img').click();
$('li.ql-item.linkid18854777').fadeOut('fast').remove();
$('li.ql-item.linkid188546').fadeIn(500);
});
The first function works great, but the second doesn't. I realize that if I copy/paste the second function in the console after the first one, it works too.
I tried a few solutions (callback / setTimeout / jquery deferred / jquery .when method...) I didn't try promise but I don't think I have to in my context. Maybe I didn't write these solutions good enough.
I finally try to put my event (click) directly the .before() which create my new element like this :
$('.flag-icon-dz').click(function() {
var lang = 'Arab';
var $frame = $('.goog-te-menu-frame:first');
if (!$frame.size()) {
console.log("Error: Could not find Google translate frame.");
return false;
}
$frame.contents().find('.goog-te-menu2-item span.text:contains(' + lang + ')').get(0).click();
$("li.ql-item.linkid188546").after("<li class='ql-item linkid18854777 closegoogle'><a href='#' class='btn-primary' target='_self'><i class='icon closegoogle ls-lang-frr' aria-hidden='true'></i></a></li>").fadeIn(500).click(function() {
$('.skiptranslate').contents().find('.goog-close-link > img').click();
$('li.ql-item.linkid18854777').fadeOut('fast').remove();
$('li.ql-item.linkid188546').fadeIn(500);
});
$('li.ql-item.linkid188546').fadeOut(500);
return false;
});
But it doesn't work either.
Thanks for the help.
EDIT :
I finally found a kind of solution for my second click event (which isn't the best solution but i works) :
window.setInterval(function(){$('.closegoogle').on("click",function(){
$('.skiptranslate').contents().find('.goog-close-link > img').click();
$('li.ql-item.linkid18854777').fadeOut('fast').remove();
$('li.ql-item.linkid188546').fadeIn(500);
}); }, 1000);
Thanks.
You need to use a delegated bind as the element does not exist before you try your binding:
$('#parent-element-of-closegoogle').on('click', '.closegoogle', function() {
$('.skiptranslate').contents().find('.goog-close-link > img').click();
$('li.ql-item.linkid18854777').fadeOut('fast').remove();
$('li.ql-item.linkid188546').fadeIn(500);
});
Please note that the #parent-element-of-closegoogle needs to be an element that already exists when you do the binding - this can be $(document) if you hjave no other element to bind to

How to Show Dynamically Added Element

I'm trying to create tooltips with title attribute and jQuery but can't find method to show dynamically added element.
HTML
some page
CSS
.tooltip {
    …
display: none; /* I's needed for hard coded tooltips */
…
}
jQuery
$(function () {
if (window.matchMedia('(min-width: 980px)').matches) {
$('.dfn').hover(
function () {
var el = $(this);
var txtTitle = el.prop('title');
el.append('<p class="tooltip">' + txtTitle + '</p>');
                //That's it. My tooltip has been created, but it has not been shown
$(el + ' .tooltip').show('fast');
el.data('title', el.prop('title'));
el.removeAttr('title');
}, function () {
$(el + ' .tooltip').hide('fast').remove();
el.prop('title', el.data('title'));
}
);
}
});
As mentioned by others, $(el + ' .tooltip').show('fast'); is probably wrong.
The el is an object, not a string to concat', one way is to use el.find('.tooltip').show().
The other way is to use the context option: $('.tooltip', el).show();
You need to have correct code to find new element:
$('.tooltip', el).show('fast');
Your current one probably endup searching for something like [object] .tooltip or similar string depending on how JavaScript decides to convert HTML element to string.
As others have mentioned el.find('.tooltip').show() and el.find('.tooltip').hide().remove(); solve the problem.
Also, in HandlerOut function, you el was not declared. Fiddle here
$(function () {
//if (window.matchMedia('(min-width: 980px)').matches) {
$('.dfn').hover(
function () {
var el = $(this);
var txtTitle = el.prop('title');
el.append('<p class="tooltip">' + txtTitle + '</p>');
//That's it. My tooltip has been created, but it has not been shown
el.find('.tooltip').show()
el.data('title', el.prop('title'));
el.removeAttr('title');
}, function () {
var el = $(this);
el.find('.tooltip').hide().remove();
el.prop('title', el.data('title'));
}
);
//}
});

Call Javascript Function with argument and use argument as a variable name

I've the following snip of a code:
var about = "about.html";
function loadPage(target){
$("#dashboard").load(target);
}
$(".nav li").click(function(){
loadPage($(this).attr("class"));
});
So when I click on a button like <li class="about">, target is = about.
But in that way, $("#dashboard").load(target); doesn't load the variable about which is the html-file which I want to load.
So how is it possible to call the variable in this way?
You seem to miss the .html part. Try with
$("#dashboard").load(target+'.html');
But, supposing you have only one class on your li element, you'd better use this.className rather than $(this).attr("class").
EDIT :
if you want to use your about variable, you may do this :
$("#dashboard").load(window[target]);
But it would thus be cleaner to have a map :
var pages = {
'about': 'about.html',
'home': 'welcome.jsp'
}
function loadPage(target){
$("#dashboard").load(pages[target]);
}
$(".nav li").click(function(){
loadPage(this.className);
});
A stupid answer : create a <a> tag, and set its href attribute to the correct value.
Otherwise :
A standard way to store key: values pairs in javascript is to use a plain object :
var urls = {};
urls['about'] = 'mysuperduperurlforabout.html';
function loadPage(target) {
var url = urls[target];
//maybe check if url is defined ?
$('#dashboard').load(url);
}
$(".nav li").click(function(){
loadPage($(this).attr("class") + ".html");
});
or
$("#dashboard").load(target+".html");
You can call the variables like this (if that's what you asked):
var test = 'we are here';
var x = 'test';
console.log(window[x]);
It's similar to the $$ in PHP. The output will be:
we are here in the console window.
You could put the "about" as an object or array reference similar to:
var pageReferences = [];
pageReferences["about"] = "about.html";
var otherReference = {
"about": "about.html"
};
function loadPage(target) {
alert(pageReferences[target]);
alert(otherReference[target]);
$("#dashboard").load(target);
}
$(".nav li").click(function () {
loadPage($(this).attr("class"));
});
Both of these alerts will alert "about.html" referencing the appropriate objects.
EDIT: IF you wished to populate the object based on markup you could do:
var otherReference = {};
$(document).ready(function () {
$('.nav').find('li').each(function () {
var me = $(this).attr('class');
otherReference[me] = me + ".html";
});
});
You could even store the extension in an additional attribute:
var otherReference = {};
$(document).ready(function () {
$('.nav').find('li').each(function () {
var me = $(this).attr('class');
otherReference[me] = me + "." + $(this).attr("extension");
});
});
Better would be to simply put the page reference in a data element:
<li class="myli" data-pagetoload="about.html">Howdy</li>
$(".nav li").click(function () {
loadPage($(this).data("pagetoload"));
});

How to get outer element value in JavaScript

I have the following jQuery code:
$('.active #search').on('mouseout', function () {
$('#search_box #search').not('.active').each(function(){
this.value = $('.active #search')[0].value;
})
});
It works, but I have to call $('.active #search') twice. How can I refer to the $('.active #search') array from within my inner function?
P/S: I know I'll be complained about giving multiple elements same ID, but this seem to be generated by Rails automatically (text_field_tag).
I think this is what you're looking for:
$('.active #search').on('mouseout', function () {
var val = $(this)[0].value; //cache value of $('.active #search').
$('#search_box #search').not('.active').each(function () {
this.value = val;
})
});
You can do something like below. I added self = $(this)
$('.active #search').on('mouseout', function () {
var self = $(this);
$('#search_box #search').not('.active').each(function(){
this.value = self[0].value;
});
});
Here is a link to very good explanation of 'this' keyword, explained by Jeffrey Way
tutsplus.com/lesson/the-this-keyword
Therese several ways of achieving this:
var activeSearch = $('.active #search');
activeSearch.on('mouseout', function () {
$('#search_box #search').not('.active').each(function(){
this.value = activeSearch.val();
})
});
notice that since this is an id you are querying for you should have only one element so you can replace activeSearch[0].value with activeSearch.val();
second way:
$('.active #search').on('mouseout', function () {
var activeSearch = $(this);
$('#search_box #search').not('.active').each(function(){
this.value = activeSearch.val();
})
});
when in an event handler $(this) will give you a jquery object of the event sender. you can further simplify it by ignoring jquery and just using plain elements by doing the following:
$('.active #search').on('mouseout', function () {
var activeSearch = this;
$('#search_box #search').not('.active').each(function(){
this.value = activeSearch.value;
})
});
this is the same as above but you arent dealing with jquery objects.
What you end up using depends on you but the final code snippet would be my preferred way.
You can use $(this) instead of using the $('.active #search')

Categories