How to insert an element only once with jQuery event

Asked

Viewed 162 times

1

I am creating a validation in jQuery and when the field loses its focus it checks if it is empty and inserts the error message, more every time this event happens it inserts the same message. How to do this without this repetition?

I wanted to do something similar to jquery-validate...

My code is this:

$(function() {
  var $form = $("#formtest");
  $("#nome").on('blur', function() {
    var $this   = $("#nome"),
        $value  = $this.val();

    if ($value == "") {
      $form.submit(function() {
        return false;
      });
      if ($this.hasClass('.error')) {
        $this.removeClass("erro");
        $("small").remove();
      } else {
        $this.addClass("erro");
        $this.after("<small class='erro'>Preencha seu nome!</small>");

      }
    } else {
      $this.removeClass("erro");
      $("small.erro").remove();
      alert("tudo certo!");
      $form.submit(function() {
        return true;
      });
    }
  })
})
input.erro {
  border: 1px solid red;
}

.erro {
  color: red;
  padding-left: .3rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="formtest">
  <label>Nome</label>
  <br>
  <input type="text" id="nome" value="">
  <input type="submit" value="submit">
</form>

2 answers

2

To ONE THING what you need to do is change the line $("small").remove(); of place, placing it before the if:

$(function() {
  var $form = $("#formtest");
  $("#nome").on('blur', function() {
    var $this   = $("#nome"),
        $value  = $this.val();

    if ($value == "") {
      $form.submit(function() {
        return false;
      });
      // COLOQUE AQUI. Irá remover se existir
      $("small").remove();
      if ($this.hasClass('.error')) {
        $this.removeClass("erro");
      } else {
        $this.addClass("erro");
        $this.after("<small class='erro'>Preencha seu nome!</small>");

      }
    } else {
      $this.removeClass("erro");
      $("small.erro").remove();
      alert("tudo certo!");
      $form.submit(function() {
        return true;
      });
    }
  })
})
input.erro {
  border: 1px solid red;
}

.erro {
  color: red;
  padding-left: .3rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="formtest">
  <label>Nome</label>
  <br>
  <input type="text" id="nome" value="">
  <input type="submit" value="submit">
</form>

  • thanks for your reply, helped too much! wanted to understand this logic of it having to be before to check, I could explain?

  • I forgot to ask, how do you check when you press Submit too...?

1


An interesting solution

This way just put data-required="Preencha seu nome!" in the input text you want putting the error message and so you will no longer need to modify the javascript for the new fields you create, and also you can create new custom validations with the same idea.

Upshot

Code comments are explaining how it works

//Função para cuidar da mensagem de erro
function setaMensagem(seletor, mensagem){

  //Verifica se já existe uma mensagem de erro
  if(seletor.next().attr("class") == 'erro'){
    seletor.next().text(mensagem); //Se existir apenas seta a mensagem
  }else{
    seletor.after("<small class='erro'>" + mensagem + "</small>");//Se não cria uma mensagem nova
  }
}

function validar(element){
    if(element.val().length <= 0){
      setaMensagem(element, element.data('required'));
      return false;
    }else{
      setaMensagem(element, "");
      return true;
    }
}

$(function() {
  $("[data-required]").on('blur', function() {
    validar($(this));
  });
  $('#formtest').submit(function() {
    return validar($("[data-required]"));
  });
})
input.erro {
  border: 1px solid red;
}

.erro {
  color: red;
  padding-left: .3rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="formtest">
  <label>Nome</label>
  <br>
  
  <input 
  type="text"  
  id="nome" 
  value="" 
  data-required="Preencha seu nome!">
  <!-- Defino apenas a mensagem de erro -->
  
  <small class='erro'></small>
  <input type="submit" value="submit">
</form>

Solving using your code

Red error message

For the error message to be set only once I have directly placed the html tag

<small class='erro'></small>

Since it is empty it will not be visible, and in the code Javascript I put it this way

$this.next().text("Preencha seu nome!");

It takes the next element using the method next, which in this case is the tag small and arrow the text, in case it seven again it replace the previous text not thus repeating the text.

And finally I replace the following excerpt

$("small").remove();

for

$("small").text("");

So it just manipulates the text, since the small without text as stated above does not appear if there is no text.

Alert

But in case you want to limit the alert, I created a flag with a variable as I did in the case "Tudocerto", thus the alert appear only once.

The operation is simple, the flag is set to true, and when displaying the message it is set to false, if the event is called again the message does not appear since the flag will be false.

Upshot

$(function() {
  var tudoCerto = true;
  var $form = $("#formtest");
  $("#nome").on('blur', function() {
    var $this   = $("#nome"),
        $value  = $this.val();

    if ($value == "") {
      $form.submit(function() {
        return false;
      });
      if ($this.hasClass('.error')) {
        $this.removeClass("erro");
      } else {
        $this.addClass("erro");
        $this.next().text("Preencha seu nome!");

      }
    } else {
      $this.removeClass("erro");
      $("small.erro").text("");
      if(tudoCerto){
        alert("tudo certo!");
        tudoCerto = false;
      }
      
      $form.submit(function() {
        return true;
      });
    }
  })
})
input.erro {
  border: 1px solid red;
}

.erro {
  color: red;
  padding-left: .3rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="formtest">
  <label>Nome</label>
  <br>
  <input type="text" id="nome" value="">
  <small class='erro'></small>
  <input type="submit" value="submit">
</form>

  • thanks for your reply too, a really interesting method, just did not understand in your example, because the data-required you passed the message and then had to pass again within the function, it was not to take the data-required message dynamically?

  • Another thing I forgot to ask in my question, you can check this when you press Submit too?

  • I finished making the changes :)

  • Now it pulls the data-required value and also checks before the Submit :)

  • 1

    Perfect, you really saved me! now I can do my own way

  • Great! Any questions just comment, and please mark the question as answered :)

  • I’m new here, how do you do that ^^

  • You can press the up arrow button to evaluate the answers you liked, that is, you can vote for as many answers as you want with a positive vote, but underneath there is a "V", in which you mark the best answer for you.

  • Okay, now to be perfect, as I would give the focus to the button that is wrong more in the right order! , I tried here by adding an element.Focus() plus it shows out of order...

  • You have two buttons, one on the other, and when you hit it tab from the wrong focus button, that’s it?

  • When I press the Ubmit it focuses the other exact...

  • Let me get this straight, you want to press Ubmit, and focus go to the field in case of error?

  • Exactly, only I have about 10 fields to check, then it does not go to 1 it goes to the second... will have q to have a for()... if I have to, I do not have much notion of how to do...

  • I think this is a little outside the scope of the question, I think you’d better create a new question for that, because then the next person who’s having the same problem with you will be able to search for it, create the new question explaining your difficulty, and post the link here

  • 1

    True, thank you!

Show 10 more comments

Browser other questions tagged

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