rickard
rickard

Reputation: 495

compare two client typed text fields jQuery

I have some problems with my jQuery "compare" function. Its mission is to compare two text areas and highlight the differences.

eg. "My name is Michael" in one text area, and "My name is Michel" in another.

My function shall return both inputs and highlight the char "a" from the first input, and highlight a missing char from the second.

This is how the function looks so far, but it doesn't seem to work 100% of the time.

$(function () {

$('#btnCompare').on('click', function () {
    compare();
});

function compare() {
    $('#divColLeft').empty();
    $('#divColRight').empty();
    var textOne = $('#taOneComp').val();
    var textTwo = $('#taTwoComp').val();

    var output;
    var outputX;

    var arrTextOne = [];
    var arrTextTwo = [];

    for (var i = 0; i < textOne.length; i++) {
        output = textOne.charAt(i);
        arrTextOne.push(output);
    }
    for (var x = 0; x < textTwo.length; x++) {
        outputX = textTwo.charAt(x);
        arrTextTwo.push(outputX);
    }

    $.each(arrTextOne, function (y, e) {
        if ($.inArray(e, arrTextTwo) == -1) {
            $('#divColLeft').append(e);
            $('#divColLeft').highlight(e);
        } else {
            $('#divColLeft').append(arrTextOne[y]);
        }
    });

    $.each(arrTextTwo, function (z, f) {
        if ($.inArray(f, arrTextOne) == -1) {
            $('#divColRight').append(f);
            $('#divColRight').highlight(f);
        } else {
            $('#divColRight').append(arrTextTwo[z]);
        }
    });
}

});

Update: To be more precise and improve the original question

If some includs the char "a" before any of the two texts, this is a difference that should be highlighted. In the first text the "a" should be highlighted, in the second text i want to input an empty space that is highlighting the difference(the missing char).

Upvotes: 16

Views: 3109

Answers (3)

razz
razz

Reputation: 10110

Your code will work only if the two strings has the exact same length and the same words arrangement, otherwise it will break down i.e. if you add an extra character at the beginning of the tested string.
after some coding i managed to come up with the code below, it compares two strings and find missing charcters/words, extra characters/words and wrong spellings:

function compare() {
    var elm1 = document.getElementById("div1"),
        elm2 = document.getElementById("txt"),
        output = document.getElementById("div2"),
        txt1 = elm1.innerHTML,          //original text
        txt2 = elm2.value,              //submitted text
        arr1 = txt1.split(" "),         //split original text to array of words
        arr2 = [];                      //miss matching words will be added here

//filter txt1 and txt2 from matching words and add miss matching to arr2///////
    for (var i in arr1) {
        var match = txt2.match(new RegExp("\\b" + arr1[i] + "\\b"));
        if (match) {
            txt2 = txt2.replace(new RegExp("\\s?" + arr1[i]), "");
            txt1 = txt1.replace(new RegExp("\\s?" + arr1[i]), "");
        } else if (!match) {
            arr2.push(arr1[i]);
        }
    }
//compare miss matching words from original and submitted text, if matching charachters is more that 50% highlight missing and extra characters
    var arr3 = txt2.split(" "), //convert filtered submitted text to words array
        right = elm1.innerHTML,
        wrong = elm2.value;
    for (var a in arr2) {
        for (var b in arr3) {
            var match2 = arr3[b].match(new RegExp("[" + arr2[a] + "]", "g")),
                t = (arr2[a].length > arr3[b].length) ? arr2[a].length : arr3[b].length;
            if (match2 && match2.length >= t * 0.5) { //check for words that look similar
                txt2 = txt2.replace(new RegExp("\\s?" + arr3[b]), "");
                txt1 = txt1.replace(new RegExp("\\s?" + arr2[a]), "");
                var str1 = "",
                    str2 = "",
                    n = 0;
                for (var c = 0; c < t; c++) {
                    if (arr2[a].charAt(c) === arr3[b].charAt(c + n)) {
                        str1 += arr3[b].charAt(c + n);
                        str2 += arr2[a].charAt(c);
                    } else if (arr2[a].charAt(c) !== arr3[b].charAt(c + n)) {
                        if(arr2[a].charAt(c + 1) == arr3[b].charAt(c + n)){
                            str2 += arr2[a].charAt(c).fontcolor("blue");
                            str1 += "_".fontcolor("red");
                            n--;
                        }else if(arr2[a].charAt(c) == arr3[b].charAt(c + n + 1)){
                            str1 += arr3[b].charAt(c + n).fontcolor("orange");
                            n++;
                            c--;
                        }else{
                            str1 += arr3[b].charAt(c + n).fontcolor("red");
                            str2 += arr2[a].charAt(c).fontcolor("green");
                        }
                    }
                }
                wrong = wrong.replace(arr3[b], str1);
                right = right.replace(arr2[a], str2);
            }
        }
    }
//check for extra words//////////////////////////////////////
    extra = txt2.split(" ");
    for(var d in extra){
        wrong = wrong.replace(extra[d], extra[d].fontcolor("grey"));
    }
//check for missing words//////////////////////////////////////
    missing = txt1.split(" ");
    for(var f in missing){
        right = right.replace(missing[f], missing[f].fontcolor("blue"));
    }
    output.innerHTML = wrong;
    elm1.innerHTML = right;
}

