JQuery chat application scroll to bottom of div ONLY on new message? - javascript

I have picked up this AJAX code from multiple tutorials, but the problem is, when the ajax is called, the div ALWAYS scrolls to the bottom. But I want it so that the div ONLY scrolls if there are new messages in the div.
$.ajax({
url: "msg-handle/get-messages.php",
cache: false,
data: { room: $("#room").val() },
success: function(data) { $('#chat').html(data)
$("#chat").scrollTop($("#chat")[0].scrollHeight);
},
});
}, 500);
Is there a way to achieve this without any major ramifications to my code?

I didn't try it, but I think it has to be something like this... (among other solutions)
var oldscrollHeight = $("#chat")[0].scrollHeight;
//Takes the height BEFORE reload the div
$.ajax({
url: "msg-handle/get-messages.php",
cache: false,
data: { room: $("#room").val() },
success: function(data) { $('#chat').html(data)
var newscrollHeight = $("#chat")[0].scrollHeight;
//Takes the height AFTER reload the div
if(newscrollHeight > oldscrollHeight){ //COMPARES
$("#chat").scrollTop($("#chat")[0].scrollHeight); //Scrolls
}
},
});
I think You have to put a $("#chat").scrollTop($("#chat")[0].scrollHeight); after the first load of the chat.. just an advise.

the easiest way would be to let the php script pass a flag when there are new messages in the div. you then just have to put in a check condition for the the scrolling.
another option would be to compare the number of divs in the new .get() result to the previous one and scroll only if there are more divs present in the current.

Related

How to show and hide an image properly in javascript?

