I have a few images, like
<img src="unstarred.png" class="unstarred-button" id="unstarred-1" />
<img src="unstarred.png" class="unstarred-button" id="unstarred-2" />
<img src="unstarred.png" class="unstarred-button" id="unstarred-3" />
<img src="unstarred.png" class="unstarred-button" id="unstarred-4" />
Then I bind this function:
$('.unstarred-button').click(function() {
id = $(this).attr('id').replace(/^unstarred-/, '');
url = '/star.php?id=' + id;
$.ajax({
type: 'GET',
url: url
}).done(function() {
// What should be put here?
});
});
Now I don't know how to go forward. I want to change the src attribute of the clicked image in the done() call, but $(this) doesn't return the image clicked for sure, as $(this).attr('id') is undefined according to alert().
Could someone help me out?
That's because this within the context of done doesn't refer to img. You need to save the context in the click event handler:
$('.unstarred-button').click(function() {
var self = $(this);
id = self.attr('id').replace(/^unstarred-/, '');
url = '/star.php?id=' + id;
$.ajax({
type: 'GET',
url: url
}).done(function() {
self.attr('src', 'something.jpg');
});
});
Also, you don't need jQuery to change the src or an id of a DOM element, you can change the attribute directly, i.e., this.src = 'something.jpg or this.id = 'new_id'.
$('.unstarred-button').click(function() {
var that = this;
var id = this.id.replace(/^unstarred-/, '');
var url = '/star.php?id=' + id;
$.ajax({
type: 'GET',
url: url
}).done(function() {
that.src = 'some/new/src.jpg';
});
});
Related
I'm working at a comment system for a website.
I am using jquery to update the view after comment under post is posted.
The element I am pushing the comment after post is like this:
<p class="card-text new_comment_{{$i->id}}" style="display:none"></p>
So what I do is
//Manages post in view
jQuery(function ($) {
$(document).ready(function () {
$("body").on("submit", ".dynamic-form", function (e) {
var form_id = '#' + $(this).attr('id');
//removes the 'post_' part from id
var id = this.id.replace('post_', '');
var new_comment_class = '.new_comment_' + id;
var new_comment_class_removal = 'new_comment_' + id;
var comments_id = '#comments_' + id;
var form = $(this);
$.ajax({
url: form.prop('action'),
type: 'post',
dataType: 'json',
data: $(this).serialize(),
success: function (data) {
var resultStr = "";
resultStr = resultStr + "<a href=\"#\">" + data.user_name + " <\/a>" + data.body ;
$(comments_id).find(new_comment_class).html(resultStr).slideToggle(150).promise().done(function () {
$(new_comment_class).fadeIn("fast").toggleClass(new_comment_class_removal);
});
$(form_id).slideToggle(150).promise().done(function () {
$(form_id).fadeOut("fast");
});
}
});
e.preventDefault();
});
});
});
so after the javascript gets executed the element loses the class that permits me to find it in the view so that if the user posts again the body of the post doesn't get appended to that element. But now how do I put a new target element as the original one just above the newly creatded one? like this:
<p class="card-text new_comment_{{$i->id}}" style="display:none"></p>
<p class="card-text">This is the body of the comment</p>
solved using http://api.jquery.com/before/ and some temp variables
I have the following code reading an XML file and creating variables from some of the values. This is my jQuery:
$(document).ready(function() {
$.ajax({
type: 'GET',
url: 'https://status.clook.net/xml/status/harvey.xml',
dataType: 'xml',
success: function(xml){
var http = $(xml).find('http').text();
var ftp = $(xml).find('ftp').text();
var mysql = $(xml).find('mysql').text();
var pop = $(xml).find('pop').text();
var imap = $(xml).find('imap').text();
var smtp = $(xml).find('smtp').text();
var load = $(xml).find('load').text();
$('.http').html(http);
$('.ftp').html(ftp);
}
});
$.ajax({
type: 'GET',
url: 'https://status.clook.net/xml/status/email01.xml',
dataType: 'xml',
success: function(xml){
var ehttp = $(xml).find('http').text();
var eftp = $(xml).find('ftp').text();
var emysql = $(xml).find('mysql').text();
var epop = $(xml).find('pop').text();
var eimap = $(xml).find('imap').text();
var esmtp = $(xml).find('smtp').text();
var eload = $(xml).find('load').text();
$('.ehttp').html(ehttp);
$('.eftp').html(eftp);
}
});
});
This is then being used with the following HTML:
<div class="container">
<h3>Server Status Widget</h3>
<h4>Hosting Server</h4>
<p>
<strong>HTTP: </strong>
<span class="http"></span>
</p>
<p>
<strong>FTP: </strong>
<span class="ftp"></span>
</p>
<h4>Email Server</h4>
<p>
<strong>HTTP: </strong>
<span class="ehttp"></span>
</p>
<p>
<strong>FTP: </strong>
<span class="eftp"></span>
</p>
</div>
What I would like to do now is instead of outputting the variable, show an image based on the variable value. I would like to check if the variable value is OK, and if so display an image in the span, and then if the variable is anything other to show another image.
For instance if the variable http has the value OK, in span .http to show allgood.jpg. If the variable value is anything other than OK to show notgood.jpg.
if (ehttp == "ok") {
var imgsrc = '/images/' + ehttp + '.png';
var img = document.createElement("img");
var img.src = imgsrc;
var target = document.querySelector('.ehttp');
target.appendChild(img);
}
From what I understand of your objective, I'd do something like that.
You could write something like this, with a generalised showResult() function to avoid duplication of code.
$(document).ready(function() {
// Fixed data (adapt as necessary)
var OkText = 'OK';
var paths = {
'goodHttp': '/path/to/good/http/image/',
'badHttp': '/path/to/bad/http/image/',
'goodFtp': '/path/to/good/ftp/image/',
'badFtp': '/path/to/bad/ftp/image/'
};
// Generalised utility function
function showResult(containers, xml) {
var httpText = $(xml).find('http').text();
var ftpText = $(xml).find('ftp').text();
if(httpText === OkText) {
containers.http.html('<img src="' + paths.goodHttp + '"/>');
} else {
containers.http.html('<img src="' + paths.badHttp + '"/>');
}
if(ftpText === OkText) {
containers.ftp.html('<img src="' + paths.goodFtp + '"/>');
} else {
containers.ftp.html('<img src="' + paths.badFtp + '"/>');
}
}
// AJAX
$.ajax({
'url': 'https://status.clook.net/xml/status/harvey.xml',
'dataType': 'xml',
}).then(showResult.bind({
'http': $("span.http"),
'ftp': $("span.ftp")
}));
$.ajax({
'url': 'https://status.clook.net/xml/status/email01.xml',
'dataType': 'xml',
}).then(showResult.bind({
'http': $("span.ehttp"),
'ftp': $("span.eftp")
}));
});
Note the use of Function.prototype.bind() to cater for the differences between the two calls.
A better approach might be to hard code the <img> elements then change their src properties.
I want to append data into divs by passing their id as attributes in a script tag. In this example the first-div should get get 'test1' appended to it, and the second-div should get the 'test2' appended to it.
However, the result it that both 'test1' and 'test2' are appended to second-div. first-div is empty. I'm guessing it has to do with how document.currentScript is functioning. Is there any way to get the result I am looking for?
<div id="first-div"></div>
<div id="second-div"></div>
<script attr1="name1" attr2="name2" to-div="first-div" type="text/javascript">
var this_script = document.currentScript;
var attr1 = this_script.getAttribute('attr1');
var attr2 = this_script.getAttribute('attr2');
var append_div = this_script.getAttribute('to-div');
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function(data) {
$('#' + append_div).append("test1");
});
</script>
<script attr1="name3" attr2="name4" to-div="second-div" type="text/javascript">
var this_script = document.currentScript;
var attr1 = this_script.getAttribute('attr1');
var attr2 = this_script.getAttribute('attr2');
var append_div = this_script.getAttribute('to-div');
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function(data) {
$('#' + append_div).append("test2");
});
</script>
Also, in the solution, the scripts cannot have id attributes, which is why I am trying to use document.currentScript.
The reason for this is that the code will be hosted on my servers. The code will append information into the divs the user wants, given parameters passed through attributes on the script tag. In the end the user should be able to use:
<script attr1="var1" attr2="var2" to-div="custom-div" src="http://www.myurl.com/assets/script.js" type="text/javascript"></script>
To insert data into their custom-div based on code I run on my servers dependend on the parameters attr1 and attr2 they provide.
Your problem is that var append_div is a global variable and each time a new script tag is encountered it gets overwritten with the new value.
Since ajax is asynchronous , by the time the responses return the other script tags will have been evaluated so append_div will have the value of the last script tag.
You could fix this by creating a function that wraps the ajax
function doAjax(elementId, attr1) {
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function (data) {
$('#' + elementId).append("test2");
}
});
}
doAjax(append_div, attr1);
An even better solution as pointed out by #Rhumborl is to use an IIFE
(function( elementId, attr1){
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function (data) {
$('#' + elementId).append("test2");
}
});
}(elementId, attr1);
Or wrap all of your code in an IIFE and no arguments would need to be passed in.
(function(){
var this_script = document.currentScript;
var attr1 = this_script.getAttribute('attr1');
var attr2 = this_script.getAttribute('attr2');
var append_div = this_script.getAttribute('to-div');
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function(data) {
$('#' + append_div).append("test2");
}
});
}();
i have a button with the folowing code
<button type="button" class="btn btn-success btn-xs vote up" id="76" name="up"><span class="glyphicon glyphicon-thumbs-up"></span> Bueno</button>
the button does not work unless i reload the page, and i dont know why. any ideas?
jquery code is at the beginning of the body
jquery
<script type="text/javascript">
$(function() {
$(".vote").click(function()
{
var id = $(this).attr("id");
var name = $(this).attr("name");
var dataString = 'id='+ id ;
var parent = $(this);
var _this = this;
if(name=='up')
{
$(this).fadeIn(600).html('<span class="glyphicon glyphicon-ok"></span>');
$.ajax({
type: "POST",
url: "up_vote.php",
data: dataString,
cache: false,
success: function(html)
{
parent.html(html);
$( _this ).remove();
$( ".escondido" ).css( "display", "block" );
} });
return false;
});
});
</script>
If the jQuery code is at the beginning of the code (before the HTML) as you state, the DOM would not have been created yet. Try moving the jQuery code to the bottom of the body (after the HTML).
I would assume you're getting an error in the button click event. Have you tried using the live('click') instead? Can you demonstrate the issue using JSFIDDLE?
In the jsFiddle I created, I'm seeing syntax errors - Original Code
If I change the code to Edited jsFiddle:
$(function () {
$(".vote").click(function () {
var id = $(this).attr("id");
var name = $(this).attr("name");
var dataString = 'id=' + id;
var parent = $(this);
var _this = this;
if (name == 'up') {
$(this).fadeIn(600).html('<span class="glyphicon glyphicon-ok"></span>');
$.ajax({
type: "POST",
url: "up_vote.php",
data: dataString,
cache: false,
success: function (html) {
parent.html(html);
$(_this).remove();
$(".escondido").css("display", "block");
}
});
return false;
}; // Removed ) from this line
});
}); // Added this whole line
First sorry im a big beginner and just experimenting, and I made a similar wall like facebook with oembed.
And would like to add a like, and dislike button too.
I started with the like button, it works, likes, and unlikes too, and the cookie saves the class value perfectly.
My problems is the ajax call, so actually when I click on the like button it overwrites all anchors href val and adds a class to all not on what click.
here is my code
jquery
var cookieLike = "like_"
$('a.like').each(function(){
var id = $(this).attr('href'), cookieLiked = cookieLike + id;
switch($.cookies.get(cookieLiked) ) {
case "unliked":
$(this).removeClass('btn-success');
break;
case "liked":
$(this).addClass('btn-success');
break;
}
}).on('click', function(e){
e.preventDefault()
var likeId = $(this).attr('href');
$.ajax({
url: "<?php echo base_url(); ?>stream/like/" + likeId ,
type: "post",
data: likeId,
dataType: "json",
success: function(like)
{
if(like.likeStatus == "unliked") {
$('a.like').attr('href', likeId).removeClass('btn-success');
$.cookies.set(cookieLike + likeId, 'unliked');
}else if(like.likeStatus == "liked") {
$('a.like').attr('href', likeId).addClass('btn-success');
$.cookies.set(cookieLike + likeId, 'liked');
}
}
});
});
html
<div class="stream-bottom">
Komment
<div class="pull-right like-options">
<i class="icon-thumbs-up" title="tetszik"></i>
<i class="icon-thumbs-down" title="nem tetszik"></i>
</div>
</div>
could please someone point out what i am missing?
Maybe:
.on('click', function (e) {
e.preventDefault();
var button = $(this);
var likeId = button.attr('href');
$.ajax({
url: "<?php echo base_url(); ?>stream/like/" + likeId,
type: "post",
data: likeId,
dataType: "json",
success: function (like) {
if (like.likeStatus == "unliked") {
button.removeClass('btn-success');
$.cookies.set(cookieLike + likeId, 'unliked');
} else if (like.likeStatus == "liked") {
button.addClass('btn-success');
$.cookies.set(cookieLike + likeId, 'liked');
}
}
});
});
Bind the target element (the clicked link) and reference it in the success callback
In the .on('click') callback
var $link = $(this);
In the success callback use
$(this).attr('href', likeId)
instead of
$('a.like').attr('href', likeId)
When you use $("a") or $("a.like") you are referring to the entire set of anchor tags or anchor tags with 'like' as the class name. To specifically use the anchor tag on which you have clicked use $(this) variable.
That will give you the element on which the event got generated and in this case the anchor tag on which you clicked.