How to validate date with Angularjs or jQuery?

Asked

Viewed 17,707 times

7

I have a simple input that gets a date, how to validate that date if it is true?

For example:

31/02/2006 this does not exist
20/20/9999 this does not exist

<input name="data" 
 ui-mask="99/99/9999"
 kendo-date-picker name="t"
 ng-model="model.data"
 k-format="'dd/MM/yyyy'">

That is to validate days, months and years.

Is Angular something ready for this? Or if it is better to use Javascript, show me the simplest way.

  • See if the example I posted does not answer

6 answers

7

Follows:

Regular expression:

function isValidDate(date)
{
    var matches = /^(\d{2})[-\/](\d{2})[-\/](\d{4})$/.exec(date);
    if (matches == null) return false;
    var d = matches[2];
    var m = matches[1] - 1;
    var y = matches[3];
    var composedDate = new Date(y, m, d);
    return composedDate.getDate() == d &&
            composedDate.getMonth() == m &&
            composedDate.getFullYear() == y;
}

Directive (Angular)

var app = angular.module("myApp",[]);

function Fiddle($scope){}

app.directive('input-data', function() {
    return {
        restrict: 'E',
        require: '?ngModel',
        link: function(scope, elm, attr, ctrl) {
            if (!ctrl) {
                return;
            }

            elm.bind('keyup', function () {

                var matches = /^(\d{2})[-\/](\d{2})[-\/](\d{4})$/.exec(this.value);
                if(matches){
                var d = matches[1];
                var m = matches[2] - 1;
                var y = matches[3];

                var composedDate = new Date(y, m, d); 
                var valid = composedDate.getDate() == d &&
                    composedDate.getMonth() == m &&
                    composedDate.getFullYear() == y;
                }

                if(!matches || !valid)
                    elm.attr('style', 'border:solid 3px #FE2E2E');
                else
                    elm.removeAttr('style');
            });
        }
    };
});

var app = angular.module("myApp", []);

function Fiddle($scope) {}

app.directive('input', function() {
  return {
    restrict: 'E',
    require: '?ngModel',
    link: function(scope, elm, attr, ctrl) {
      if (!ctrl) {
        return;
      }


      elm.bind('keyup', function() {

        var matches = /^(\d{2})[-\/](\d{2})[-\/](\d{4})$/.exec(this.value);
        if (matches) {
          var d = matches[1];
          var m = matches[2] - 1;
          var y = matches[3];


          var composedDate = new Date(y, m, d);
          var valid = composedDate.getDate() == d &&
            composedDate.getMonth() == m &&
            composedDate.getFullYear() == y;
        }

        if (!matches || !valid)
          elm.attr('style', 'border:solid 3px #FE2E2E');
        else
          elm.removeAttr('style');
      });
    }
  };
});



function validarData() {
  var valid = isValidDate(document.getElementById("ipData").value);
  document.getElementById("ipData").style.border = (!valid ? 'solid 3px #FE2E2E' : '');
};


