user4082764
user4082764

Reputation:

Ajax User Typing message for chat

I am trying to make a facebook style user typing system. But i have one question about keypress.

So my code is working fine but i want to change something else like keypress, keyup, paste ect.

I am using following javascript and ajax codes. In the following my ajax code is working like if ($.trim(updateval).length == 0) { send width notyping.php notyping.php posting 0 and the 0 is don't show typing message.

If if ($.trim(updateval).length > 13) { send with usertyping.php usertyping.php posting 1 and the 1 is show typing message.

The problem is here if user is stoped to wrire some message then it is everytime saying typing. What should I do to fix for it anyone can help me in this regard ?

All ajax and javascript code is here:

;
(function($) {
  $.fn.extend({
    donetyping: function(callback, timeout) {
      timeout = timeout || 1000; // 1 second default timeout
      var timeoutReference,
        doneTyping = function(el) {
          if (!timeoutReference) return;
          timeoutReference = null;
          callback.call(el);
        };
      return this.each(function(i, el) {
        var $el = $(el);
        // Chrome Fix (Use keyup over keypress to detect backspace)
        // thank you @palerdot
        $el.is(':input') && $el.is(':input') && $el.on('keyup keypress paste', function(e) {
          // This catches the backspace button in chrome, but also prevents
          // the event from triggering too premptively. Without this line,
          // using tab/shift+tab will make the focused element fire the callback.
          if (e.type == 'keypress' && e.keyCode != 8) return;

          // Check if timeout has been set. If it has, "reset" the clock and
          // start over again.
          if (timeoutReference) clearTimeout(timeoutReference);
          timeoutReference = setTimeout(function() {
            // if we made it here, our timeout has elapsed. Fire the
            // callback
            doneTyping(el);
          }, timeout);
        }).on('blur', function() {
          // If we can, fire the event since we're leaving the field
          doneTyping(el);
        });
      });
    }
  });
})(jQuery);

Checking text value if is 0 then send data is 0 for user no typing

$('#chattextarea').donetyping(function() {
  var typingval = $("#chattextarea").val();
  var tpy = $('#tpy').val();
  if ($.trim(typingval).length == 0) {
    $.ajax({
      type: "POST",
      url: "/notyping.php",
      data: {
        tpy: tpy
      },
      success: function(data) {

      }
    });
  } 

Checking text value is >13 then send data is 1 for user typing.(Maybe need to change this if statement)

if ($.trim(typingval).length > 13) {
    $.ajax({
      type: "POST",
      url: "/usertyping.php",
      data: {
        tpy: tpy
      },
      success: function(data) {

      }
    });
  }

});

Check and show user typing:

function getTyping(){
     setInterval(function(){
         var tpy = $('#tpy').val();
           $.ajax({
            type: "POST",
            url: "/getTyping.php",
            data: { tpy: tpy },
            success: function(data) {
               $('#s').html(data);
              }
             });
         },1000);
    }   
getTyping();

HTML

<textarea id="chattextarea"></textarea>
<div id="s"></div>

Upvotes: 3

Views: 3297

Answers (3)

akmozo
akmozo

Reputation: 9839

I have some remarks about your code and app :

  • At the first, and as mentioned by @rory-mccrossan, unless you have the infrastructure of facebook, google or microsoft, ..., I think it's really a bad idea to use Ajax instead of Websockets for a real time application like a chat.

  • Now about your code, I don't know what your PHP scripts are doing behind the scene, but I think that you don't need to send two requests to indicate that the user is typing or not, you can limit that to one request to be sent when the user is typing otherwise, he is surely not typing. Of course you can use some sort of a timeout in your getTyping.php script to limit the life time of a "typing" status (for example 5 seconds), so if a request is sent after that timeout, you can know that your user is not typing.

  • And about your current problem, I think that's because the "not typing" status is just fired when the textarea is empty, so of course, after stopping writing and the length of the current text is more that 13, so the "not typing" status will never be fired (sent), that's why you need a timeout as I told you in the 2nd point ...

  • Also, don't forget the cache problem when getting the status using the getTyping.php script which should be not cacheable (or at least for a very limited period) ...

  • Then, I don't see in your posted code any information(s) to identify the current user and the one which is converting with him ... maybe you haven't included that in the question, I don't know !

...

Hope that can help.

Upvotes: 7

Rajveer gangwar
Rajveer gangwar

Reputation: 735

your updated code is given below i have created a getTyping function which will be call at every time 1 sec interval if user get start typing.

in get getTyping setinterval function i called a function check_which_function.

in function check_which_funciton i used your code by applying conditions on textarea value length which is in nested if else statement , so now

if user start typing but if content length is =0 than

$.trim(typingval).length == 0 will execute till length is not equal to 12

if length of content is greather equal to 13 than

$.trim(typingval).length > 13 will execute

by default getTyping2() function is executing in this function getTyping.php ajax call is going

<script>
    (function ($) {
        $.fn.extend({
            donetyping: function (callback, timeout) {
                timeout = timeout || 1000; // 1 second default timeout
                var timeoutReference,
                        doneTyping = function (el) {
                            if (!timeoutReference)
                                return;
                            timeoutReference = null;
                            callback.call(el);
                        };
                return this.each(function (i, el) {
                    var $el = $(el);
                    // Chrome Fix (Use keyup over keypress to detect backspace)
                    // thank you @palerdot
                    $el.is(':input') && $el.is(':input') && $el.on('keyup keypress paste', function (e) {
                        // This catches the backspace button in chrome, but also prevents
                        // the event from triggering too premptively. Without this line,
                        // using tab/shift+tab will make the focused element fire the callback.
                        if (e.type == 'keypress' && e.keyCode != 8)
                            return;

                        // Check if timeout has been set. If it has, "reset" the clock and
                        // start over again.
                        if (timeoutReference)
                            clearTimeout(timeoutReference);
                        timeoutReference = setTimeout(function () {
                            // if we made it here, our timeout has elapsed. Fire the
                            // callback
                            doneTyping(el);
                        }, timeout);
                    }).on('blur', function () {
                        // If we can, fire the event since we're leaving the field
                        doneTyping(el);
                    });
                });
            }
        });
    })(jQuery);


    function getTyping2() {
        var tpy = $('#tpy').val();
        $.ajax({
            type: "POST",
            url: "/getTyping.php",
            data: {tpy: tpy},
            success: function (data) {
                $('#s').html(data);
            }
        });
    }
    function check_which_action() {
        $('#chattextarea').donetyping(function () {
        var typingval = $("#chattextarea").val();
        var tpy = $('#tpy').val();
        if ($.trim(typingval).length == 0) {
            $.ajax({
                type: "POST",
                url: "/notyping.php",
                data: {
                    tpy: tpy
                },
                success: function (data) {

                }
            });
        }

        else if ($.trim(typingval).length > 13) {
            $.ajax({
                type: "POST",
                url: "/usertyping.php",
                data: {
                    tpy: tpy
                },
                success: function (data) {

                }
            });
        }
        else {
            getTyping2() ;
        }

    });
    }
    function getTyping() {
        setInterval(check_which_action, 1000);
    }
    getTyping();

</script>

<textarea id="chattextarea"></textarea>
<div id="s"></div>

Upvotes: 0

Armen
Armen

Reputation: 4202

My suggestion here to have external setInterval which will each 3 seconds save current text in oldValue variable and compare currentText with oldValue if they are equal then user stopped writing then send ajax to notyping.php

Upvotes: 0

Related Questions