jquery animation does not animate - javascript

i have some jquery code that will load the chatbox of my site every second (so if any new posts arrive they become visible)
my code is here
function loadLog(){
$.ajax({
url: "/log.html",
cache: false,
success: function(html){
$("#chatbox").html(html); //Insert chat log into the #chatbox div
if($("#chatbox").attr("scrollHeight") + 20 > $("#chatbox").attr("scrollHeight") - 20){
$("#chatbox").animate({ scrollTop: newscrollHeight }, 'normal'); //Autoscroll to bottom of div
}
},
});
}
everything works fine, except it is meant to autoscroll to the bottom of the chatbox so you see the newest posts, instead it just stays at the top.
I am using the most recent version of jQuery

There is no such attribute scrollHeight (it's property). What if you try something like this instead:
$box.animate({scrollTop: $box[0].scrollHeight}, 'normal');
http://jsfiddle.net/dfsq/zBdas/
Another tip: make sure you cache your DOM queries like $box = $("#chatbox"), don't reselect elements again and again.

Related

How to update html table without disturbing scroll position?

HTML:
<div class="html_table"></div> # In html body tag.
Ajax function to get table data.
var $html_table= $('.html_table');
function ajaxCallFunction() { $.ajax({
type: 'POST',
url: url,
contentType: 'application/json',
success: function(res, status, xhr){
$html_table.html(res['html_table']);
},
error:function(xhr, status, error){
}
});
Updating table for every 5 seconds,
window.onload = function() {
ajaxCallFunction();
setInterval(ajaxCallFunction, 1000*5);
}
Issue:
I have 100 rows in a table. Need to update it every 5 seconds without disturbing the position of scroll. When the user looking to the bottom line, the scroll bar goes to its original position after 5 seconds. How to handle the issue?
How to update the cell value of the table, without affecting the scroll position?
Any other suggestions are welcome.
Note:
In my case, its more important that focus on current row should not get affected.
You can save the current scroll position before changing the html and restore it after you changed the html.
var savedScrollPosition = $(window).scrollTop;
in response callback then restore the position:
$(window).scrollTop(savedScrollPosition);
If the requested HTML is different from the previous one this is of course not working. Maybe you could calculate the real new scroll position relative to the height of the old and new HTML and the saved scroll position in such a case.

Tooltipster not working properly in the beginning

I am using the tooltipster plugin tool where I got gantt chart drawn with some td given id.
So, which ever id is defined and the mouse over it will get ajax data and show accordingly.
Below is snippet of my codes. Issue here is that the tool tip only appear after few times I mouse the td. Thereafter, it works fine.
I can see, in my debug window, that ajax page is called and following error:
Tooltipster: one or more tooltips are already attached to this element: ignoring. Use the "multiple" option to attach more tooltips. jquery.tooltipster.min.js:1
$(document).ready(function () {
$('td[id]').tooltipster({
// content: 'Loading...',
functionBefore: function(origin, continueTooltip) {
// We'll make this function asynchronous and allow the tooltip to go ahead and show the loading notification while fetching our data
continueTooltip();
var idval=0;
// Next, we want to check if our data has already been cached
//if (origin.data('ajax') !== 'cached') {
$.ajax({
type: 'GET',
url: 'getDetails.php',
data:idval,
success: function(data) {
// Update our tooltip content with our returned data and cache it
//alert("Data is : "+data);
var finalData = 'Total Data : 300 <br> Total Completed : 200';
//alert("DATA");
//origin.tooltipster: $('<span>testst<strong>This text is in bold case !</strong></span>')
origin.tooltipster({
content: finalData,
multiple: true,
contentAsHTML: true
});
//origin.tooltipster({content: data,contentAsHTML: true}).data('ajax', 'cached');
}
});
//}
}
});
});
The Tooltipster plugin really should be initialised before all of this. Using the mouseenter enter to trigger it's initialisation every time a user hover's over a <td> element is not great practice and is the root problem to your issue. Ideally you would want to break it down into the following:
Find your <td> elements with id's defined.
Apply tooltipster to these elements.
Let tooltipster handle everything from there.
1. Finding your <td> elements
With the magic of jQuery you can fetch these with a clever use of selectors rather than querying a larger set with your initial implementation, gathered from the answers within the StackOverflow thread here, jquery get only all html elements with ids, we get:
$('td[id]')
This will fetch you all <td> elements with an id defined, be warned this could be a bit slow if you have an extensive table. Alternatively you can select, then apply a filter to narrow down your set:
$('td').filter(function(){
return $(this).attr('id') !== undefined;
});
Both will essentially do the same!
2. Applying tooltipster to these elements
I've not done much here since you had a lot of commented out code, so I've kept it the same, with some minor tweaks, here is my version of the "working code":
$('td[id]').tooltipster({
// content: 'Loading...',
functionBefore: function(origin, continueTooltip) {
// We'll make this function asynchronous and allow the tooltip to go ahead and show the loading notification while fetching our data
continueTooltip();
// Next, we want to check if our data has already been cached
//if (origin.data('ajax') !== 'cached') {
$.ajax({
type: 'GET',
url: 'getDetails.php',
data: $(this).attr('id'),
success: function(data) {
// Update our tooltip content with our returned data and cache it
//alert("Data is : "+data);
var finalData = 'Total Data : 300 <br> Total Completed : 200';
//alert("DATA");
//origin.tooltipster: $('<span>testst<strong>This text is in bold case !</strong></span>')
origin.tooltipster({
content: finalData,
multiple: true,
contentAsHTML: true
});
//origin.tooltipster({content: data,contentAsHTML: true}).data('ajax', 'cached');
}
});
//}
}
});
3. Letting tooltipster handle everything from here
Tooltipster (when intialised) is triggered by default when hovering over an element, this means your functionBefore will be run before this "hover" event, causing your AJAX request to be run each time, there is no need to do anything more thereafter :D
I hope this helps! :)
You can use this code :
var tooltipInstance;
$("body").on('mouseover', 'td[id]:not(.tooltipstered)', function(){
tooltipInstance = $(this).tooltipster({
//your code ...
});
tooltipInstance.tooltipster('open');
});

Scroll to element inside modal window

I have a modal window and need to be able to open the modal and then scroll the user to a specific spot in the modal.
I am getting the modal contents with AJAX to a PHP script.
eg mypage.php?loc=someid
In the PHP script I have this JS to do the scrolling:
$( document ).ready(function() {
$('.modal-body').animate({
scrollTop: $("#<?php echo $_GET['loc'];?>").offset().top
}, 1000);
});
in the PHP page is some HTML like this:
<div id="someid"></div>
My content loads correctly but the amount of scroll that happens appears to be relative to the link that opened the modal so it does not actually find the div in the doc.
I am guessing my JS needs a little tweaking.
It seems I need to be able to calculate the offset of the element from the top of the modal content.
I can fake this by setting the value against the element I am scrolling to like this. But I really need a programmatic way of calculating this. Obviously different devices will not work correctly as shown.
$( document ).ready(function() {
$('.modal-body').animate({
scrollTop: $("#<?php echo $_GET['loc'];?>").attr('distance')
}, 1000);
});
//Trying to find out how far this div is from the top of the modal window?
<div id="someid" distance="670"></div>
User found solution but doesn't appear to have added it, so for the sake of completeness, here it is
$( document ).ready(function() {
setTimeout(function() {
var $el = $("#<?php echo $_GET['loc'];?>")
var elpos = $el.position();
$('.modal-body').animate({
scrollTop: elpos.top
}, 1000);
},500);
});
The solution found by the OP and reposted by Rob Quincey works well, HOWEVER do remember that position give you the position relative to the element's parent element.
If the element is a bare <div> it is not problem, but if the grandparent element has some margin or padding properties, then the position of the parent element will be pushed down the page. Which means that the position of this element will also be pushed down. So to the the scrolling to work properly, you need to add the position of the parent element viz:
$( document ).ready(function() {
setTimeout(function() {
var $el = $("#<?php echo $_GET['loc'];?>")
var elpos = $el.position();
var elparentpos = $el.parent().position();
$('.modal-body').animate({
scrollTop: elpos.top + elparentpos.top;
}, 1000);
},500);
});
And then, if necessary, work your way up the DOM tree until you get to the top element which would normally be your modal div. But you only need to address elements which have some top end margin or padding.

How can I write a function that relies on dynamic selectors?

I am writing a function to dynamically load jQuery UI accordian leaves with content. I know (think) the AJAX part works as I lifted it from another working AJAX loader I have, but the function as a whole does not work.
The code:
function load_leaf(link){
var link = link;
$.ajax({
cache : false,
type : 'POST',
async: false,
url : 'includes/'+ link +'.php?'+ new Date().getTime(),
dataType : 'text',
data: {
owner : '$user_id'
},
success: function(msg){
$("#" + link).html(msg);
console.log('Can\'t see me in Chrome, but ok in firefox !')
},
error: function() {
console.log($.makeArray(arguments));
},
complete: function() {
console.log($.makeArray(arguments));
}
});
};
$(function(){
$('.accordian').click(function(){
var link = this.getAttribute("link");
load_leaf(link);
});
});
For whatever reason this does not work. The break point seems to be this line
$("#" + link).html(msg);
Specifically the selector, as a hard coded selector works perfectly. The link variable is correctly filled i know this as i can alert the value correctly. The link is not the problem as i replaced the whole ajax function with a simple add class and it a still did not work, it also broke at the selector.
EDIT:
This is the div as printed by php:
<h3 class="accordian" id="'.$tab_id.'" link="'.$tab_link.'" >
'.$tab_name.'
</h3>
<div id="'.$tab_link.'"><p>Hi</p></div>
The html for the first one is:
<h3 class="accordian" id="accordian_manage.php" link="accordian_manage.php" >Manage Images</h3><div id="accordian_manage.php"><p>Hi</p></div>
Your ID has a period . in it, which jQuery interprets as a chained class selector.
You can either change your link/IDs, or use this hack:
$("[id='" + link + "']");
Live demo
I guess your problem is with Jquery is not finding the div to load the msg..Post the accordion div so that i could give you the proper selector

loading content into a div with jquery

Hey All - I am having a bit of trouble with a jquery function. I have a nav bar and I want when a user clicks on the nav bar to have the page load into a div (#content)
The code I have works for the first click, but when I try to click on another item it shows the loading image, but does not put the new content in the div (it leaves the old content). Any thoughts?
$(document).ready(function() {
$('.cat').live("click",function() {
var section = $(this).attr("id");
$.ajax({
type: "POST",
url: "../soccer/nav/" + section + ".php",
beforeSend: function() {
$('div#content').hide();
$('div#loading').show();
},
success: function(html){
$('div#loading').hide();
$("div#content").replacewith(html);
}
});
return false;
});
});
Any help would be greatly appreciated!
The problem is the .replacewith() method. You are actually replacing the #content div with the new content. Just use .html() instead.
You don't need $("div#content"). You can just do $("#content")
$("#content") means find the node with the id "content".
Try with:
$.post("../soccer/nav/" + section + ".php", null, function(data)
{
$('#loading').hide();
$("#content").html(data);
});
Try to use jQuery.Load event to make use of ajax and html populating at the same time.

Categories