Count the amount of characters changed in an input field

Asked

Viewed 910 times

10

On a given page for changing registered data, in one of the fields you need to limit the number of characters that can be changed. There are 2 fields inputs and one of them is hidden by storing the name in the current form. In input visible is also stored the name in the current format and the user can make changes. I used the OnBlur for when the user leaves the field a method js compares the string of input occult with the input visible, if there are more than 3 changes a message is passed to the user and the name goes back to the previous format.

The problem is that I couldn’t get a logic that meets all the rules, what complicates it is that characters can be removed, altered or inserted, that is, if the information Hnrikuei is recorded and the user wants to fix to Henry three amendments shall be counted:

  1. 'and' added,
  2. 'i' removed
  3. 'k' change for 'q'
  • I think I get the whole character change thing. For example, if the user fills the field with "George" and then switches to "Geor", it will be possible because only 2 characters, "g" and "e" have been changed. Is that right? But there’s something I don’t quite understand, so the hidden input?

  • In the hidden input is the name in the format in which it came from the comic book. Ai whenever it leaves the field Onblur sends the value of the hidden input and the visible input where the changes were made.

  • @Georgewurthmann please post the code you have already made and if possible create some examples that could help us understand the problem.

  • @Gabriel Rodrigues, I will be the solution indicated by Bacco. You want me to post my code anyway?

2 answers

11


To Distance from Levenshtein is one of the best known algorithms to calculate the difference between two strings.

See an adaptation of another issue for your specific case:

function levenshtein(str1, str2) {
  var m = str1.length,
      n = str2.length,
      d = [],
      i, j;

  if (!m) return n;
  if (!n) return m;

  for (i = 0; i <= m; i++) d[i] = [i];
  for (j = 0; j <= n; j++) d[0][j] = j;

  for (j = 1; j <= n; j++) {
    for (i = 1; i <= m; i++) {
      if (str1[i-1] == str2[j-1]) d[i][j] = d[i-1][j-1];
      else d[i][j] = Math.min(d[i-1][j], d[i][j-1], d[i-1][j-1])+1;
    }
  }
  return d[m][n];
}

// Daqui para baixo, o código é apenas para demonstração de uso.
function calc() {
  var t1 = document.getElementById('t1');
  var t2 = document.getElementById('t2');
  var r1 = document.getElementById('r1');
  var d  = levenshtein( t1.value, t2.value );
  r1.innerHTML = d;
  r2.innerHTML = d>3?'Não':'Sim';
}
calc();
<strong>Altere os campos para testar a função</strong><br>
Palavra 1:<br>
<input id="t1" type="text" value="Hnrikuei" onKeyUp="calc()"><br>
Palavra 2:<br>
<input id="t2" type="text" value="Henrique" onKeyUp="calc()"><br>
Diferença:<br>
<div id="r1">?</div>
Valida (até 3):<br>
<div id="r2">?</div>


Here’s a link recommended by @Cold with string similarity measurement techniques:
http://en.wikipedia.org/wiki/Category:String_similarity_measures

  • 3

    That’s exactly what I need, perfect! Thank you so much @Bacco and everyone else involved.

3

Well, I did an example on Jsfiddle: http://jsfiddle.net/SamirChaves/y41q39yd/4/

You will notice that there are two text boxes. Basically, the system will check if there is a difference greater than 3 characters.

    function verifyChange(){

        var span = document.getElementsByTagName("span")[0];

        var name = document.getElementById("name_user");
        var correcao = document.getElementById("correcao_name_user");

        var char1 = []; //quantidade de caracteres do name_user
        var char2 = []; //quantidade de caracteres do correcao_name_user

        for(var i = 0; i < name.value.length; i++){
            char1[i] = name.value.substring(i, i+1);
        }
        for(var j = 0; j < correcao.value.length; j++){
            char2[j] = correcao.value.substring(j, j+1);
        }
        if(char1.length - char2.length > 3 || char2.length - char1.length > 3){

            span.innerHTML = "Modificação inválida.";

        }else{
            var NCrt = 0; //nº de caracteres modificados
            var n = 0;
            if(char1.length == char2.length){
                for(var i = 0; i < char1.length; i++){
                    if(char1[i] != char2[i]){
                        NCrt++;
                    }
                }
            }else{
                if ( char1.length < char2.length){
                    Mlength = char1.length
                    
                    for(var j = 0; i < char2.length; i++){
                        for(var i = 0; i < char1.length; i++){
                            if(char1[j] != char2[i]){
                                NCrt++;
                            }
                    	}
                        if(NCrt == char2.length){
                        	n++;
                        }
                    }
                }else {
                    
                    for(var j = 0; i < char1.length; i++){
                        for(var i = 0; i < char2.length; i++){
                            if(char2[j] != char1[i]){
                                NCrt++;
                            }
                    	}
                        if(NCrt == char1.length){
                        	n++;
                        }
                    }
                }
            }
            if(NCrt > 3 || n > 3){
                span.innerHTML = "Modificação inválida.";
            }else{
            	span.innerHTML = "Modificação válida.";
            }
        }
    }
<form action="javascript: verifyChange()">
  <input type="text" onblur="verifyChange()" id="name_user" value="George">
  <input type="text"  onblur="verifyChange()"  id="correcao_name_user" value="gege">

  <input type="submit" value="Verificar" onclick="verifyChange()">
  <br>
  <br>
  <span></span>

</form>

Fiz em javascript puro mesmo.

The estate substring, works by capturing the character of String, for example:

    var ex = "Exemplo";
    ex.substring(0, 3);

Would result in:

    Exe

It counts as if it worked equal to a selection, |E|x|e|m|p|l|o|

in the above case, it selected from the first bar (0) to the fourth (3).

See more about the subtring here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring

There is also the substr, explained here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr

  • Samir, I did something similar in js pure també and I had the logic problem I mentioned to you. Test, for example George and Gege. It returns invalid, but only 2 letters have been removed.

  • Yeah. You’re right.. I’m sorry, I’ll try to fix this problem and edit the answer.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.