Loading popover content with ajax not working properly - javascript

I am using an ajax call to display a show method content for different products in popovers in my page.
I use the following code:
function details_in_popup(link, div_id){
$.ajax({
url: link,
success: function(response){
$('#'+div_id).html(response);
}
});
return '<div id="'+ div_id +'">Loading...</div>';
}
$(function () {
$('[data-toggle="popover"]').popover({
"html": true,
"title": '<span class="text-info"><strong>title</strong></span>'+
'<button type="button" id="close" class="close" >× </button>',
"content": function(){
var div_id = "tmp-id-" + $.now();
return details_in_popup($(this).data('url'), div_id);
}
}).on('shown.bs.popover', function(e){
var popover = jQuery(this);
$('body').on('click','.close', function(e){
popover.popover('hide');
});
});
});
The problem that i am encountering is that the first time i open a popover, the content get filled properly, the second time, i get title duplicates in the popover, then the third time, content from the first popover and the second one get all mixed up.
It's like if the previous popovers are never cleaned-up and get accumulated each time i open a new popover...
Is there something obvious in the code that might be creating this problem ?
Thanks!

reset the div on ajax success with
$('#'+div_id).text('');
than append the response.

Related

AJAX post and page refresh

I'have and AJAX post request:
$(document).ready(function() {
$("span").click(function(e) {
e.preventDefault();
e.stopPropagation();
var URL = "someURL";
$.post(URL, this.id, function(data, status) {
var val = parseInt(document.getElementById(this.data).innerHTML)
document.getElementById(id).innerHTML = val + 1 ;
document.getElementById(id).disabled=true;
});
});
});
Read
<span id="${book.id}">
This script is working as expected; a button with number in it increase by one.
The problems are:
A refresh of the page occurs. On button click it reloads all on the page.
I'm not able to disable the button after the change
In short I need a count button which increase by 1 and can be changed once per user.
Update It seems that reload it's related to another function defined as
$(document).ready(function() {
So i have one in the body and one in the head.
Of course it refreshes the page, you're sending it a link to go to via href. Instead, remove the href, and put an onclick event and handler. Replace your anchor tag, with this:
<a onclick="runFunction()">Read</a>
And replace your script, with this.
<script>
function runFunction(){
$(document).ready(function(){
$("span").click(function(e){
e.preventDefault();
e.stopPropagation();
var URL="someURL";
$.post(URL,
this.id,
function(data,status){
var val = parseInt(document.getElementById(this.data).innerHTML)
document.getElementById(id).innerHTML = val + 1 ;
document.getElementById(id).disabled=true;
});
});
});
}
</script>

Check for change in inner html by html Tag

I currently load a html page into a <DIV> in my page. using this code
$.ajax({
url: 'myApi.php?user=' + user + '&url='+ URL2add,
success: function(html) {
var newHTML = "<object id='webloader' data='" + html + "'></object>";
$("#exweb").fadeOut(500, function () {
$("#exweb").html(newHTML).fadeIn(5000, function() {
alert("done");
});
});
}
});
So i want to do a check or preferably get a alert once that page loaded changes. which is in the data tag that comes from the html coining back from the ajax call.
I have tried document.getElementsByTagName
I know there has to be a way to get the new data info in that object .
i would prefer an alert each time the page changes from what comes back from the ajax call
i have updated the code like this...
$(document).on('contentchanged', '#exweb', function() {
alert('WOO?');
});
$.ajax({
url: 'Api.php?user=' + user + '&url='+ URL2add,
success: function(html) {
var newHTML = "<object id='webloader' data='" + html + "'></object>";
$("#exweb").fadeOut(50, function () {
$("#exweb").html(newHTML).fadeIn(50, function() {
$('#exweb').trigger('contentchanged');
});
});
}
});
But this is only working on initial change
i need to know when that page changes again.. say if someone clicks on a link that will change the page in DIV or if its a redirect page.
i want to know whenever that page changes to something after i loaded it from my ajax call
should it not be as easy as getting the information between data=""
<object id="webloader" data="http://google.com"></object>
and how do i get back that info? i have tried document.getElementsByTagName
you can do something like this after ajax.
$.ajax({...}).done(function() {
alert('page loaded');
});
$.ajax({/* your AJAX */}).done(function() {
alert(/*your text*/"page loaded!");
});
I think you could try this $("div").load("your_url.php?parameters"); the page you want to load could have the following <body onload="alert('Page Loaded')">
Update:- if you dont have the access of the webpage then use this $("div").load("your_url.php?parameters",function(){alert("Page loaded")});

Two separate $.ajax call "kill" each other on click function

So here is the problem:
I have two click event in one page. The first when you click on a thumbnail picture it's open a modal which shows a bigger image like Instagram on PC (I make an Instagram clone for practicing btw). The other button is for show more image.
The problem is, I use ajax for both click to get some variable and pass to the php. When the page loaded it's shows only 3 image and when I clicked one of them It's shows the right image in the modal but when I click show more it shows 3 more and after when I clicked on the thumbnail it's stucked. I mean its shows only one picture doesn't matter which thumbnail i clicked so the ajax request not runs again. I hope you can understand the problem and can help me. (sorry for my English).
So here is the code:
This is the ajax calling function:
function ajaxShow(urls,datas,element){
$.ajax({
url: urls,
data: {datas: datas},
cache:true,
}).always(function(result){
console.log("done");
element.html(result);
});
}
And these are the click events:
$(document).ready(function(){
//Open picture in modal
var pic = $(".pics");
var modalCont = $(".modal-content");
pic.on('click',function(event){
event.preventDefault();
var id = $(this).attr('data-id');
console.log(id);
ajaxShow("../php/ajax_modal.php",id,modalCont);
});
//Load more
var smbt = $(".smbt");
var limit = $(smbt).data('loaded');
smbt.on('click',function(event) {
event.preventDefault();
var cont = $("#cont");
limit += 3;
console.log(limit);
ajaxShow("../php/show_more.php",limit,cont);
});
});
In a nutshell: After I clicked on load more the modal open ajax request not run again.
Use overloaded version of .on() on document node.
$(document).on(events, selector, data, handler );
So your code should be rewritten as this:
$(document).on('click', '.pics', null, function (event) {
event.preventDefault();
var id = $(this).attr('data-id');
console.log(id);
ajaxShow("../php/ajax_modal.php",id,modalCont);
});
and
$(document).on('click', '.smbt', null, function (event) {
event.preventDefault();
var cont = $("#cont");
limit += 3;
console.log(limit);
ajaxShow("../php/show_more.php",limit,cont);
});

Ajax request succeeds but continues on to the target url regardless

I'm working on a page which contains various Youtube video thumbnails in divs which have links attached to each <img> and has Masonry on the container to control class switching to resize selected videos.
The idea is that the div is clicked on, which triggers masonry to change the CSS and also triggers an .ajax() request to django which returns the template for the selected video. (And will perform the opposite when you select it again to return the thumbnail template and reset to normal with Masonry).
As it stands I have two javascript functions, one triggering masonry on the div, and then another triggering the ajax request on the video link;
<script>
(function($) {
$(document).ready(function() {
var container = $('.masonry'), masonry;
//masonry = new Masonry(container[0]);
container.masonry('stamp', container.find('.stamp'));
container.unbind('click').on('click', '.item', function() {
var $this = $(this),
this_link = $this.find('a'),
$this_link = $(this_link),
this_href = $this_link.attr('href'),
video_id = $this.attr('data-video-id'),
gigante = $this.hasClass('gigante'),
selector = 'div#panel-area.video_grid div.masonry div.item.' + video_id;
$.ajax({
type: "GET",
async: false,
url: this_href,
timeout: 5000,
data: {'g': gigante},
dataType: 'html',
success : function(data) {
$(selector).html(data);
container.find('.item').removeClass('gigante');
$(this).toggleClass('gigante', !gigante);
container.masonry();
console.log('Selector: ' + selector + '\nSuccess');
}
})
.done(function(msg){
console.log('Done: ' + msg);
})
.fail(function(jqXHR, textStatus){
console.log('Failed: ' + textStatus);
});
});
});
})(jQuery); </script>
And the HTML;
<div class="masonry js-masonry" data-masonry-options='{ "stamp": ".stamp", "isOriginLeft": false }'>
<div class="mpus stamp">
</div>
<div class="item video {{ object.id }}" data-video-id="{{ object.id }}">
<a class="GetYoutubeVideo" href="{% url 'show_video' video_id=object.id %}">
<i class="icon-play-circled play"></i>
<span class="title">
{{ object.get_title|slice:":20" }}...<br/>
{{ object.date_created|date:"d/m/Y" }}
</span>
{{ object.get_img_tag }}
</a>
</div>
</div>
I'm a javascript novice essentially so I'm sure this is a very basic issue. When I run this through chrome dev tools with async disabled I see the ajax request return the expected content, but then ultimately end up on the target page instead of loading the content in to $(selector) as expected.
When I enable async it just instantly fails. I've been reading docs for ages but don't feel like I'm getting anywhere. Any help would be appreciated.
To avoid the default click action, modify your click handler as follows:
.on('click', '.item', function(e) {
var ...
e.preventDefault();
$.ajax({
...
)}
...
})
Adding e to the click handler function means that the event details are available within the function - on the e object you run the preventDefault() method which prevents default actions from occuring - for instance, a hyperlink will no longer navigate to its target.
The event occurs in generally the following manner, though this is don't an in-depth summation:
A click event occurs on the a element.
The click event starts a search for an event handler. Should one not be found on the element that caused then the event will 'bubble' up the DOM tree, one level at a time until it either reaches the root DOM element and cannot go further, or a click handler is found.
At any point, should a click handler be found then the code in the click handler is executed. If the click handler sets preventDefault() on the event object, or returns false then no further action is taken.
If the click handler neither returns false nor sets preventDefault() then the original browser default action will be executed in addition to your own event handler.
Your code in full with modifications:
<script>
(function($) {
$(document).ready(function() {
var container = $('.masonry'), masonry;
//masonry = new Masonry(container[0]);
container.masonry('stamp', container.find('.stamp'));
container.unbind('click').on('click', '.item', function(e) {
var $this = $(this),
this_link = $this.find('a'),
$this_link = $(this_link),
this_href = $this_link.attr('href'),
video_id = $this.attr('data-video-id'),
gigante = $this.hasClass('gigante'),
selector = 'div#panel-area.video_grid div.masonry div.item.' + video_id;
e.preventDefault();
$.ajax({
type: "GET",
async: false,
url: this_href,
timeout: 5000,
data: {'g': gigante},
dataType: 'html',
success : function(data) {
$(selector).html(data);
container.find('.item').removeClass('gigante');
$(this).toggleClass('gigante', !gigante);
container.masonry();
console.log('Selector: ' + selector + '\nSuccess');
}
})
.done(function(msg){
console.log('Done: ' + msg);
})
.fail(function(jqXHR, textStatus){
console.log('Failed: ' + textStatus);
});
});
});
})(jQuery);
</script>
Is there a point to setting a functioning href attribute on your <a> element if you don't want it to actually go to that URL directly?
Not trying to be clever, just asking if there is a specific reason for it.
Because the problem is that your <a> element is still performing its 'normal' duties, i.e. changing the page. I can see you retrieve that URL via jQuery at a later stage, but that shouldn't matter.
Change your used attribute to something that is NOT href:
<a class="GetYoutubeVideo" href="#" data-custom-url="{% url 'show_video' video_id=object.id %}">
And when you need to retrieve the value, just use that new attribute name:
this_href = $this_link.attr('data-custom-url')
Note that I'm not 100% sure if you need the href attribute for masonry. From what I can see from your code examples, it doesn't matter, as long as you're able to retrieve the value from an attribute (not specifically href).
By NOT using the href attribute, you're making sure your <a> element doesn't have an actual URL to refer to when it gets clicked.
Is this an acceptable solution/workaround?
You could simply return false in your click event callback:
container.unbind('click').on('click', '.item', function() {
...
#ajax
...
return false;
});
I believe it's a more practical way of stopping the default action and preventing the event from bubbling up.

Change a href=# to javascript:

Hi I asked before on how to load a div's content (A url) by clicking a button and not on page load before and I got this code as an answer:
<script type="text/javascript">
function toggleDiv(id){
if ($('#' + id).html() == '') {
$.ajax({
url: 'api.microsofttranslator.com/V2/Ajax.svc/Translate?appId=SOMETHING&from=en&to=de&text=Hello', // your url to microsoft translator
success: function(data) {
$('#' + id).html(data);
},
error: function() {
$('#' + id).html('The resource could not be loaded');
}
});
}
$('#' + id).toggle(); // Toggle div visibility
}
</script>
Show/Hide Value
<div id="a" style="display:none"></div>
First of all it doesn't work correctly and always show "The resource could not be loaded" if you put a txt link like (http://knowpersia.com/a.txt) it doesn't work either.
Secondly the Show/Hide Value link uses a href=# and onclick system to work. When I use it on my website it gets back to the homepage when I click it. Is there a way to change it to something like:
Show/Hide Value
Thanks
You have to pass an id to the toggleDiv() function, and you're passing a collection of objects -> toggleDiv('a') // Nop.
Also, if you're using jQuery, I suggest you get rid of that ugly inline code. Then, you can pass jQuery objects into your function:
Show/Hide Value
<div id="content"></div>
.
var toggleDiv = function($el) {
if ($el.empty()) { // You can just use `empty()`
$.ajax({
url : 'api.microsofttranslator.com/V2/Ajax.svc/Translate?appId=SOMETHING&from=en&to=de&text=Hello', // your url to microsoft translator
success : function (data) {
$el.html(data);
},
error : function () {
$el.html('The resource could not be loaded');
}
});
}
$el.toggle(); // Toggle div visibility
};
$('#link').click(function(){ toggleDiv($('#content')); });

Categories

Resources