How To Refresh Chat using ajax - javascript

I'm implementing text chat based on twilio api ,I have functions do the following loads the chat on click ,send message,get last message (setting interval to 1sec to update in real time) and i will add check if the data is unset do nothing else fetch last message,
I need to get the data value of the current clicked item
here is the script and the logs
[![<script type="text/javascript">
$(document).ready(function(){
loadContacts();
displayChatOnclick();
setInterval(getlastmsg,1000);
}
);
//when the user clicks on contacts div fetch the chat history
function displayChatOnclick(){
$('#contacts').on('click','li',function() {
var channel = $(this).closest('li').attr('data-channel');
var name=$(this).closest('li').attr('data-name');
console.log(channel);
fetchChat(channel,name);
sendmsg();
//check if new msg is sent
});
}
function fetchChat(channel,name){
$.ajax({
url: 'loadchat.php',
type: 'POST',
data: { channel:channel,name:name },
success: function(msg) {
console.log(name);
$('#conversation').html(msg);
}
});
}
function loadContacts(){
$.ajax({
url: 'loadcontacts.php',
type: 'POST',
success: function(msg) {
$('#contacts').html(msg);
}
});
}
//function to get the last msg
function getlastmsg(){
var channel = $('#contacts li').data('data-channel');
var name=$('#contacts li').data('data-name');
//check if channel and name is null do nothing else fetch last message
console.log(name);
}
//function to send a msg
function sendmsg(){
$("#send").click(function() {
var channel=$(this).data('ch');
var message=$("#msg").val();
$('#msg').val('');
console.log(msg);
$.ajax({
type: "POST",
url: "sendmsg.php",
data: {
msg: message,
channel:channel,
},
success: function(result) {
console.log("sent");
$('#b').append(result);
}
});
});
}
</script>][1]][1]

what you are doing is a pull method: setInterval is not the best idea because it keeps calling your server with or without a change, imagine if you have 1000 users each one of them will send a request to the server every second.
I advise you to use a push method such as SignalR. here is a demo for chat that you can do with small number of lines

try this
var $container = $("#contacts li");
$container.load("rss-feed-data.php");
var refreshId = setInterval(function()
{
$container.load('rss-feed-data.php');
}, 9000);

Related

Reloading Ajax function with setTimeout doesnt clear previous timeout first

