Check date is correct + regex Angular4 - html

I have a form in Angular4, with 2 dates: started, finished.
I want to check that the format date is dd/mm/yyyy.
I wrote:
<input pattern="((0)*[1-9]|[1-2][0-9]|(3)[0-1])(\/)(((0)*[1-9])|((1)[0-2]))(\/)\d{4}$" [(ngModel)]="filterDateStart" class="form-control" type="date" id="filterDateStart" name="filterDateStart" clrDate>
<input pattern="((0)*[1-9]|[1-2][0-9]|(3)[0-1])(\/)(((0)*[1-9])|((1)[0-2]))(\/)\d{4}$" [(ngModel)]="filterDateEnd" class="form-control" type="date" id="filterDateEnd" name="filterDateEnd" clrDate>
Then when I write invalid dates , my html doesn't say anything... I can send this form.
Then I need to check these dates.
1º Date start < date end
2º Ranges valid -> (30/20/2018) or (32/12/2018)
I see the library moment.js, but my boss says that I don't should be it. thanks, sorry for my english.

Don't use regexes, rely on the Date API :
const valid = '12/12/2018';
const invalid1 = '12/12';
const invalid2 = '12.12.2018';
const invalid3 = 'foo';
function parseDate(date) {
try {
// Make your business logic here. Examples : all must be defined and numbers, and separated with a /
const [d, m, y] = date.split('/');
if (!d || !m || !y) throw new Error();
if(isNaN(d) || isNaN(m) || isNaN(y)) throw new Error();
return new Date(y, m, d);
} catch(err) {
return 'Invalid date';
}
}
console.log(parseDate(valid));
console.log(parseDate(invalid1));
console.log(parseDate(invalid2));
console.log(parseDate(invalid3));
With that you can create a custom validator, that will be a lot more explicit than using a pattern.

Related

using .replace in gmail to spreadsheet function. Is there anyway to replace everything EXCEPT a selection that matches a pattern? [duplicate]

