3

I have a form with two input : one for Hostname another for ip address. how can i validate these two fields before submit the form and if they are not match with their pattern show an error.for example :Enter correct hostname. here is patterns:

Host : ^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$

Ip : ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$

Here is my snippet but it is not working :

$('#hosti').focusout(function() {
    $('#hosti').filter(function() {
        var hosti = $('#hosti').val();
        var hostiback = $('#hosti');
        var hostiReg = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
        if (!hostiReg.test(hosti)) {
            $('#hosti').css('boxShadow', '0px 0px 2px 1px #E25249');
        } else {
    $('#hosti').css('boxShadow', '0px 0px 0px 0px #E25249');
        }
    })
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<form>
  HOST :
<input type="text"  placeholder="Host" id="hosti" pattern="/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/"/>
  
  IP ADDRESS :
  <input type="text"  placeholder="IP Address" pattern="/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/"/>

  
  <button type="submit">Submit</button>
</form>
inaz
  • 1,755
  • 4
  • 20
  • 41

5 Answers5

3

Dunno what the focusout function is about... Why would you need that?

The pattern attribute handles what you need. You have however used the same pattern for both fields. And as Wiktor pointed out - you don't use the / for patterns. I've also added required.

This HTML should be all you need to make it work:

<form>
HOST :
<input type="text"  placeholder="Host" id="hosti" pattern="^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$" required/>

IP ADDRESS :
<input type="text"  placeholder="IP Address" pattern="^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$" required/>


  <button type="submit">Submit</button>
</form>

It appears as if SO's snippets don't support forms, but you can see it here at JSFiddle.

SamWhan
  • 8,296
  • 1
  • 18
  • 45
2

First of all, pattern regexps cannot have regex delimiters, the / must be removed. Also, these patterns are anchored by default (i.e. wrapped within ^(?: and )$), the ^ and $ are not necessary in the patterns you have.

To show an error message on submit, you need to add title attributes to the input nodes.

Also, you may add CSS styles to invalid and valid properties of the elements being validated.

See a demo below and a JSFiddle:

.to_validate:valid {
  color: black;
  border: 5px solid #dadadada; // dadada .glowing-border: http://stackoverflow.com/questions/5670879/css-html-create-a-glowing-border-around-an-input-field
  border-radius: 7px;
}
.to_validate:invalid {
  color: navy;
  outline: none; // .glowing-border:focus 
  border-color: #ff1050;
  box-shadow: 0 0 10px #ff0000;//#9ecaed
}
<form>
  HOST :
<input type="text"  placeholder="Host" class="to_validate" id="hosti" pattern="(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])" title="Wrong Host"/>
  IP ADDRESS :
  <input type="text" class="to_validate"  placeholder="IP Address" pattern="(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])" title="Wrong IP"/>
  <button type="submit">Submit</button>
</form>

If you want to fail a match once the whole HostName field input is equal to a number +.+ number +.+ number +.+ number pattern, add a (?!\d+(?:\.\d+){3}$) negative lookahead at the start:

pattern="(?!\d+(?:\.\d+){3}$)(([a-zA-Z\d]|[a-zA-Z\d][a-zA-Z\d-]*[a-zA-Z\d])\.)*([A-Za-z\d]|[A-Za-z\d][A-Za-z\d-]*[A-Za-z\d])"

See a JSFiddle here.

This lookahead matches 1 or more digits, and then 3 sequences of a dot and 1+ digits, and then the end of string (here, we need to define the end of string pattern explicitly as it is not at the end of the pattern).

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • It seems SO does not let the messages trigger in the sandboxed code, see the external JSfiddle to see the error message demo. – Wiktor Stribiżew Dec 14 '16 at 12:45
  • when the hostname field with for example :192.168.0.100 it almost show correct. but it's an ip address not a host name.what is the problem do you think? – inaz Jan 16 '17 at 09:11
  • The host field pattern also matches IP addresses, do you want to disallow them? See https://jsfiddle.net/0b300qo3/3/, where I added a negative lookahead at the start that will fail the match once the whole input looks like *number* +`.`+ *number* +`.`+ *number* +`.`+ *number*. I am somewhat unsure of what the requirements you need for the hostname part. – Wiktor Stribiżew Jan 16 '17 at 09:14
  • i want to add only name in host filed. in your newe fiddle when in host fileld i wrote : 192.168.178 it was still valid ! – inaz Jan 16 '17 at 10:38
  • Yes, that is valid because it only contains 3 numbers separated with dots, and an IP string requires 4 sections. So, it is not an IP. **What are your *exact* requirements**? Do you want to fail the match if there are digits/dots only? Use `(?![\d.]+$)` lookahead then. See [this demo](https://jsfiddle.net/0b300qo3/4/). – Wiktor Stribiżew Jan 16 '17 at 11:09
1

Basically what you're trying to achieve is an intermediate state between the button click event and form submission. What you can do is remove the type="submit" attribute from the button and capture the button click event, where you can validate your inputs and then submit the form. Something like this:

$("#submit_button").on("click", function() {
  /* DO ALL YOUR REQUIRED INPUT VALIDATIONS AND DISPLAY ERRORS */
  $("#my_form").submit();
}
1

You can use validation engine plugin (https://github.com/posabsolute/jQuery-Validation-Engine) and drop inside your patterns

Or just use input mask for users clarity with your patterns (https://github.com/RobinHerbots/Inputmask)

Last is less safe but anyway backend validation is inevitable

1

Check this out try put some value in host input and see

$(document).ready(function(){
  $( "input[name='host']")
   .focusout(function() {
     var pat_h  = $( "input[name='host']").attr("pattern");
     var val = $( "input[name='host']").val();
     var reg = new RegExp("^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$");
     if(reg.test(val)){
      alert("match")
     }
     else{
       alert("not match");
     }

   });
 });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<form>
  HOST : 
  <input  type="text"  placeholder="Host" id="hosti" pattern="/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/" name="host"/>
  
  IP ADDRESS :
  <input name="ip" type="text"  placeholder="IP Address" pattern="/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/"/>

  
  <button type="submit">Submit</button>
</form>
code.rider
  • 1,891
  • 18
  • 21