I am trying to load a chat box when a contact name is clicked. On initial load it displays the inbox. All functionality works ok until I try and click the contact name a second time. It loads the new contacts chat but also displays the original contact chat even though I set clearTimeout().
Here is the JS file -
$(document).ready(function(){
var contactTimeout;
var inboxTimeout;
function contact() {
var fromName = $('#from').val();
var toName = $("#to").val();
$(".chat-title").replaceWith("<div class='chat-title'>" + toName + "</div>");
$(".chat-form").fadeIn(100);
$.ajax('chat/get-chat.php', {
data: ({ to: toName,from: fromName}),
type: "POST",
success: function(data) {
$(".chat-body").replaceWith("<div class='chat-body'>" + data + "</div>");
contactTimeout = setTimeout(contact, 2000);
}
});
}
function inbox() {
var user = $('#from').val();
$.ajax('chat/get-chat-inbox.php', {
data: ({ user: user}),
type: "POST",
success: function(data) {
$(".chat-body").replaceWith("<div class='chat-body'>" + data + "</div>");
inboxTimeout = setTimeout(inbox, 2000);
}
});
}
// Load inbox when chat box is opened
$(".chat-arrow").click(function(){
clearTimeout(contactTimeout);
inbox();
});
// Load chat from contact name
$(".contact-name").click(function() {
clearTimeout(contactTimeout); // Here I try and kill previous timeout
clearTimeout(inboxTimeout);
var contactName = $(this).attr('id');
$("#to").val(contactName);
contact();
});
});
Why would it just add more timeout functions rather than replace them when a new contact name is clicked?
First i would suggest you instead of using replace each time, you could easily use .html(data) to put new data in existing content of chat-body.
And explanation is you call your function on ajax success (there's wait time to server respond to your request) and if you click in meanwhile on your another call, you will have two calls instead of one, because you can't clear timer that's not started yet.
Well one of the solutions would be, let timer works only through it's default state, and when you need some fast data, you can call your contact without calling the next timer.
$(document).ready(function(){
var contactTimeout;
var inboxTimeout;
/* add parameter which will mean will we call timer or not */
function contact(dotimer) {
var fromName = $('#from').val();
var toName = $("#to").val();
$(".chat-title").replaceWith("<div class='chat-title'>" + toName + "</div>");
$(".chat-form").fadeIn(100);
$.ajax('chat/get-chat.php', {
data: ({ to: toName,from: fromName}),
type: "POST",
success: function(data) {
$(".chat-body").replaceWith("<div class='chat-body'>" + data + "</div>");
/* default calling of timer with repeating */
if (dotimer) { contactTimeout = setTimeout(function(){ contact(true); }, 2000); }
}
});
}
function inbox() {
var user = $('#from').val();
$.ajax('chat/get-chat-inbox.php', {
data: ({ user: user}),
type: "POST",
success: function(data) {
$(".chat-body").replaceWith("<div class='chat-body'>" + data + "</div>");
inboxTimeout = setTimeout(inbox, 2000);
}
});
}
// Load inbox when chat box is opened
$(".chat-arrow").click(function(){
clearTimeout(contactTimeout);
inbox();
});
// Load chat from contact name
$(".contact-name").click(function() {
clearTimeout(inboxTimeout);
var contactName = $(this).attr('id');
$("#to").val(contactName);
/* call function without TIMER, default one will work as it works */
contact(false);
});
});

Delete data from database without reloading the page

I want to delete data from database without refreshing the page. My code is working but after deleteing a product needs to refresh the page. I want something like this
Here is my js code:
<script>
$(document).on('click', '.delete-it', function() {
var id = $(this).attr('delete-id');
bootbox.confirm("Are you sure?", function(result) {
if (result) {
$.ajax({
type: "POST",
async: false,
url: "delete_product.php",
data: {
object_id: id
},
dataType: 'json',
success: function(data) {
location.reload();
}
});
}
});
return false;
});
</script>
and the delete_product php code:
<?php
// check if value was posted
if($_POST){
// get database connection
$database = new Database();
$db = $database->getConnection();
// prepare product object
$product = new Product($db);
// set product id to be deleted
$product->id = $_POST['object_id'];
// delete the product
if($product->delete()){
echo "Object was deleted.";
}
// if unable to delete the product
else{
echo "Unable to delete object.";
}
}
?>
Please show me a way to make it!
I see no place where the you're targeting something in the page, but this is what I would use:
<script>
function swapContent(href, url_data, target) {
$.ajax({
type: 'GET',
cache: false,
url: href+'?' + url_data, //add a variable to the URL that will carry the value in your i counter through to the PHP page so it know's if this is new or additional data
success: function (data) { // this param name was confusing, I have changed it to the "normal" name to make it clear that it contains the data returned from the request
//load more data to "target" value div
target.innerHTML = (data); // as above, data holds the result of the request, so all the data returned from your results.php file are in this param but please see below
}
})
}
$(document).on('click', '.delete-it', function() {
var id = $(this).attr('delete-id');
bootbox.confirm("Are you sure?", function(result) {
if (result) {
swapContent(base_url, url_data, target) //set variables
}
});
return false;
});
</script>
note: because of how much ajax I use, I keep an ajax function by itself

How to display a progress bar during an ajax request (jquery/php)

I have an ajax request, whereby I am installing a magento shop automatically, and when the process is done, it would redirect the user to the newly created shop. Here are my codes:
function postSuccessFormData() {
var targetUrl = '/index.php/install/wizard/successPost';
jQuery('.form-button').addClass('loading');
setInterval(installStatus(),4000);
jQuery.ajax({
url: targetUrl,
global: false,
type: 'POST',
data: ({
finish: 1,
password_key: jQuery('#password_key').val()
}),
async: true,
dataType: 'json',
error: function() {
alert("An error has occurred. Please try again.");
},
success: function(data) {
window.location.href = '/';
}
});
function installStatus() {
var installerUpdatesUrl = '/index.php/install/wizard/installerStatus';
//showProgressBar();
jQuery.ajax({
url: installerUpdatesUrl,
// global: false,
type: 'GET',
async: true,
dataType: 'json',
error: function (data) {
// alert(data.result);
},
success: function (data) {
handle data.result
var dataKeys = Object.keys(data);
var lastElementKey = dataKeys[dataKeys.length - 1];
var lastMessage = data[lastElementKey]['message'];
if(data[lastElementKey]['progress'] == '') {
updateProgressBar(data[dataKeys[dataKeys.length - 2]]['progress'],100);
}
setting message
jQuery("#message").html(lastMessage);
if (data[lastElementKey]['state'] == 'Failure') {
var stepStr = lastElementKey.split('_');
var stepString = stepStr[0].toUpperCase() + ' ' + stepStr[1] + ':';
alert(stepString + "\n" + data[lastElementKey]['message']);
//hideProgressBar();
jQuery('.form-button').removeClass('loading');
return false;
} else if (data[lastElementKey]['state'] == 'Finish') {
alert(data[lastElementKey]['message']);
//hideProgressBar();
jQuery('.form-button').removeClass('loading');
//window.location.href = '/';
} else {
// installStatus();
}
},
complete: function () {
installStatus();
jQuery('.form-button').removeClass('loading');
}
});
}
The way this is done:
After every 4 seconds the function installStatus is run, which will output the current progress in JSON format. My problem is, this function needs to be executed simultaneously with the function post().
This is not happening, the installStatus is only run after the first function has been completed.
What is wrong?
You are executing installStatus when you define it. So this:
setInterval(installStatus(),4000);
needs to be
setInterval(installStatus, 4000);
The new XMLHttpRequest has a nice progress event you can listen to show the user the upload progress.
Here's the spec with a nice demo: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress
Initially you should call installStatus() only once and then inside the method inside ajax success you should update the procent in the progress bar and call it recursively the same method. On the server side you can save the current procent in a cookie and with every recursive call you can update the cookie and return the procent.

Cannot write in text box while it's autosaving using tinymce-4 plugin

I am using a plugin to autosave a textbox. However, when the autosave function is called, the text box cannot be typed into. I want users to be able to continue typing while the auto save is posted via AJAX.
tinymce.PluginManager.add('jsave', function(editor) {
// Get the form element into a jQuery object.
var $form = $(editor.formElement);
// Settings for initialization.
var settings = {
// Interval to execute the function. Default is 15000 (ms 1000 = 1 second).
//seconds: editor.getParam('jsave_seconds') || 2000,
seconds: 2000,
// This is our url that we will send data. If you want to have two different links,
// one for ajax and one for manual post this setting is pretty useful!
url: editor.getParam('jsave_url') || $form.attr('action'),
// This is the callback that will be executed after the form is submitted
callback: editor.getParam('jsave_callback')
};
$('.form_header,#attachbox').change(function (){
tinymce.get('mail_body').isNotDirty=0;
$("#save_status").html("Not saved");
});
var interval = setInterval(function() {
// Quit the function if the editor is not dirty.
if (!editor.isDirty()){
return;
}
// Update the original textarea
editor.save();
// Create a data string from form elements.
ds =$form.serialize();
// $form.find(':input').each(function (i, el) {
// $el = $(el);
// if($el.attr('name')!=null)
// ds[$el.attr('name')] = $el.val(); }
// );
$("#save_status").html("Saving");
$.ajax({
url: settings.url,
type: $form.attr('method'),
data: ds,
dataType:"json",
async:false,
success: function(msg) {
if (settings.callback){
//editor.setContent(msg.draft_body);
$("#save_status").html("Saved");
settings.callback(msg);
}
else{
$("#save_status").html("Saving error");
console.log(msg);
}
}
});
}, settings.seconds);
}); //vsk.me/en/28/adding-an-autosave-plugin-to-tinymce-2#sthash.jsOruJSd.dpuf
I have solved this problem:
just change form async:false, to async:true, in ajax calling part.
$.ajax({
url: settings.url,
type: $form.attr('method'),
data: ds,
dataType:"json",
async:true,
success: function(msg) {
if (settings.callback){
//editor.setContent(msg.draft_body);
$("#save_status").html("Saved");
settings.callback(msg);
}
else{
$("#save_status").html("Saving error");
console.log(msg);
}
}
});
Why don't you just disable it while doing the ajax call and enable again on ajax call ends?
You have a reference to enable/disable the field via JavaScript here:
make readonly/disable tinymce textarea
That way you could use the complete attribute on your Ajax call to enable the field again after either succes or error response like this:
var interval = setInterval(function() {
// Quit the function if the editor is not dirty.
if (!editor.isDirty()){
return;
}
// Update the original textarea
editor.save();
// Create a data string from form elements.
ds =$form.serialize();
$("#save_status").html("Saving");
tinyMCE.get('textarea_id').getBody().setAttribute('contenteditable', false);
$ajax({
url: settings.url,
type: $form.attr('method'),
data: ds,
dataType:"json",
async:false,
success: function(msg) {
if (settings.callback){
//editor.setContent(msg.draft_body);
$("#save_status").html("Saved");
settings.callback(msg);
}
else{
$("#save_status").html("Saving error");
console.log(msg);
}
},
error:function(){
//DO ERROR STUFF
},
complete:function(){
tinyMCE.get('textarea_id').getBody().setAttribute('contenteditable', true);
}
});

How to connect to the Parse Javascript API? (502 error)

I am building a chatroom-type app using the Parse Javascript API. The task is to get some data from Parse, display it, add user input to the messages, and send it right back to parse.
The problem is I am not being able to see the data from parse, and receive a 502 error. I am a bit newer to javascript, so any advice on how to accomplish this, or any mistakes you may see in my code, would be fantastic. I also commented out my code the best I could. Thanks for the help.
Here is my code;
$(document).ready(function(){
delete Chat.display;
delete Chat.send;
delete Chat.fetch;
var my_messages = $('ul.messages')
//fetches data from parse
var myChat = function() {
$.ajax({
url: "https://api.parse.com/1/classes/chats",
dataType: "json",
success: console.log("Success"),
function message(a) {
my_messages.append('<ul>' + a +'</ul>'); //adds ul 'text' to messages
};
});
};
myChat(); // call mychat
$('button.send').on('click', function() { // when user clicks send
// send post to
$.ajax({
type: "POST",
url: "https://api.parse.com/1/classes/chats",
data: JSON.stringify({text: $('input.draft').val()}), // stringify the text on value input.draft
function(message){
window.location.reload(1) //refresh every 3 seconds
});
});
});
</script>
you have syntax error in both of your success functions of $.ajax calls. In the first ajax call you have places console.log, which should be inside the success callback. In the second one u haven't even added success: callback.
Try below updated code
$(document).ready(function(){
delete Chat.display;
delete Chat.send;
delete Chat.fetch;
var my_messages = $('ul.messages');
var myChat = function() {
$.ajax({
url: "https://api.parse.com/1/classes/chats",
dataType: "json",
success:function message(a) {
console.log("Success")
$.each(a,function(i,item){
my_messages.append('<ul>' + item.username +'</ul>'); //adds ul 'text' to messages
});
}
});
};
myChat(); // call mychat
$('button.send').on('click', function() { // when user clicks send
// send post to
$.ajax({
type: "POST",
url: "https://api.parse.com/1/classes/chats",
data: JSON.stringify({text: $('input.draft').val()}), // stringify the text on value input.draft
success:function(message){
window.location.reload(1) //refresh every 3 seconds
}
});
});
});

Categories