This question already has answers here:
What is the best regular expression to check if a string is a valid URL?
(62 answers)
Closed 8 years ago.
Currently I have an input box which will detect the URL and parse the data.
So right now, I am using:
var urlR = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)
(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
var url= content.match(urlR);
The problem is, when I enter a URL like www.google.com, its not working. when I entered http://www.google.com, it is working.
I am not very fluent in regular expressions. Can anyone help me?
Regex if you want to ensure URL starts with HTTP/HTTPS:
https?:\/\/(www\.)?[-a-zA-Z0-9#:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()#:%_\+.~#?&//=]*)
If you do not require HTTP protocol:
[-a-zA-Z0-9#:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()#:%_\+.~#?&//=]*)
To try this out see http://regexr.com?37i6s, or for a version which is less restrictive http://regexr.com/3e6m0.
Example JavaScript implementation:
var expression = /[-a-zA-Z0-9#:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()#:%_\+.~#?&//=]*)?/gi;
var regex = new RegExp(expression);
var t = 'www.google.com';
if (t.match(regex)) {
alert("Successful match");
} else {
alert("No match");
}
(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})
Will match the following cases
http://www.foufos.gr
https://www.foufos.gr
http://foufos.gr
http://www.foufos.gr/kino
http://werer.gr
www.foufos.gr
www.mp3.com
www.t.co
http://t.co
http://www.t.co
https://www.t.co
www.aa.com
http://aa.com
http://www.aa.com
https://www.aa.com
Will NOT match the following
www.foufos
www.foufos-.gr
www.-foufos.gr
foufos.gr
http://www.foufos
http://foufos
www.mp3#.com
var expression = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi;
var regex = new RegExp(expression);
var check = [
'http://www.foufos.gr',
'https://www.foufos.gr',
'http://foufos.gr',
'http://www.foufos.gr/kino',
'http://werer.gr',
'www.foufos.gr',
'www.mp3.com',
'www.t.co',
'http://t.co',
'http://www.t.co',
'https://www.t.co',
'www.aa.com',
'http://aa.com',
'http://www.aa.com',
'https://www.aa.com',
'www.foufos',
'www.foufos-.gr',
'www.-foufos.gr',
'foufos.gr',
'http://www.foufos',
'http://foufos',
'www.mp3#.com'
];
check.forEach(function(entry) {
if (entry.match(regex)) {
$("#output").append( "<div >Success: " + entry + "</div>" );
} else {
$("#output").append( "<div>Fail: " + entry + "</div>" );
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="output"></div>
Check it in rubular - NEW version
Check it in rubular - old version
These are the droids you're looking for. This is taken from validator.js which is the library you should really use to do this. But if you want to roll your own, who am I to stop you? If you want pure regex then you can just take out the length check. I think it's a good idea to test the length of the URL though if you really want to determine compliance with the spec.
function isURL(str) {
var urlRegex = '^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?#)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$';
var url = new RegExp(urlRegex, 'i');
return str.length < 2083 && url.test(str);
}
Test:
function isURL(str) {
var urlRegex = '^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?#)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$';
var url = new RegExp(urlRegex, 'i');
return str.length < 2083 && url.test(str);
}
var check = [
'http://www.foufos.gr',
'https://www.foufos.gr',
'http://foufos.gr',
'http://www.foufos.gr/kino',
'http://werer.gr',
'www.foufos.gr',
'www.mp3.com',
'www.t.co',
'http://t.co',
'http://www.t.co',
'https://www.t.co',
'www.aa.com',
'http://aa.com',
'http://www.aa.com',
'https://www.aa.com',
'www.foufos',
'www.foufos-.gr',
'www.-foufos.gr',
'foufos.gr',
'http://www.foufos',
'http://foufos',
'www.mp3#.com'
];
for (let index = 0; index < check.length; index++) {
var url=check[index]
if (isURL(check[index]))
console.log(`${url} ✔`);
else{
console.log(`${url} ❌`);
}
}
Result
Another possible solution, above solution failed for me in parsing query string params.
var regex = new RegExp("^(http[s]?:\\/\\/(www\\.)?|ftp:\\/\\/(www\\.)?|www\\.){1}([0-9A-Za-z-\\.#:%_\+~#=]+)+((\\.[a-zA-Z]{2,3})+)(/(.)*)?(\\?(.)*)?");
if(regex.test("http://google.com")){
alert("Successful match");
}else{
alert("No match");
}
In this solution please feel free to modify [-0-9A-Za-z\.#:%_\+~#=, to match the domain/sub domain name. In this solution query string parameters are also taken care.
If you are not using RegEx, then from the expression replace \\ by \.
Hope this helps.
Test:-
function IsUrl(url){
var regex = new RegExp("^(http[s]?:\\/\\/(www\\.)?|ftp:\\/\\/(www\\.)?|www\\.){1}([0-9A-Za-z-\\.#:%_\+~#=]+)+((\\.[a-zA-Z]{2,3})+)(/(.)*)?(\\?(.)*)?");
if(regex.test(url)){
console.log(`${url} ✔`);
}else{
console.log(`${url} ❌`);
}}
var check = [
'http://www.foufos.gr',
'https://www.foufos.gr',
'http://foufos.gr',
'http://www.foufos.gr/kino',
'http://werer.gr',
'www.foufos.gr',
'www.mp3.com',
'www.t.co',
'http://t.co',
'http://www.t.co',
'https://www.t.co',
'www.aa.com',
'http://aa.com',
'http://www.aa.com',
'https://www.aa.com',
'www.foufos',
'www.foufos-.gr',
'www.-foufos.gr',
'foufos.gr',
'http://www.foufos',
'http://foufos',
'www.mp3#.com'
];
for (let index = 0; index < check.length; index++) {
IsUrl(check[index])
}
Result
I was trying to put together some JavaScript to validate a domain name (ex. google.com) and if it validates enable a submit button. I thought that I would share my code for those who are looking to accomplish something similar. It expects a domain without any http:// or www. value. The script uses a stripped down regular expression from above for domain matching, which isn't strict about fake TLD.
http://jsfiddle.net/nMVDS/1/
$(function () {
$('#whitelist_add').keyup(function () {
if ($(this).val() == '') { //Check to see if there is any text entered
//If there is no text within the input, disable the button
$('.whitelistCheck').attr('disabled', 'disabled');
} else {
// Domain name regular expression
var regex = new RegExp("^([0-9A-Za-z-\\.#:%_\+~#=]+)+((\\.[a-zA-Z]{2,3})+)(/(.)*)?(\\?(.)*)?");
if (regex.test($(this).val())) {
// Domain looks OK
//alert("Successful match");
$('.whitelistCheck').removeAttr('disabled');
} else {
// Domain is NOT OK
//alert("No match");
$('.whitelistCheck').attr('disabled', 'disabled');
}
}
});
});
HTML FORM:
<form action="domain_management.php" method="get">
<input type="text" name="whitelist_add" id="whitelist_add" placeholder="domain.com">
<button type="submit" class="btn btn-success whitelistCheck" disabled='disabled'>Add to Whitelist</button>
</form>

Comparing 2 strings from HTML file - Angular

I am using angular 7 and I would like to know how to compare two strings. In this case, each of my strings simulates one date, let's say "2019-12-26" and "2018-12-26".
In Javascript is pretty simple to compare them since I just need to use the operators:
console.log(today > "2018-12-06");
It is working how I supposed it was gonna work. It basically returns true. Nevertheless, I am trying to do exactly the same from my HTML file
<div *ngIf="today > example.endDate">
being today and 'example.endDate' two strings containing exactly the same strings that I used for the Javascript example, but it does not show any of them.
Is there any other way to make this comparison?
Regards,
Mario
UPDATE
I have had a second look at the problem and it seems that the comparison is not a problem, but the way of getting the variable is.
I get a variable in ngOnInit().
ngOnInit() {
this.getCurrentDate();
}
//Get current date
getCurrentDate() {
let aux = new Date();
//2 characteres
let dd = String(aux.getDate()).padStart(2, "0");
let mm = String(aux.getMonth() + 1).padStart(2, "0"); //January is 0!
let yyyy = aux.getFullYear();
let today = yyyy + "-" + mm + "-" + dd;
let other = "2019-01-31";
}
The problem is that I use this variable directly in my HTML how I previously showed. The error I get is the following:
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression
has changed after it was checked. Previous value: 'ngIf: undefined'.
Current value: 'ngIf: true'.
So the problem is that I am using a variable in the HTML file before getting the value. Or at least it is what I understand
To check this error I have created a Stackblitz representation. On it, I have created two examples:
Variables not on ngOnInit()
Variables in ngOnInit()
https://stackblitz.com/edit/angular-jjgsmq?file=src%2Fapp%2Fhello.component.ts
the most simple solution is just to
and are you sure that ngOnInit is the right LifeCycle hook for you?
I would try ngAfterContentInit() if the component is "heavy" to render other wise ngAfterViewInit() would have been my choice
<div *ngIf="IsTodayBigger()">
ngOnInit() {
this.getCurrentDate();
}
IsTodayBigger(): boolean {
today=this.getCurrentDate()
exampleEndDate= example.endDate;//use binding or ViewChild if needed
return today&&exampleEndDate&& today> example.endDate
}
//Get current date
getCurrentDate() {
let aux = new Date();
//2 characteres
let dd = String(aux.getDate()).padStart(2, "0");
let mm = String(aux.getMonth() + 1).padStart(2, "0"); //January is 0!
let yyyy = aux.getFullYear();
today = yyyy + "-" + mm + "-" + dd;
let other = "2019-01-31";
}

How to filter or custom filter array of objects based on matching values from another object

I implemented an advance search with 15 input fields in AngularJS.
In the page load itself the result set is return from database in JSON format and i need to do the filter in client side only.
The input criteria's equivalent column is available in the result set and i need to check in its respective column only.
I am converting each column by JSON.stringify() and check with the search params like the below :
$scope.filteredData = $scope.actualData.filter(function(item) {
return JSON.stringify(item.FirstName).toLowerCase().indexOf(lowerFirstName) != -1 &&
JSON.stringify(item.LastName).toLowerCase().indexOf(lowerLastName) != -1 &&
JSON.stringify(item.EmailAddress).toLowerCase().indexOf(lowerEmailAddress) != -1 &&
JSON.stringify(item.Address1).toLowerCase().indexOf(lowerAddress1) != -1 &&
JSON.stringify(item.Address2).toLowerCase().indexOf(lowerAddress2) != -1;
...... etc // upto 15 fields
});
Since i have the 15 input fields and the actual result set contains a minimum of 50,000 records.
So converting each record's each column by JSON.stringify() and check with search params will surely cause the performance issue.
Is there any other way to achieve the filtering in client side with other approach.
I posted a sample code in Plunker with 5 input fields only : http://plnkr.co/edit/nUWZEbGvz7HG6gb91YZP
sylwester's answer is the normal way you'd filter things. Your code looks like you want to filter down to only the object that matches every input field. You code attempts to find an object where every property matches the searchParams object. At that point, I don't see what benefit there is to finding that object, because the user already created the object again! Nonetheless, here's a proper version of your code:
Live demo here.
<div ng-repeat="data in actualData | filter:searchData()">
$scope.searchData = function() {
return function(item) {
return Object.keys(item).every(function(key) {
// skip the $$hashKey property Angular adds to objects
if (key === '$$hashKey') { return true; }
var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
return item[key].toLowerCase() === $scope.searchParams[searchKey].toLowerCase();
});
};
};
You really need to limit the data coming from the server for the browser's sake and for the server's sake. It's easy to implement a LIMIT, OFFSET system. It sounds like, overall, you just need to be able to query the server for a certain record.
From your comments, it seems you definitely want Angular's built in filter filter:searchParams, and just capitalize your searchParams models to match your data. For fun, I'll include more options for finer tuning.
This one almost mimics filter:searchParams. You can change > 1 to adjust when the partial matching kicks in, or have it return true only when both items are strictly equal === to disable partial matching. The difference here is that all items are hidden until matched, whereas filter:searchParams will show all items and then remove what doesn't match.
Live demo here.
$scope.searchData = function() {
return function(item) {
return Object.keys(item).some(function(key) {
if (key === '$$hashKey') { return false; }
var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
var currentVal = $scope.searchParams[searchKey].toLowerCase();
var match = item[key].toLowerCase().match(currentVal);
return currentVal.length > 1 && match;
});
};
};
Lastly, to perfectly mimic filter:searchParams, you'd just put in a check to NOT filter the items until there is user input and the input is long enough to start the partial match.
Live demo here.
$scope.searchData = function() {
var partialMatchLength = 2;
return function(item) {
var shouldFilter = Object.keys($scope.searchParams).some(function(key) {
return $scope.searchParams[key] && $scope.searchParams[key].length >= partialMatchLength;
});
if (!shouldFilter) { return true; }
return Object.keys(item).some(function(key) {
if (key === '$$hashKey') { return false; }
var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
var currentVal = $scope.searchParams[searchKey].toLowerCase();
var match = item[key].toLowerCase().match(currentVal);
return currentVal.length >= partialMatchLength && match;
});
};
};
First of all you ng-repeter with 50.000 records more likely is going to kill your browser, so you should thing about pagination.
Secondly you can easy filter your data using angular filter please see that demo
http://plnkr.co/edit/R8b8G4xCMSQmX1144UJG?p=preview
<div ng-controller="ListCtrl">
<br />
First Name:
<input type="text" id="txtFirstname" ng-model="searchParams.FirstName">
<br/>Last Name:
<input type="text" id="txtLastname" ng-model="searchParams.LastName">
<br/>Email Address:
<input type="text" id="txtEmailAddress" ng-model="searchParams.EmailAddress">
<br/>Address 1:
<input type="text" id="txtAddress1" ng-model="searchParams.Address1">
<br/>Address 2:
<input type="text" id="txtAddress2" ng-model="searchParams.Address2">
<br/>
<button class="btn btn-primary" ng-click="searchData()">Search</button>
<br />
<hr />
<b>Filtered Data(s):</b>
<div ng-repeat="data in actualData | filter:searchParams ">
<span ng-bind="data.FirstName"></span>
<span ng-bind="data.LastName"></span> |
Address : {{data.Address1}}
</div>
<hr />
</div>

HTML5 Time Element in Form with Milliseconds

There are several examples of HTML5 form options on this page, including the "time" element. Is it possible to force the time element to include a millisecond component?
I'm not concerned for the fallback option where a plain text box is used.
This works:
<input type="time" step="0.001"></input>
Live preview: http://jsbin.com/giqikelumu/edit?html,output
Simply use the step attribute. In case of a input type="time". The step attribute defaults to 60 (1 means 1 second). But you can also set fractions.
<input type="time" step="any" />
As its an input tag, the value can be entered into it by the user then using the step attribute as stated above will surely help.
What if this input is in the form and value can come from some API cal and is given to the form to show it. It can be changed too. If the requirement then is to show or not show the second or millisecond part we can do the following.
When second and millisecond is required
getFormatDate = function (val) { // assuming val is date like "/Date(946673340000)/"
if (val != undefined) {
date = new Date(val.match(/\d+/)[0] * 1); // creating a date object from val
return new Date(date.getFullYear(), date.getMonth(), date.getDate(),
date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
}
}
When second and millisecond is NOT required
getFormatDate = function (val) { // assuming val is date like "/Date(946673340000)/"
if (val != undefined) {
date = new Date(val.match(/\d+/)[0] * 1); // creating a date object from val
return new Date(date.getFullYear(), date.getMonth(), date.getDate(),
date.getHours(), date.getMinutes());
}
}

How do I input date in forms with xhtml or html4?

well I know it's easier on html5, but I have to use html4 or xhtml and I can't find any info without html5 somehow. Can anyone help and explain me how I can input a date?
<input type="text" name ="sometext">
The normal html4 or xhtml doesn't seem to have the type date as the type of input.
Thanks in advance.
This question has been asked & answered on some other StackOverflow threads, but as I'm hitting the same problem, here's more info.
Using the jQuery DatePicker is a good start, but it does not enforce format or min/max value integrity outside of the actual calendar popup. Meaning, you can type or paste some bad stuff.
Here's 2 links to sites that demo how to do it the "old way" in JS with a function:
http://www.javascriptkit.com/script/script2/validatedate.shtml
http://www.w3resource.com/javascript/form/javascript-date-validation.php
And here's a StackOverflow link to another pretty nice way to do it:
Detecting an "invalid date" Date instance in JavaScript
Personally, I need validation and restriction to min and max date ranges (SQL hates dates before 1/1/1773 and somebody tried that in my app). I'm going to wire up a function that tells me if a date string is valid, and then wire that up to the input's onchange event.
Here's the HTML for mine:
I'm also using ASP.NET and jQuery's DatePicker, so the key element for folks is the onblur event.
Here's the JS for the FixValidDate() function:
var availableDateFormats = ["mmddyyyy","mm/dd/yyyy","mm-dd-yyyy","yyyy/mm/dd","yyyy-mm-dd"];
function FixValidDate(txtDate,nulls, minDate, maxDate) {
//debugger;
formats =
{
'mmddyyyy':{
're':/^(\d{1,2})(\d{1,2})(\d{4})$/,
'month': 1,'day': 2, year: 3
},
'mm/dd/yyyy':{
're':/^(\d{1,2})[/](\d{1,2})[/](\d{4})$/,
'month': 1,'day': 2, year: 3
},
'mm-dd-yyyy':{
're':/^(\d{1,2})[-](\d{1,2})[-](\d{4})$/,
'month': 1,'day': 2, year: 3
},
'yyyy/mm/dd':{
're':/^(\d{4})[/](\d{1,2})[/](\d{1,2})$/,
'month': 2,'day': 3, year: 1
},
'yyyy-mm-dd':{
're':/^(\d{4})[-](\d{1,2})[-](\d{1,2})$/,
'month': 2,'day': 3, year: 1
}
}
dateText = txtDate.value;
matched = false;
for(i=0; i<availableDateFormats.length; i++)
{
f = formats[availableDateFormats[i]];
match = dateText.match(f.re);
if(match)
{
matched = true;
month = match[f.month];
day = match[f.day];
year = match[f.year];
//TODO validate if the numbers make sense
txtDate.value = month+"/"+day+"/"+year;
}
}
if (!matched && nulls) {
txtDate.value = "";
return false;
} else {
var timestamp = Date.parse(txtDate.value);
if (isNaN(timestamp) == false) {
var d = new Date(timestamp);
if (minDate != null) {
if (d < minDate) {
txtDate.value = "";
return false;
}
}
if (maxDate != null) {
if (d > maxDate) {
txtDate.value = "";
return false;
}
}
} else {
txtDate.value = "";
return false;
}
}
return true;
}
This is from an old library I've used for JS stuff for about a decade. You could easily find another JS validation function and swap mine out.
In my function, I required to accept a variety of date formats, and if it's a bad format, I blank out the field and keep the user in the same box. You could change that up.
HTML4 doesn't have any tags to input date by default.All you need to do is include third party library like JQUERY.
Checkout this example http://jqueryui.com/datepicker/
The basic input element is all that HTML (other than HTML5) has. You should have a label, with associated markup, for all text input. Normally you should also include information about the expected input format, as this varies by language and culture, e.g.
<label for="birth">Date of birth (day/month year):</label>
<input id="birth" type="text" name="birth" size="10">
You should also pre-check the user input client-side, with JavaScript, to give the user fast response in case of data error. Naturally, the checks should be duplicated server-side.