I have a modal box in jQuery which I have created to display some embed code. I want the script to take the id of the link that is clicked but I can't seem to get this working.
Does anyone know how I can do that or why this may be happening?
My jQuery code is:
function generateCode() {
var answerid = $('.openembed').attr('id');
if($('#embed input[name="comments"]:checked').length > 0 == true) {
var comments = "&comments=1";
} else {
var comments = "";
}
$("#embedcode").html('<code><iframe src="embed.php?answerid=' + answerid + comments + '" width="550" height="' + $('#embed input[name="size"]').val() + '" frameborder="0"></iframe></code>');
}
$(document).ready(function () {
$('.openembed').click(function () {
generateCode();
var answerid = $('.openembed').attr('id');
$('#box').show();
return false;
});
$('#embed').click(function (e) {
e.stopPropagation()
});
$(document).click(function () {
$('#box').hide()
});
});
My mark-up is:
Embed
Embed
Your problem is here:
$('.openembed')
returns an array of matched elements. Your should instead select only the clicked element.
$('.openembed') works correctly if you assing a click event to all elements that have this class. But on the other hand, you're unable do know which is clicked.
But fortunately in the body of handler function click you could call $(this).
$(this) will return the current (and clicked element).
// var answerid = $('.openembed').attr('id'); // Wrong
var answerid = $(this).attr('id'); // Correct
// Now you can call generateCode
generateCode(answerid);
Another error is the body of generateCode function. Here you should pass the id of selected element. This is the correct implementation.
function generateCode(answerid) {
if($('#embed input[name="comments"]:checked').length > 0 == true) {
var comments = "&comments=1";
} else {
var comments = "";
}
$("#embedcode").html('<iframe src="embed.php?answerid=' + answerid + comments + '" width="550" height="' + $('#embed input[name="size"]').val() + '"frameborder="0"></iframe>');
}
Here I have implemented your code with the correct behavior: http://jsfiddle.net/pSZZF/2/
Instead of referencing the class, which will grab all members of that class, you need to reference $(this) so you can get that unique link when it is clicked.
var answerid = $(this).prop('id');
$('.openembed').click(function () {
generateCode();
var answerid = $(this).attr('id');
$('#box').show();
return false;
});
Use $(this). $('.openembed') refers to multiple links.
var answerid = $('.openembed').attr('id');
needs to be
var answerid = $(this).prop('id');
The other answers are trying to fix the click() function, but your issue is actually with the generateCode function.
You need to pass the clicked element to the generateCode function:
$('.openembed').click(function () {
generateCode(this);
And modify generateCode:
function generateCode(element) {
var answerid = element.id;
Of course var answerid = $('.openembed').attr('id'); within the click code isn't correct either, but it doesn't seem to do anything anyway.
Get the id when the correct anchor is clicked and pass it into your generateCode function
$('.openembed').click(function () {
var answerid = $(this).attr('id');
generateCode(answerid)
$('#box').show();
return false;
});
Change your function
function generateCode(answerid) {
// dont need this line anymore
// var answerid = $('.openembed').attr('id');
Related
If you take a look at this fiddle it will seem fine, but if you click next and move down 2 to 3 times, and then click "memory" (in top nav) it takes .active back to the first .item,
then if you click 'NEXT' again it continues to go to the next element from the prior one we left off of.
I am trying to reset it and continue based on where we go after clicking on the top nav.
Faulty jQuery:* Two click functions both adding active*
var items = $('.item'),
currentItem = items.filter('.active'),
last = items.last();
$("#next-button").on('click', function () {
currentItem.removeClass('active');
var nextItem = currentItem.next();
if (nextItem.length) {
currentItem = nextItem.addClass('active');
if (currentItem.is(last)) {
$('#slide-buttons').addClass('red');
}
}
var items = $('.item');
$(".breadcrumb-cell .breadcrumb").click(function () {
var theID = $(this).data("id");
items.filter(function() {
return $(this).data('category') === theID;
}).addClass('active');
});
});
Fiddle
I Googled "how to reset .next() jquery" but couldn't find anything, not sure if that's even the right thing to do?
The problem you had was that currentItem didn't get updated when you clicked on a breadcrumb.
I made a lot of changes, mostly "streamlining" things. I removed your global variables and based the current item on the active class instead. Check: http://jsfiddle.net/kQabJ/17/
$("#next-button").on('click', function () {
var nextItem = $('.active').removeClass('active').next();
if (!nextItem.length) {
nextItem = $('.item').first();
}
nextItem.addClass('active');
});
$(".breadcrumb-cell .breadcrumb").on('click', function () {
$('.active').removeClass('active');
var theID = $(this).data("id");
$("#" + theID).addClass('active');
});
Note that I also modified your DOM a bit to make it easier to select an item when a user clicks a breadcrumb. That change is using an ID on your .items instead of data. This way you can do $("#" + theID) rather than filtering based on data.
Since these things are uniquely identifying your .item elements themselves - it makes since to use an id anyway, but if this is not what you not you can always change that part back.
You just need to update currentItem, see http://jsfiddle.net/kQabJ/13/
$(".breadcrumb-cell .breadcrumb").on('click', function () {
items.removeClass('active');
var theID = $(this).data("id");
items.filter(function() {
return $(this).data('category') === theID;
}).addClass('active');
currentItem = items.filter('.active');
});
Try this code
You were not updating the currentItem, which was causing the problem.
var items = $('.item'),
currentItem = items.filter('.active'),
last = items.last();
$("#next-button").on('click', function () {
currentItem = items.filter('.active');
var nextItem = currentItem.next();
currentItem.next().length > 0 ? currentItem.next().addClass('active')
: items.first().addClass('active');
currentItem.removeClass('active');
});
$(".breadcrumb-cell .breadcrumb").on('click', function () {
items.removeClass('active');
var theID = $(this).data("id");
items.filter(function () {
return $(this).data('category') === theID;
}).addClass('active');
});
Check Fiddle
Not sure how to formulate this but here it goes.
I am checking if a var exists (content), if it doesnt i set it.
Problem is next click, it still behaves as if there is no var content. But why??
Here my code:
$("#nav a").click(function(event) {
event.preventDefault();
var href = $(this).attr("href");
var load = href + " .content";
if (!content)
{
var content = $('<div>').load(load);
$(".content").append(content);
}
else
{
var position = content.offset();
$(document).scrollTop(position);
}
});
It never results to else, so always a click is made the whole load and append function repeats.
Basically how can I record that content for this particular link has been loaded once, so the else function should be performed next time?
Also, what is wrong with my if(!content) statement? Is it because of scope?
In Javascript functions determine the scope of an object. You need to place content in the global scope. Currently it is created within the anonymous function assigned to the click event handler, so when the function is executed again content is out of scope causing it to return false.
var content;
$("#nav a").click(function(event) {
event.preventDefault();
var href = $(this).attr("href");
var load = href + " .content";
if (!content)
{
content = $('<div>').load(load);
$(".content").append(content);
}
else
{
var position = content.offset();
$(document).scrollTop(position);
}
});
Try to make the var content as a global variable rather than a local one, like you are doing right now. That's why the if (!content) result as true always, like:
var content;
$("#nav a").click(function (event) {
event.preventDefault();
var href = $(this).attr("href");
var load = href + " .content";
if (!content) {
content = $('<div>').load(load);
$(".content").append(content);
} else {
$(document).scrollTop(content.offset());
}
});
Just to show what happens, when value of content is not set at first and then set again:
var content;
console.log(content); // undefined
console.log(!content); // true
content = 'text';
console.log(content); // text
console.log(!content); // false
Thanks to everyone for answering the first question about the checking if var exists.
I ended up ditching this whole concept it turned out the
one()
function is what I needed all along. In order to only execute a function once and another function on all following clicks.
Here it is:
$(document).ready(function() {
//Ajaxify Navi
$("#nav a").one("click", function(event) {
event.preventDefault();
var href = $(this).attr("href");
var load = href + " .content";
var content = $('<div>').load(load);
$(".content").append(content);
$(this).click(function(event) {
event.preventDefault();
var position = content.offset().top;
$(document).scrollTop(position);
$("body").append(position);
});
});
});
What this is is the following:
1st click on a button loads content via ajax and appends it, second click on the same button only scrolls to said content.
I'm having a problem with my code, lemme first paste my code, most of it isn't important, just the context of it.
$("#navbar > a").click(function(event) {
$('#controls').show();
var currentNum = parseInt($(this).attr('class'), 10);
document.getElementById('pNum').innerHTML = "pg. " + (currentNum + 1);
event.preventDefault();
var t2 = ($(this).attr('id')).split("#");
var $tr = $(zip.file(localStorage.selected + "/" + t2[0]).asText());
document.getElementById('main').innerHTML = "";
$('#main').append($tr);
document.getElementById(t2[1]).scrollIntoView()
current = ($(this).attr('class'));
$(function() {
$("#main img").each(function() {
var imgPath = localStorage.selected + "/" + $(this).attr('src');
var imageData = zip.file(imgPath).asBinary();
$(this).attr('src', 'data:image/jpeg;base64,' + btoa(imageData));
});
});
$("#main a").click(function(event){
event.preventDefault();
var elems = ($(this).attr('href')).split("#");
var $path = $(zip.file(localStorage.selected + "/" + elems[0]).asText());
document.getElementById('main').innerHTML = "";
$('#main').append($path);
});
});
Now the click event at the bottom only works if I place it inside the code that creates the content, which shouldn't be the case and secondly it only works once, after I call it for the first time it refuses to work, any suggestions ?
It sounds like you want to use event delegation instead. For example:
$(document).on('click', '#main a', function(event){
event.preventDefault();
var elems = ($(this).attr('href')).split("#");
var $path = $(zip.file(localStorage.selected + "/" + elems[0]).asText());
document.getElementById('main').innerHTML = "";
$('#main').append($path);
});
The problem is that the $('#main a').click(...) approach requires that the #main a elements already be present on the page at the time that the click handler is bound.
Event delegation allows you to listen for a click event on the document (or any other element that will always be present), and see if that event originated from a #main a element. This allows you to add/remove elements on the fly without worrying about which ones have or haven't already had click handlers bound.
I've had this problem before, have you tried using this?:
$("<element id>").on( 'click', this, function ()
{
// Your code here
}
reference: http://api.jquery.com/on/
edit* Sorry did not see an answer before ( better explanation in answer above ) - but I'll keep mine for reference.
I'm working on a website that makes use of isotope filters and hash history.
However, in order for my filters to work I need #filter=.print to be added after the permalink of my thumbnails "a.perma". the ".print" is the class of the filter thats being clicked "option-set a". In this case the print filter.
I am not too skilled at jQuery and any help would be appreciated.
Here's the code I've been messing with:
var myClass;
jQuery("option-set a").click(function() {
myClass = jQuery(this).attr("class");
});
jQuery("a.perma").each(function() {
var _href = jQuery(this).attr("href");
jQuery(this).attr("href", _href + myClass);
});
Here is the working code. Removes any previous filters. Keeps the permalink value even after going to another page and coming back. Uses localStorage.
if(typeof(Storage)!=="undefined") {
var oldClass = localStorage.getItem("permalink");
if(oldClass != null && oldClass != "") {
jQuery("a.perma").each(function() {
var _href = jQuery(this).attr("href");
_href = _href.split("#")[0];
jQuery(this).attr("href", _href + "#filter=." + oldClass);
});
}
}
jQuery("option-set a").click(function() {
myClass = jQuery(this).attr("class");
jQuery("a.perma").each(function() {
var _href = jQuery(this).attr("href");
_href = _href.split("#")[0];
jQuery(this).attr("href", _href + "#filter=." + myClass);
if(typeof(Storage)!=="undefined") {
localStorage.setItem("permalink", myClass);
}
});
});
You could try this, using .attr() with a function to determine and set the new value to avoid having to iterate and get/set separately.
jQuery("option-set a").click(function() {
var myClass = this.className; // same as $(this).attr('class');
jQuery('a.perma').attr('href', function(i, oldHref) {
return oldHref + '.' + myClass;
});
});
Depending on what the original href attributes look like you may have to add more or less to the string; I've assumed in the above that the #filter= part is already included. You may also want to check that it's not already in the existing href so it's not added more than once.
So I'm not really good in JavaScript, but here's something I'm kind of stuck with:
So, I got this:
$(".post-click").click(function()
{
var classid = $(this).attr('id');
var postid = $(this).attr('id');
postid = postid.replace('post-click-id_', '');
alert("ID: " + classid + " PostID: " + postid);
$(this).replaceWith('<img SRC="assets/img/refresh.gif" ALT="" >');
$.post("likepost.php", { postid: postid } , function(data)
{
if(data.indexOf("Yes") >= 0)
{
//Question is about this part
}
else
{
//Question is about this part
}
});
});
Now, at that "Yes" or else part: How can I do it so I can replace the data from $(this) with replaceWith? I thought I could do it with classid, but I'm not really sure how to do that. I thought about this:
$(classid).replaceWith('Yes, yes indeed.');
$(classid).replaceWith('Nope.');
How would I make this work?
Assuming I've understood the question correctly and you're attempting to replace the clicked element inside the $.post callback, the easiest thing to do will be to maintain a reference to that element outside of the callback. This saves you from having to traverse the DOM again to reselect an element you have already selected once:
var clicked = $(this);
$.post("likepost.php", { postid: postid } , function(data) {
if(data.indexOf("Yes") >= 0) {
clicked.replaceWith("Yes");
} else {
clicked.replaceWith("No");
}
});
Your current attempt doesn't work because classid is simply a string representing the value of the id attribute. To create a jQuery object from it, you would need to append it to a "#" to produce a valid selector.
Don't use ids to find the element you just have (like $("#"+$(this).attr('id'))), but use it directly: $(this). As the this reference changes from function invocation to function invocation (it's different in your ajax callback), you will need to cache it in a variable.
$(".post-click").click(function() {
var loadImg = $('<img SRC="assets/img/refresh.gif" ALT="" >');
$(this).replaceWith(loadImg);
var toReplace = loadImg; // could be $(this) if you hadn't replaced it already
$.post("likepost.php", { postid: postid } , function(data) {
toReplace.replaceWith( data.indexOf("Yes") >= 0
? "success"
: "failed"
);
});
});