DEMO

How It Works:

  1. Compare original and submitted texts and find matching words and remove them
  2. Compare the remaining words from both strings
  3. If two words look similar (equal characters => 50% of total characters)
  4. check for missing/extra/misspelled characters and highlight them.
  5. Remove the misspelled words from both strings
  6. Highlight the remaining words in the original text as missing words
  7. Highlight the remaining words in the submitted text as extra words

Upvotes: 7

Prabhakaran Parthipan
Prabhakaran Parthipan

Reputation: 4273

My code Compare first textarea words with second textare words.For Example ..first textarea text is 'How are you' and second textarea text is 'I am fine'.It will compare 'how' with 'I' and 'are' with 'am'.. Please try this code...My fiddle

  $(function () {

            $('#btnCompare').on('click', function () {
                compare();
                return false;
            });

            function compare() {
                $('#divColLeft').empty();
                $('#divColRight').empty();

                var textOne = $.trim($('#taOneComp').val());
                var textTwo = $.trim($('#taTwoComp').val());

                var TempArr1 = textOne.split(' ');
                var TempArr2 = textTwo.split(' ');
                var arr1 = [];
                for (var i = 0; i < TempArr1.length; i++) {
                    if (TempArr1[i] !== "" && TempArr1[i] !== null) {
                        arr1.push(TempArr1[i]);
                    }
                }

                var arr2 = [];
                for (var i = 0; i < TempArr2.length; i++) {
                    if (TempArr2[i] !== "" && TempArr2[i] !== null) {
                        arr2.push(TempArr2[i]);
                    }
                }
                var minArrLen = arr1.length < arr2.length ? arr1.length : arr2.length;

                for (var x = 0; x < minArrLen; x++) {

                    var maxCharLen = arr1[x].length > arr2[x].length ? arr1[x].length : arr2[x].length;
                    for (var y = 0; y < maxCharLen; y++) {
                        if (arr1[x].charAt(y) == ' ') {
                            $('#divColLeft').append('<span  class="missing">' + arr2[x].charAt(y) + '</span>');

                            $('#divColRight').append('<span class="missmatch">' + arr2[x].charAt(y)) + '</span>';
                        }
                        else if (arr2[x].charAt(y) == ' ') {
                            $('#divColLeft').append('<span class="missing">' + arr1[x].charAt(y) + '</span>');

                            $('#divColRight').append('<span class="missmatch">' + arr1[x].charAt(y)) + '</span>';
                        } else if (arr1[x].charAt(y) == arr2[x].charAt(y)) {
                            $('#divColLeft,#divColRight').append(arr1[x].charAt(y));
                        }
                        else {
                            $('#divColLeft').append('<span  class="missmatch">' + arr1[x].charAt(y) + '</span>');
                            $('#divColRight').append('<span  class="missing">' + arr2[x].charAt(y) + '</span>');
                        }
                    }
                    $('#divColLeft').append(' ');
                    $('#divColRight').append(' ');
                }

                if (minArrLen < arr1.length) {
                    for (var Len = minArrLen; Len < arr1.length; Len++) {
                        $('#divColLeft').append(arr1[Len])
                                        .append(' ');
                    }
                } else if (minArrLen < arr2.length) {
                    for (var Len = minArrLen; Len < arr2.length; Len++) {
                        $('#divColRight').append(arr2[Len])
                                        .append(' ');
                    }
                }
            }
        });

Upvotes: 0

Alex M
Alex M

Reputation: 537

$(document).ready(function () {

  $('#btnCompare').on('click', function () {
      compare();
  });

  function compareText(textOne, textTwo)
  {
      var len = Math.min(textOne.length, textTwo.length);
      for (var i=0;i<len; i++)
      {
          if (textOne.charAt(i) == textTwo.charAt(i)) continue;

          return i;      // this character is different
      }

      if (textOne.length == textTwo.length) return -1;    // same

      return i;
  }

  function compare() {
      $('#divColLeft').empty();
      $('#divColRight').empty();
      var textOne = $('#taOneComp').val();
      var textTwo = $('#taTwoComp').val();

      var diffIndex = compareText(textOne, textTwo);
      if (diffIndex == -1)
      {
          // TODO: tell user they are identical
          $('#divColLeft').html('Identical');

      } else {

          // if textTwo has more characters, 
          // add a dummy character for highlighting to textOne

          if (diffIndex >= (textOne.length)) textOne += '_';

          var char = textOne.charAt(diffIndex);

          // highlight differing character

          var tmpLeft = textOne.substring(0, diffIndex);
          tmpLeft += "<span style='background-color:yellow;font-weight:bold'>" + char + "</span>";
          tmpLeft += textOne.substring(diffIndex+1);

          $('#divColLeft').html(tmpLeft);
      }
  }
});

Upvotes: -1

Related Questions