Why my find('a') doesn't work in jquery? - javascript

I have a function in jquery:
function handleUpcomingUserTexts () {
$.ajax({
url: 'getjson.php',
type: "POST",
data: {
mail: '<?php echo htmlentities($_SESSION["email"]); ?>'
},
dataType:'text',
success: function(ans)
{
var data = JSON.parse(ans);
$.each(data, function(i, v) {
var upcomingText = $('<i class="fa fa-comment fa-fw"></i> '+v.Content+'<span class="pull-right text-muted small"><em>'+v.Date+'</em></span>');
$('#upcomingTexts').append(upcomingText);
var a = upcomingText.find('a').on('click',function(e){
e.preventDefault();
alert("here");
});
});
}});
};
and it fills the html nicely, but when I click the link - nothing happens and I don't see the alert message. What is wrong in here?

Because upcomingText is already a a. And you are trying to find a a in your a.
You can just write this :
var a = upcomingText.on('click',function(e){
When you write var variable = $('<a ...>...</a>');, the result is the root tag of the given html. So in your case, the <a>.

Because upcomingText is <a> and in this tag there are not any <a> tags, so you need use upcomingText like this
upcomingText.on('click',function(e) {});
but event delegation in this case better solution
// add this code before $.ajax
$('#upcomingTexts').on('click', 'a.list-group-item', function(e) {});

Try to use delegate function, on #upcomingTexts block
$('#upcomingTexts').delegate('a', 'click', function(e){
//your code here
});

Related

document execCommand copy not working with AJAX

I can't copy the generated link directly (without ctrl+C)
I am usign document.execCommand('copy') but it seems it has no effect.
If code has no AJAX then its working pefectly.
Here's the
fiddle link with AJAX
fiddle link without AJAX
HTML:
<div class="permalink-control"> </div>
JQUERY:
$(".permalink-control")
.append(
'<div class="input-group">' +
' <span class="input-group-btn"><button type="button" class="btn btn-default" title="Get Permalink"><span class="glyphicon glyphicon-link"></span></button></span>' +
' <input type="text" class="form-control">' +
'</div>'
);
$(".permalink-control input")
.hide()
.focus(function () {
// Workaround for broken selection: https://stackoverflow.com/questions/5797539
var $this = $(this);
$this.select()
.mouseup(function () {
$this.unbind("mouseup");
return false;
});
});
$(".permalink-control button")
.click(function () {
var $this = $(this);
$.ajax({
url: "https://api-ssl.bitly.com/shorten",
dataType: "jsonp",
data: {
longUrl: window.location.href,
access_token: "your access token",
format: "json"
},
success: function (response) {
var longUrl = Object.keys(response.results)[0];
var shortUrl = response.results[longUrl].shortUrl;
if (shortUrl.indexOf(":") === 4) {
shortUrl = "https" + shortUrl.substring(4);
}
$this.parents(".permalink-control")
.find("input")
.show()
.val(shortUrl)
.focus();
},
async:false
});
});
UPDATE:
How do I copy to the clipboard in JavaScript?
is not answer to my question as My code also copies without using ctrl+C if AJAX is not there.
However when I am using AJAX document.execCommand('copy') is not working.
The reason for this is clearly stated in W3 specs:
Copy and cut commands triggered through a scripting API will only affect the contents of the real clipboard if the event is dispatched from an event that is trusted and triggered by the user, or if the implementation is configured to allow this.
But, having said that we can try to fool around the browser by copying text when a user does some interaction.
In this case since you are looking for a click event I assume you're user is interacting with mouse
So, what if I attach a $(window).blur() or $(document).click() event after the ajax call is resolved?
That's right, Since, the user has to blur at some point to use the copy selection, user will initiate a blur() or click() (depending on your need) and we can copy text to our clipboard.
Here's the HACKY DEMO
$(document).ready(function(){
var shortUrl;
$(".permalink-control")
.append(
'<div class="input-group">' +
' <span class="input-group-btn"><button type="button" class="btn btn-default" title="Get Permalink"><span class="glyphicon glyphicon-link"></span></button></span>' +
' <input type="text" class="form-control">' +
'</div>'
);
$(".permalink-control input")
.hide()
.focus(function () {
// Workaround for broken selection: http://stackoverflow.com/questions/5797539
var $this = $(this);
$this.select();
document.execCommand('copy');
$this.mouseup(function () {
$this.unbind("mouseup");
return false;
});
});
$(".permalink-control button")
.click(function () {
var shortUrl ="";
var $this = $(this);
$.ajax({
url: "https://api-ssl.bitly.com/shorten",
dataType: "jsonp",
data: {
longUrl: window.location.href,
access_token: "48ecf90304d70f30729abe82dfea1dd8a11c4584",
format: "json"
},
success: function (response) {
var longUrl = Object.keys(response.results)[0];
shortUrl = response.results[longUrl].shortUrl;
if (shortUrl.indexOf(":") === 4) {
shortUrl = "https" + shortUrl.substring(4);
}
$this.parents(".permalink-control")
.find("input")
.show()
.val(shortUrl)
.focus();
}
}).done(function(){
$(window).blur(function(){
document.execCommand('copy');
$(window).off('blur');// make sure we don't copy anything else from the document when window is foucussed out
});
})
});
})
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="permalink-control"></div>
<div class"log"></div>
P.S: This has been tested in chrome.
I had the same problem. I solved it rather primitively: inside the handler of a click event, you can run an interval that will check the variable where ajax will insert the value after the server responds. After the answer is received, we stop the interval and start the work with the clipboard. No problem, because the user himself starts the interval after the click, without any callbacks.
Simple jQuery example:
var ajaxResponse;
function copyText(copiedText){
$('<textarea class="copied-text">' + copiedText + '</textarea>').appendTo('body');
if ( navigator.userAgent.match(/ipad|iphone/i) ) {
var range = document.createRange(),
textArea = $('.copied-text')[0];
range.selectNodeContents(textArea);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
textArea.setSelectionRange(0, 999999);
} else {
$('.copied-text').select();
}
document.execCommand('copy');
$('.copied-text').remove();
};
function myAjaxFunc(){
$.ajax({
type: 'POST',
url: yourUrl,
data: yourData,
success: function(data){
ajaxResponse = data;
}
});
};
$('.your-button').on('click', function(){
myAjaxFunc();
var ajaxCheckTimer = setInterval(function(){
if ( ajaxResponse ) {
copyText(ajaxResponse);
clearInterval(ajaxCheckTimer);
};
}, 100);
});
In this example, when clicking on a button, we send some data to the server and start the interval with checking the value of the ajaxResponse variable.
After the response from the server is received, the response of the server is written to this variable, after which the condition in the interval becomes true and the text copy function is called, and the server response variable is specified as the parameter: copyText(ajaxResponse);. The interval stops.
The copyText function creates an textarea on the page with the value of the ajaxResponse variable, copies this value from the field to the clipboard, and deletes the field from the page.
UPDATE 01.07.19
For correct copying to the clipboard on iOS, add the attribute contenteditable with the valuetrue to the text field:
$('<textarea class="copied-text" contenteditable="true">' + copiedText + '</textarea>').appendTo('body');

jQuery.ajax, I always have to request twice

I am binding the click function foo to the anchor tag in jquery.ajax. The problem I am facing is that I have to request twice or click the anchor tag twice to make the request. Also I have noticed in the browser under the network bar that ajax request is not triggered, first time when I hit the anchor tag. But when I hit it twice then I see two ajax request in the network tab. I have no idea what is going on?
<script type="text/javascript">
function show(thelink)
{
var cat = thelink.innerHTML;
var productContainer = document.getElementById("productContainer");
$.ajax({
type:"POST",
url:"fetchdata1",
data:"cat="+cat,
success:function(data){
productContainer.innerHTML ="";
var $productContainer = $('#productContainer');
$.each(data,function(key,value){
if(value['newVar'] === 1)
{
$productContainer.append("<div id='productBox' class='grid_3'>\n\
<a href='product.jsp?id="+value['id']+"'><img src='"+value["image"]+"'/></a><br/>\n\
<a href='product.jsp?id="+value['id']+"'><span class='black'>"+value['name']+"</span></a><br/>\n\
<span class='black'>By "+value['company']+"</span><br/><span class='red'>RS."+value['price']+"</span>\n\
<br/><br/><a href='#' class='remove' onclick='foo(this)' pid='"+value['id']+"'>REMOVE</a></div>");
}
else{
$productContainer.append("<div id='productBox' class='grid_3'>\n\
<a href='product.jsp?id="+value['id']+"'><img src='"+value["image"]+"'/></a><br/>\n\
<a href='product.jsp?id="+value['id']+"'><span class='black'>"+value['name']+"</span></a><br/>\n\
<span class='black'>By "+value['company']+"</span><br/><span class='red'>RS."+value['price']+"</span></div>");
}
}) ;
}
});
return false;
}
function foo(obj){
var pid = $(obj).attr("pid");
$(obj).bind("click", function(){
$.ajax({
type:"POST",
url:"removeFromWishlist",
data:"pid="+pid,
success:function(response){
console.log("sent ajax request");
}
});
});
}
You were binding an extra onclick handler to .remove.
When working with callbacks on dynamically added elements, its better to bind all required events on document context using $(document).on("click", 'selector', function(){ ... });.
So instead of a href='#' class='remove' onclick='foo(this)' pid='"+ do this (see below snippet)
$(document).on("click", '#productBox .remove', function(){
// your ajax call
$.ajax({
type:"POST",
url:"removeFromWishlist",
data:"pid="+pid,
success:function(response){
console.log("sent ajax request");
}
});
});
This will separate your HTML layout and its behaviour.
Below things must be avoided (Thanks to #charlietfl):
Binding 'click' listeners twice on same element.
Using javascript inline with your html code.
Directly binding a javascript function using onclick attribute.
Not using javascript unobtrusively.
Hope it helps.

Ajax: setInterval function doesn't update html (but it works)

I have several divs in code. I need to update the html inside, based on API request.
It works, but html doesn't refresh (i.e. if I get via API a new result, html remain same of first iterate, but in firebug I can read new HTML ready to inject in page).
$('div.show-gpio-state').each(function(i, obj) {
var id_gpio = $(this).data('id-gpio');
getGpioState(id_gpio,$(this));
setInterval(function(){getGpioState(id_gpio,$(this))}, 5000);
});
function getGpioState(id_gpio,box) {
$.ajax(
{ url: api_gpio_url+id_gpio,
cache:false,
success: function (result) {
box.html('');
var state = result;
var final_state = '';
if ( (state==='error') || (state==='') ) {
final_state = '<span class="text-danger"><i class="fa fa-fw fa-2x fa-exclamation-triangle"></i></span>';
} else {
if (state==1) {
final_state = '<p class="h2"><i class="fa fa-fire text-success"></i></p>';
} else {
final_state = '<p class="h2"><i class="fa fa-remove text-grey"></i></p>';
}
}
box.html('');
box.html(final_state);
// here in console I have right final state for right box
console.log(final_state);
console.log(box);
}
});
}
Change this
setInterval(function(){getGpioState(id_gpio,$(this))}, 5000);
to
setInterval(function(){getGpioState(id_gpio,$(this))}.bind(this), 5000);
or assign $(this) to variable and pass inside setInterval function
You could fix it like:
setInterval((function(_this){
return function(){
getGpioState(id_gpio,$(_this));
};
}(this)), 5000);
The issue is related to how scope and this keyword works in JavaScript.
Or you could even simply use a variable:
$('div.show-gpio-state').each(function(i, obj) {
var id_gpio = $(this).data('id-gpio');
var $this = $(this);
getGpioState(id_gpio,$this);
setInterval(function(){getGpioState(id_gpio,$this)}, 5000);
});
To learn more about the issue you could read this post: Understand JavaScript’s “this” With Clarity, and Master It

Ajax request with on method of jquery

I have a doubt, I use Jquery to load dynamic wall posts of people who follow me. Now since Jquery dosent work on dynamic content in the tradition click method I use on method for the response.If i dont trigger a Jquery method but do other things it works. I want to know how to launch Ajax method.
My Code:
$('body').on('click','.likebutton', $.ajax({
method:"POST",
url:"../assets/backend/likepost/index.php",
data:"postid="+$('.likebutton').attr('id'),
success:function(response) {
$(this).find(".liketext").html("<p class='liketext'><span class='glyphicon glyphicon-ok'></span> You like this</p>");
}
Any improvment to the code would be greatly appreciated. Thnx
Use following format:
$('body').on('click','.likebutton', function(){
var that = this;
/*
place code of other processing
*/
$.ajax({
method:"POST",
url:"../assets/backend/likepost/index.php",
data:"postid="+$(that).attr('id'),
success:function(response) {
$(that).find(".liketext").html("<p class='liketext'><span class='glyphicon glyphicon-ok'></span> You like this</p>");
}
});
}
You need to wrap ajax function call in an anonymous functions.
Use
$('body').on('click', '.likebutton', function() {
//Store the reference in a variable
var _this = $(this);
$.ajax({
method: "POST",
url: "../assets/backend/likepost/index.php",
data: "postid=" + this.id, //fetch id using this
success: function(response) {
//Use the refrence to set html
_this.find(".liketext").html("<p class='liketext'><span class='glyphicon glyphicon-ok'></span> You like this</p>");
}
});
});

On ajax success, change another link value

I have a simple jquery voting system where users click a heart icon and a value is updated with the amount of likes the post currently has. That works fine, but I want to display the updated value in another link instead. Example:
The function:
$(function() {
$(".fav").click(function() {
var id = $(this).attr("id");
var dataString = 'id='+ id ;
var parent = $(this);
$(this).fadeOut(300);
$.ajax({
type: "POST",
url: "/ajax/post_like.php",
data: dataString,
cache: false,
success: function(html) {
parent.html(html);
parent.fadeIn(300);
}
});
return false;
});
});
How the HTML looks like:
<i class="fa fa-heart"></i>
<i class="fa fa-retweet"></i>
{$p->notes}
How can I achieve this? I'm still in the process of learning javascript. Any help appreciated!
If all you're looking to do is increment it by 1 you can add this to your success:
var val = parseInt($(".notes").text());
$(".notes").text(val+1);
Otherwise, if the return from your AJAX, "html", is the number you want to use just replace
parent.html(html);
with
$(".notes").text(html);
Update:
Based on your comment, try this:
parent.parent().find(".notes").text(html);
This will get the closest notes (presumably the one you want to update) and change it's text.

Categories