I've been having issues trying to show and hide images inside of my ajax request function. In order to be clear of what I'm trying to do, I make a video less than 1 minute click here. If you see in the web console, there's a variable that is changing from "ocupado" to "libre" and that means if there's a free or busy parking space. So It kind of work because in the beginning my variable "data" = ocupado shows a car image, then when it changes to "data" = libre hide the car image. The problem starts when it changes again to "data" = ocupadobecause It doesn't show any car image.
Here's my code for ajax function
<script src="js/jQuery.js"></script>
<script type="text/javascript">
setInterval(function(){
$("img").error(function () {
$(this).unbind("error").attr("src", "");
});
$(function ()
{
$.ajax({
url: 'api.php',
data: "",
success: function(data)
{
console.log(data);
if (data === "libre"){
$("#slave1free").hide();
$("#slave1busy").hide();
}else{
$("slave1free").show();
$("slave1busy").show();
}
}
});
})
}, 1000);
<div class="chart">
<div class="chartimage"><img src="images/parkinglot.jpg"></div>
<div class="image" id = "esclavo1">
<div class "free" id = "slave1free"><img src="images/carfree.png"></div>qQ
<div class "busy" id = "slave1busy"><img src="images/carbusy.png"></div>
</div>
By the way, carfree.png and carbusy.png are those images that are shown in the video next to "estacionamiento libre" and "estacionamiento ocupado". I put one image in top of the other because I was planning to show and hide both images according to value of data ("libre" or "ocupado").
Edit: Yes, I'm hidding both and showing both on purpose because I wanted to see where's the problem. Despite that both are showing or hidding at the same time, It would appear both images(one in top of the other) when "data"=ocupado ?
note that you are hiding the two items, or showing them at the same time... shouldn't be one of each?
if (data === "libre") {
$("#slave1free").show();
$("#slave1busy").hide();
} else{
$("slave1free").hide();
$("slave1busy").show();
}
-edit-
Just realized that you are missing the id selector ( # ) on the else
if (data === "libre") {
$("#slave1free").show();
$("#slave1busy").hide();
} else{
$("#slave1free").hide();
$("#slave1busy").show();
}

jQuery - How to select all elements with same Class but not with particular ID

Here is my code:
$( "#targetButton" ).click(function() {
$.ajax({
url: './checkcolors.php',
type: 'post',
data: {
url: 'http://www.sportsdirect.com/dunlop-mens-canvas-low-top-trainers-246046?colcode=24604622',
SizeId: '6.5'
},
dataType: 'text',
success: function (data) {
var arr = data.split(',');
arr.forEach(function(id){
$('#' + id.trim()).show();
});
}
});
});
This is a ajax post function which is returning an number if ids.
The returned ids are answering to div html elements which i have to show.
These html div elements have same class but all of them are with different ids.
So i tried this code to select all elements with same class but excluding the elements with the pointed ids:
$('.ColorImagesNOColor:not(#' + id.trim() + ')').show();
It seems it is not working because it shows all elements with this class even with the ids which must NOT be shown.
Can you please help me out ?
Thanks in advance!
You're doing it inside a .forEach loop. That means that the last $('.ColorImagesNOColor:not(#' + id.trim() + ')').show(); will determine the final visibility of the .ColorImagesNOColor elements.
If you want to show all .ColorImagesNOColor elements and hide the ones with the id's returned, then you can move the first step to before the .forEach loop:
// Show all initially
$('.ColorImagesNOColor').show();
// Hide ones with certain Id's
arr.forEach(function(id){
$('#' + id.trim()).hide();
});

How to stop scrolling to top after an ajax call

I update a certain content of htm element with setInterval function to call an ajax every few sec
<div class="content">
<p>New informaton here</p>
<br>
<p>.......</p>
more information below
</div>
below is the javascript
var main = function(){
updatingMessage = setInterval(function(){
$.ajax({
type: "POST",
url:" call_MYSQLDatabase_To_Update_Content.php",
cache:0,
data:({
some vars
}),
success:function(result){
$(".content").html(result);
}
});
}, 1000);
updatingMessage();
}
$(document).ready(main);
What's bother me is everytime when I scroll down to see the information
it will scroll to the top of itself after each ajax call. Is there anyway to stay at the same <p>'s position after an ajax call ?
First you must get the element's scroll position, then make sure you maintain that position by setting the scrollTop attribute to the original position.
var position = element.scrollTop;
//do some work here, which might change the position
element.scrollTop = position;
In my case, I have a table with overflow-y: auto and a fixed height: 350px. The .scrollTop() function does not work. Indeed, I tried to read the Y position of <table> or <tbody>, but it always returns 0!
When I refresh my <table>, the browser reset scroll position on my tables ! I absolutely need to prevent this.
Here is my workaround :
update only the contents of <tbody> instead of the entire <table>
It works fine, the scroll position of my tables is not reset.
Below is a part of my code that updates 3 tables every 10 seconds:
function updateTables() {
jQuery.ajax({
url: '/get-tables.php',
dataType: 'json',
type: 'get',
data: {
tableId: [
'table-actual',
'table-new',
'table-history'
]
},
success: function(response){
jQuery.each(response, function (key, table) {
jQuery('#table-' + table.id + ' tbody').html(data.content);
});
}
});
}
setInterval(updateTables, 10000);
Hope it helps some of you.

jquery textarea does not updates its value

I have site with some columns on it and theese columns can be editet by a textarea, if the column you want to edit have some content, that old content will be put into the textarea. Then on the save button is stores the value of that text area into a variable, if i alert this variable it alerts the same value as the old content.
The idea is biscally this: FIDDLE
Where the textarea updates a div and when you hit save and get the content in the div when you hit edit. This simple works as it should, but I'm having trupple with my code, and i cant find the error. And there is no error in the console aswell.
The differense on the exmaple i made and the place of my problem is that i use an ajax call to get the old content.
First here is what happens on the edit click:
$('body').on('click', '.edit_column', function() {
column_to_edit = $(this).parent().parent().attr('id');
current_step = "edit";
$.ajax({
url: 'pageEditor_ajax.php',
dataType: 'json',
async: false,
type: 'post',
data: {
item_id: column_to_edit,
mode: "edit_item"
}, success:function(s) {
element_type = s.type;
old_content = s.content;
}, error:function(e) {
alert('Error!');
}
});
if(element_type == 'text') {
$('.input_type').html('<textarea class="dialog_editor element_content"></textarea>');
}
$('.element_content').val(old_content);
$('.column_tool_dialog').css('display', 'block');
$('#edit_column_dialog').css('display', 'block');
$('#edit_column_dialog').animate({
left: "-=300px",
opacity: "1"
},500);
});
First i find the id of the column i want to edit so I'm shure that im editing the right column i the database.
The current_step variable is only for the looks, have some different dialog boxes.
The i make my ajax call that returns with success.
Then i have an if statement to check what type of column it is, i have 3 types, the two others is image and headline, havn't startet on them yet because this is not working yet.
The if statement should just build the inputs need to edit that type of column.
After the input fields a build it put the old_content into the textarea, this works fine too. The last few line is just for the looks agen to animate to the next dialog box. So my edit step works (I think).
Then you see the textarea, and i have the old content in it. When you click the save button, this happens:
$('#element_edit_button').click(function(e) {
e.preventDefault();
new_content = $('.element_content').val();
alert(new_content);
$.ajax({
url: 'pageEditor_ajax.php',
dataType: 'json',
async: false,
type: 'post',
data: {
item_id: column_to_edit,
item_content: new_content,
col_type: element_type,
mode: "save_item",
item_attr_alt_tag: alt_tag,
item_attr_title_tag: title_tag
}, success:function(s) {
}, error:function(e) {
alert('Der skete en fejl!');
}
});
$('li#'+column_id+' .preview_content').html(new_content);
$('li#'+column_id+' > div > small').html(new_content);
});
In this step i have a lot of things just for the looks, so i have excluded them this time. But the problem is fairly simple to explain here, the new_content variable is identic with the old_content? So all the places where is use the new_content the stuff dont get updated.
EDIT
Here is the html where it all happens:
<div id=\"edit_column_dialog\" class=\"column_tool_dialog_box\">
<div class=\"close\">x</div>
<h3>Rediger dit element</h3>
<form method=\"post\" id=\"save_element\">
<p class=\"error_message\"></p>
<div class=\"input_type\"></div>
<input id=\"element_edit_button\" class=\"green dialog_button\" type=\"submit\" value=\"Gem element\" />
</form>
</div>
</div>
Sorry for the long post, hope someone have an awnser.
As others have said, your jquery and even html could use some cleaning up. With that said, assuming I understand your question correctly, I think you're just missing a line in your #element_edit_button click event:
$('.element_content').val(new_content);
That should do the trick.

jQuery: Inserting li items one by one?

I wrote the following (part of a jQuery plugin) to insert a set of items from a JSON object into a <ul> element.
...
query: function() {
...
$.ajax({
url: fetchURL,
type: 'GET',
dataType: 'jsonp',
timeout: 5000,
error: function() { self.html("Network Error"); },
success: function(json) {
//Process JSON
$.each(json.results, function(i, item) {
$("<li></li>")
.html(mHTML)
.attr('id', "div_li"+i)
.attr('class', "divliclass")
.prependTo("#" + "div_ul");
$(slotname + "div_li" + i).hide();
$(slotname + "div_li" + i).show("slow")
}
}
});
}
});
},
...
Doing this maybe adding the <li> items one by one theoretically but when I load the page, everything shows up instantaneously. Instead, is there an efficient way to make them appear one by one more slowly? I'll explain with a small example: If I have 3 items, this code is making all the 3 items appear instantaneously (at least to my eyes). I want something like 1 fades in, then 2 fades in, then 3 (something like a newsticker perhaps). Anyone has a suggestion?
You might want to get the wanted effect by coding as following:
$(slotname + "div_li" + i).hide().delay(i*n).show("slow");
where n is some soft of delay modifier (in milliseconds); I assume i also here is the index, and thus a number.

Categories