JavaScript attr('id') and this - javascript

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"
);
});
});

Related

Jquery get "this" from an if statement

I'm trying to fetch a unique value from an element using jquery, this value is supposed to appear when I scroll to a certain place on the screen. When the element is onscreen, the postId 15 is supposed to reach the jquery code.
This is my code:
$(document).scroll(function() {
if($("p.viewedPost").is(':onScreen')) {
var postId = $(this).attr("postId");
console.log("Element appeared on Screen " + postId);
}
else {
console.log("Element not on Screen");
//do all your stuffs here when element is not visible.
}
});
The problem is that I have multiple postId's, so I can't use $("p.viewedPost").attr("postId");
It needs to be $(this).attr("postId");
But when I use "this", the postId appears to be undefined. So how can I get the $("p.viewedPost").is(':onScreen') to have a this ?
Thanks.
You are looking for .filter() and .each():
$("p.viewedPost").filter(':onScreen').each(function () {
var postId = $(this).attr("postId");
console.log("Element appeared on Screen " + postId);
});
If your plugin's :onScreen selector does not work with .filter, then you can put the test inside the each callback:
$("p.viewedPost").each(function () {
if (!$(this).is(':onScreen')) return; // skip
var postId = $(this).attr("postId");
console.log("Element appeared on Screen " + postId);
});

How do I have an event filter a page?

I'm working on a twitter clone in JS + jQuery for a pre-course to a development program, so if this is an obvious fix - let me know!
I have a problem I'm unable to solve: "click on username, page returns with that user's last tweets".
The only thing I could come up with is, an event handler on the <a> tag filter the page. However I'm vastly inexperienced and unclear in how to proceed.
Any ideas?
note- I removed some code for brevity.
$(document).ready(function() {
var $body = $('body');
$body.html();
var stream = function() {
var index = streams.home.length - 1;
while (index >= 0) {
var tweet = streams.home[index];
var $tweet = $('<div class="tweetbody"></div>');
$tweet.text(': ' + tweet.message);
$tweet.appendTo($body);
index -= 1;
var link = $('<a>', {
text: tweet.user,
href: '#',
}).prop('outerHTML');
$tweet.html('#' + link + ': ' + tweet.message);
}
};
Here's the <a> tag event:
//click on a username to see that user's timeline.
$('a').on('click', function() {
console.log("a tag is clicked ");
console.log(this);
});
}();
}); //end document ready body
In the on click function you could perhaps do either of the two things, so go to another page, like redirecting to a new page
//click on a username to see that user's timeline.
$('a').on('click', function() {
//console.log("a tag is clicked ");
//console.log(this);
window.location = '/some_file.php?get_tweets='+tweet.user;
});
or, use an ajax call to do the same:
//click on a username to see that user's timeline.
$('a').on('click', function() {
//console.log("a tag is clicked ");
//console.log(this);
$.ajax({
type: "GET",
url: "/some_file.php",
data: {
'user' : tweet.user
},
success: function(msg) {
$body.html(msg);
});
});
In both cases some_file.php should format the content.

Class not changing after get request Jquery

I'm having trouble changing the class after making a jquery get request.
code:
<script>
//global variable
var table = []
var numberofaccounts = 0
$(document).ready(function() {
$('#form1').validate();
// add numbers to select ids
$(".select_changer").each(function(){
numberofaccounts++;
var new_id = "select_class"+numberofaccounts;
$(this).addClass(new_id);
});
$('#apply_btn').click(function() {
table = []
var count = 0;
var text = "";
var tracker = 0
$('#stats_table tr').each(function(){
count = 0;
text = "";
$(this).find('td').each(function(){
count++;
if (count == 4) {
text += $( ".select_class"+ tracker + " option:selected" ).val();
} else {
text += " " + $(this).text() + " ";
}
})
table.push(text);
tracker++;
});
$.post("/apply_changes", {"data": JSON.stringify(table)}, function(data) {
var res = JSON.parse(data);
if (res.data == true){
$('#updated').text("Update Successful").css('color', 'green');
$.get("/", function( data ) {
$('#stats_table').load("/ #stats_table");
numberofaccounts = 0
$(".select_changer").each(function(){
numberofaccounts++;
var new_id = "select_class"+numberofaccounts;
$(this).addClass(new_id);
});
});
} else {
$('#updated').text("Update Unsuccessful").css('color', 'red');
}
});
});
});
</script>
So when the page first loads this method changes the class on dynamically created select elements.
$(".select_changer").each(function(){
numberofaccounts++;
var new_id = "select_class"+numberofaccounts;
$(this).addClass(new_id);
});
After I make a post to flask the if the response data is true I go ahead and make a get request to grab the updated items from the db. I then refresh the table. This works great if I make one request. However on the second post nothing happens. This is because the classes that I modified at the start of the page load no longer exist. So i added the method above to also trigger after the get response (I also tried at the end of the post response). The problem is that the method doesn't seem to run again. The classes aren't there and as a result when I go to make another post request it can't find the element. How do I go about fixing this?
Things to note: The get request is necessary, the ids and classes cannot be statically assigned.
You are trying to assign classes before you even refresh your table.
$('#stats_table').load("/ #stats_table"); is called asynchronously and returns before it even completes.
You need to put you code, for assigning classes, inside the complete callback of your .load() call:
$('#stats_table').load("/ #stats_table", function() {
numberofaccounts = 0
$(".select_changer").each(function(){
numberofaccounts++;
var new_id = "select_class"+numberofaccounts;
$(this).addClass(new_id);
});
});

Infinite scroll repeatition of same ids

Following is my function which I am using to load data as per < last id of li .post-list but still I am getting repetition of same ids that were pulled before. Kindly let me know how can I resolve this issue so the old ids doesn't load/repeat itself again.:
function loadData()
{
$('div.postloader').html('<img src="img/loader.gif">');
$.post("getData.php?lastID=" + $(".post-list:last").attr("id"),
function(data){
if (data != "") {
$(".post-list:last").after(data);
}
$('div.postloader').empty();
});
};
A possible soution to prevent this is to store the last ID in a global variable in JS and increment that, so you don't have to rely on selecting the right element to find the ID to POST.
you're pulling the data from the server too fast, try adding a flag that will prevent pulling the items while the request is running:
var flagPulling = false;
function loadData() {
if( flagPulling ) {
return;
}
flagPulling = true;
$('div.postloader').html('<img src="http://www.zesteve.com/img/loader.gif">');
$.post("/getData.php?lastID=" + $(".post-list:last").attr("id"), function(data){
if (data != "") {
$(".post-list:last").after(data);
}
$('div.postloader').empty();
flagPulling = false;
});
};

jQuery getting ID of clicked link

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');

Categories