function isValidDate(date) {
  var matches = /^(\d{2})[-\/](\d{2})[-\/](\d{4})$/.exec(date);
  if (matches == null) return false;
  var d = matches[2];
  var m = matches[1] - 1;
  var y = matches[3];
  var composedDate = new Date(y, m, d);
  return composedDate.getDate() == d &&
    composedDate.getMonth() == m &&
    composedDate.getFullYear() == y;
}
html,
body {
  height: 100%;
}
body,
form {
  padding: 1em;
}
input,
input.ng-invalid.has-visited.has-focus,
form {
  border: 1px solid #8d8d8d;
}
input,
button {
  border-radius: 3px;
  padding: .25em;
}
body {
  background: #528cc2;
  /* Old browsers */
  background: -moz-linear-gradient(top, #6dbbff 0%, #528cc2 100%);
  /* FF3.6+ */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #6dbbff), color-stop(100%, #528cc2));
  /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(top, #6dbbff 0%, #528cc2 100%);
  /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(top, #6dbbff 0%, #528cc2 100%);
  /* Opera 11.10+ */
  background: -ms-linear-gradient(top, #6dbbff 0%, #528cc2 100%);
  /* IE10+ */
  background: linear-gradient(to bottom, #6dbbff 0%, #528cc2 100%);
  /* W3C */
  filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#6dbbff', endColorstr='#528cc2', GradientType=0);
  /* IE6-9 */
  font-family: sans-serif;
}
ul,
li {
  list-style: none;
}
form {
  background: #f7f7f7;
  /* Old browsers */
  background: -moz-linear-gradient(top, #f7f7f7 0%, #e5e5e5 100%);
  /* FF3.6+ */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f7f7f7), color-stop(100%, #e5e5e5));
  /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(top, #f7f7f7 0%, #e5e5e5 100%);
  /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(top, #f7f7f7 0%, #e5e5e5 100%);
  /* Opera 11.10+ */
  background: -ms-linear-gradient(top, #f7f7f7 0%, #e5e5e5 100%);
  /* IE10+ */
  background: linear-gradient(to bottom, #f7f7f7 0%, #e5e5e5 100%);
  /* W3C */
  filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#f7f7f7', endColorstr='#e5e5e5', GradientType=0);
  /* IE6-9 */
  border: 1px solid #8d8d8d;
  border-radius: 6px;
  box-shadow: 0 3px 5px rgba(0, 0, 0, .3);
  min-width: 400px;
  margin: auto;
  width: 50%;
}
form li {
  margin-bottom: .5em;
}
label {
  color: #8d8d8d;
  display: block;
  line-height: 1.5;
}
:focus {
  outline: 0;
}
input {
  background: rgba(255, 255, 255, .5);
}
input:focus {
  background: #FFF;
}
input.ng-invalid.has-visited {
  border: 1px solid #E44848;
}
input.ng-valid.has-visited {
  border: 1px solid #a3bf57;
}
.error-message {
  color: #E44848;
}
button {
  background: #528CC2;
  color: white;
  cursor: pointer;
  border: 0;
}
button:disabled {
  background: rgba(82, 140, 194, 0.5);
  color: rgba(255, 255, 255, .5);
  font-weight: 400;
}
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<form name="myForm" novalidate ng-app="myApp">
  <ul ng-controller="Fiddle">
    <li>
      <label for="barthirty">Diretiva Angular</label>
      <input input-data type="datetime" ng-model="barthirty" required />

    </li>
  </ul>
  <ul>
    <li>
      <label for="barthirty">Expressao regular</label>
      <input type="datetime" id="ipData" required onkeyup="validarData()"/>
    </li>
  </ul>
  <button type="submit" ng-disabled="myForm.$invalid">Submit</button>
</form>

  • 1

    @It may be that I made a mistake yes. But I don’t know for sure. I apologize...

  • 1

    It happens, nor heats up the head. I think the worst was the approval of the edition, rs.

6

Simple way, using pure javascript:

Try to accomplish a parse dynamic via the manufacturer of Date(). If it works, the date is valid. Example for imperial dates:

var isValidDate = function(str) {
    return !!new Date(str).getTime();
}

Or the Brazilian version:

var isValidDate = function(str) {
    return str == 'dd/mm/yyyy' || 
           ( /^\d{2}\/\d{2}\/\d{4}$/.test(str) && new Date(str).getTime() );
}

For your examples,

isValidDate('31/02/2006'); // false
isValidDate('20/20/9999'); // false

However,

isValidDate('01/31/2006'); //true
isValidDate('01/20/9999'); //true

Executable version below (in Chrome, press F12 before clicking Execute code snippet so you can see the console log):

var isValidDate = function(str) {
    return !!new Date(str).getTime();
}

console.log(isValidDate('31/02/2006'));
console.log(isValidDate('20/20/9999'));

console.log(isValidDate('01/31/2006'));
console.log(isValidDate('01/20/9999'));

5

You can use the jQuery Validation to validate your fields. It is only in English, but has some libraries for translation. An alternative is to use these extensions.

Where you add validation to your form, this way:

$( "#myform" ).validate({
  rules: {
    data: {
      required: true,
      dateBR: true
    }
  }
});

And to translate the validations, you add this method:

jQuery.validator.addMethod("dateBR", function (value, element) {
    //contando chars    
    if (value.length != 10) return (this.optional(element) || false);
    // verificando data
    var data = value;
    var dia = data.substr(0, 2);
    var barra1 = data.substr(2, 1);
    var mes = data.substr(3, 2);
    var barra2 = data.substr(5, 1);
    var ano = data.substr(6, 4);
    if (data.length != 10 || barra1 != "/" || barra2 != "/" || isNaN(dia) || isNaN(mes) || isNaN(ano) || dia > 31 || mes > 12) return (this.optional(element) || false);
    if ((mes == 4 || mes == 6 || mes == 9 || mes == 11) && dia == 31) return (this.optional(element) || false);
    if (mes == 2 && (dia > 29 || (dia == 29 && ano % 4 != 0))) return (this.optional(element) || false);
    if (ano < 1900) return (this.optional(element) || false);
    return (this.optional(element) || true);
}, "Informe uma data válida"); 

This way you will be validating dates greater than 1900. Remembering that it is necessary to separate by /. But the mask I believe you’re already doing.

For your example, it would look like this:

<html><head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title> - Validade Example</title>
  <script type="text/javascript" src="//code.jquery.com/jquery-2.1.0.js"></script>
  <script type="text/javascript" src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
  <link rel="stylesheet" type="text/css" href="/css/result-light.css">
      <script type="text/javascript" src="http://jqueryvalidation.org/files/dist/jquery.validate.min.js"></script><style type="text/css"></style>
    
<body>
  <form id="myform" novalidate="novalidate">
<label for="data">Data: </label>
<input class="left" id="data" name="data">
<br>
<input type="submit" value="Validate!">
</form>
    
    <script>
// just for the demos, avoids form submit
jQuery.validator.setDefaults({
  debug: true,
  success: "valid"
});
      jQuery.validator.addMethod("dateBR", function (value, element) {
    //contando chars    
    if (value.length != 10) return (this.optional(element) || false);
    // verificando data
    var data = value;
    var dia = data.substr(0, 2);
    var barra1 = data.substr(2, 1);
    var mes = data.substr(3, 2);
    var barra2 = data.substr(5, 1);
    var ano = data.substr(6, 4);
    if (data.length != 10 || barra1 != "/" || barra2 != "/" || isNaN(dia) || isNaN(mes) || isNaN(ano) || dia > 31 || mes > 12) return (this.optional(element) || false);
    if ((mes == 4 || mes == 6 || mes == 9 || mes == 11) && dia == 31) return (this.optional(element) || false);
    if (mes == 2 && (dia > 29 || (dia == 29 && ano % 4 != 0))) return (this.optional(element) || false);
    if (ano < 1900) return (this.optional(element) || false);
    return (this.optional(element) || true);
}, "Informe uma data válida"); 
                   
$( "#myform" ).validate({
  rules: {
    data: {
      required: true,
      dateBR: true
    }
  }
});
</script>

</body></html>

Jsfiddle example

  • Would it be possible to use this scheme as a function? Validated typeData(date) and it returns true or false, This method became excellent

4

The angular does not offer any kind of function to validate dates, at least not that I know of, but there are several directives that take care of this.

Alternatively, there is the javascript library Moment.js (http://momentjs.com/) which offers a range of methods for working with dates.

Also, you can use some datepicker lib as recalled by @Techies, follow the example of angular directive provided by it: http://720kb.github.io/angular-datepicker/ or the Jquery-UI datepicker: https://jqueryui.com/datepicker/

  • There is no jquery?

  • 2

    I was in doubt was what you meant by "in jquery" that it is nothing more than a javascript lib. There is http://jqueryvalidation.org/ that has some date functions, but I can’t tell you if it’s good.

  • I was seeing her now, but I still haven’t been able to implement.

  • No stackoverflow in English have some examples. http://stackoverflow.com/questions/511439/custom-date-format-with-jquery-validation-plugin

  • 1

    I recommend using some library or a datepicker so you won’t have "problem" with date validation.

  • Here is an example: http://720kb.github.io/angular-datepicker/

Show 1 more comment

3


I’ll give you a code that I use here in pure javascript, this little monster validates everything will solve your problem:

        function validateDate(id) {
      var RegExPattern = /^((((0?[1-9]|[12]\d|3[01])[\.\-\/](0?[13578]|1[02])      [\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|[12]\d|30)[\.\-\/](0?[13456789]|1[012])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|1\d|2[0-8])[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|(29[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00)))|(((0[1-9]|[12]\d|3[01])(0[13578]|1[02])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|[12]\d|30)(0[13456789]|1[012])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|1\d|2[0-8])02((1[6-9]|[2-9]\d)?\d{2}))|(2902((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00))))$/;

     if (!((id.value.match(RegExPattern)) && (id.value!=''))) {
          alert('Data inválida.');
   id.focus();
        }
       else
        alert('Data válidaa.');
    }
  • It worked!! was what fit better here, thank you.

  • Here with me it does not work with day 31 of any month

  • Exactly. Does not validate days 31 nor leap year.

1

Follow the function to validate dates in javascript.

if(validateDate("10/01/1985"))
    console.log("OK");
else
    console.log("ERRO");

function validateDate(data) {
        // Ex: 10/01/1985
        var regex = "\\d{2}/\\d{2}/\\d{4}";
        var dtArray = data.split("/");

        if (dtArray == null)
            return false;

        // Checks for dd/mm/yyyy format.
        var dtDay= dtArray[0];
        var dtMonth = dtArray[1];
        var dtYear = dtArray[2];

        if (dtMonth < 1 || dtMonth > 12)
            return false;
        else if (dtDay < 1 || dtDay> 31)
            return false;
        else if ((dtMonth==4 || dtMonth==6 || dtMonth==9 || dtMonth==11) && dtDay ==31)
            return false;
        else if (dtMonth == 2)
        {
            var isleap = (dtYear % 4 == 0 && (dtYear % 100 != 0 || dtYear % 400 == 0));
            if (dtDay> 29 || (dtDay ==29 && !isleap))
                return false;
        }
        return true;
    }

Browser other questions tagged

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