Datapickers cmp with today to exe jQuery code - html

I have created this code:
<div class="option">
<label for="date">Date de debut de reservation</label>
<input type="date" id="datepickerFrom" ui-date="dateOptionsFrom" ng-model="datepickerFrom" class="form-control ng-empty hasDatepicker ng-touched ng-dirty ng-valid-parse ng-invalid ng-invalid-ui-date-validator" name="datepickersFrom" placeholder="dd/mm/yyyy" min="<?php echo $today; ?>" required>
<script>
var today = new Date().toISOString().split('T')[0];
document.getElementsByName("datepickersFrom")[0].setAttribute('min', today);
</script>
</div>
I want to compare the date selected with date of today.
If it is the case that today's day is selected I would like to run this code below:
$("#exptype").append('<option value="fast" selected>Ultra-express 1 heure</option>');
otherwise if today's date is not selected, I would like to execute this code:
$("#exptype").append('<option value="stand">Livraison standard 24-48h</option>');
How can I do that?

You are using angular, right? I presume this given that you have the ng-model attribute set on your date input. If that is the case, you can use the angular controller to handle this - see example below.
Also, presuming you are using angular, then you could look at using the angular date picker controls for a richer/more robust UI control...
angular.module('myApp',[]).controller('dateController',function($scope) {
var today = new Date().toISOString().split('T')[0];
$scope.datepickerFrom = today;
$scope.todaySelected = true;
//this replaces that line you had:
//document.getElementsByName("datepickersFrom")[0].setAttribute('min', today);
$scope.minDate = today;
//when the date changes, store a boolean in our controller scope, to be used in the filter function below
$scope.dateChanged = function() {
$scope.todaySelected = ($scope.datepickerFrom == today);
};
//define our options - please adjust for your needs
$scope.expTypeOptions = [
{ value: "four hours", text: "4 heure" },
{ value: "fast", text: "Ultra-express 1 heure" },
{ value: "stand", text: "Livraison standard 24-48h" },
];
//this function handles showing the expType options in the select list,
//based on the selected date
$scope.filterOptionsByDate = function(expType) {
if ($scope.todaySelected) { //hide the 'stand' option
return expType.value != "stand";
}
else { //otherwise show everything except the 'fast' option
return expType.value != "fast";
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="option" ng-app="myApp" ng-controller="dateController">
<label for="date">Date de debut de reservation</label>
<input type="date" id="datepickerFrom" ui-date="dateOptionsFrom" ng-model="datepickerFrom" class="form-control ng-empty hasDatepicker ng-touched ng-dirty ng-valid-parse ng-invalid ng-invalid-ui-date-validator" min="{{ minDate }}" ng-change="dateChanged()" name="datepickersFrom" placeholder="dd/mm/yyyy" required >
<div>
<select ng-model="expType" ng-options="expType.text for expType in expTypeOptions | filter:filterOptionsByDate">
</select>
</div>

Related

How to restrict end date before start date after selected start date in React.JS or in html input type=date""

function App() {
let [account, setAccount] = React.useState({
startdate: "",
enddate: "",
reason: "",
leavetype: "",
});
function handleChange(e) {
let name = e.target.name;
let value = e.target.value;
account[name] = value;
setAccount(account);
}
function Submit(e) {
e.preventDefault();
console.log(account);
}
return (
<div>
<fieldset>
<form className="" method="post" onSubmit={Submit}>
Start Date:
<input
type="date"
name="startdate"
min={new Date().toISOString().split("T")[0]}
onChange={handleChange}
required
/>
End Date:
<input
type="date"
name="enddate"
// min={}
onChange={handleChange}
required
/>
</form>
</fieldset>
</div>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
You need to use the state that you have.
function App() {
const [account, setAccount] = React.useState({
startdate: "",
enddate: "",
reason: "",
leavetype: "",
});
function handleChange(e) {
const name = e.target.name;
const value = e.target.value;
// treat state as immutable!
// you need to creaet a new object here
// See https://stackoverflow.com/a/25333702/17487348 for how to create a property from a string in ES6
setAccount({...account, [name]: value});
}
function Submit(e) {
e.preventDefault();
console.log(account);
}
return (
<div>
<fieldset>
<form className="" method="post" onSubmit={Submit}>
<legend>Your trip</legend>
<label for="startdate">Start Date:</label>
<input
type="date"
name="startdate"
min={new Date().toISOString().split("T")[0]}
onChange={handleChange}
required
/>
<label for="enddate">End Date:</label>
<input
type="date"
name="enddate"
disabled={account.startdate === "" ? true: false}
min={account.startdate ? new Date(account.startdate).toISOString().split("T")[0]: ""}
onChange={handleChange}
required
/>
</form>
</fieldset>
</div>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
When you look at the code there are some other changes which you should consider.
I would disable the end date date picker as long as there is no start date selected or set sensible default values for start end end date (e.g. today for both) and set those when defining the state.
More important: You should treat state as immutable that means you need to create a new object every time the state changes as React only does a shallow comparison. Otherwise the component won't re-render. So use setAccount({...account, [name]: value}); to update your state. You need to use [] here so the variable content is interpreted as the name of the property. See this thread.
You also probably want to use <label> and maybe <legend>. See the MDN docs for <fieldset>.
For more options to control the datepicker see MDN docs for <input type="date">.

HTML FORM- validate one field against another field value at browser (client) level

I have two DATE fields in a standard HTML form (startdate) and (enddate)
<form method="POST" action="processform.php" target="_top">
<span>▶</span><select class="selectdate" name="startdate" required>
<option value='2019-12-31'>Tue, 31-Dec-19</option><option value='2019-12-30'>Mon, 30-Dec-19</option><option value='2019-12-27'>Fri, 27-Dec-19</option><option value='2019-12-26'>Thu, 26-Dec-19</option><option value='2019-12-24'>Tue, 24-Dec-19</option><option value='2019-12-23'>Mon, 23-Dec-19</option><option value='2019-12-20'>Fri, 20-Dec-19</option><option value='2019-12-19'>Thu, 19-Dec-19</option><option value='2019-12-18'>Wed, 18-Dec-19</option><option value='2019-12-17'>Tue, 17-Dec-19</option><option value='2019-12-16'>Mon, 16-Dec-19</option><option value='2019-12-13'>Fri, 13-Dec-19</option><option value='2019-12-12'>Thu, 12-Dec-19</option><option value='2019-12-11'>Wed, 11-Dec-19</option><option value='2019-12-10'>Tue, 10-Dec-19</option><option value='2019-12-09'>Mon, 09-Dec-19</option><option value='2019-12-06'>Fri, 06-Dec-19</option><option value='2019-12-05'>Thu, 05-Dec-19</option><option value='2019-12-04'>Wed, 04-Dec-19</option><option value='2019-12-03'>Tue, 03-Dec-19</option><option value='2019-12-02'>Mon, 02-Dec-19</option><option value='2019-11-29'>Fri, 29-Nov-19</option> </select>
<span>▶</span><select name="enddate" required>
<option value='2020-01-03'>Fri, 03Jan20</option><option value='2020-01-10'>Fri, 10Jan20</option><option value='2020-01-17'>Fri, 17Jan20</option><option value='2020-01-24'>Fri, 24Jan20</option><option value='2020-01-31'>Fri, 31Jan20</option><option value='2020-02-07'>Fri, 07Feb20</option><option value='2020-03-13'>Fri, 13Mar20</option><option value='2020-03-20'>Fri, 20Mar20</option><option value='2020-03-27'>Fri, 27Mar20</option><option value='2020-04-03'>Fri, 03Apr20</option><option value='2020-04-09'>Thu, 09Apr20</option><option value='2020-06-12'>Fri, 12Jun20</option><option value='2020-06-19'>Fri, 19Jun20</option><option value='2020-06-26'>Fri, 26Jun20</option><option value='2020-07-02'>Thu, 02Jul20</option><option value='2020-07-09'>Thu, 09Jul20</option><option value='2020-12-11'>Fri, 11Dec20</option><option value='2020-12-18'>Fri, 18Dec20</option><option value='2020-12-24'>Thu, 24Dec20</option><option value='2020-12-30'>Wed, 30Dec20</option><option value='2021-01-07'>Thu, 07Jan21</option> </select>
<input type="submit" value="Submit">
</form>
All I wish is to check if the user selected startdate must be less than the selected enddate at the BROWSER level (not at the server).
If selected startdate is greater than or equal to the selected enddate, it should show an error without actually submitting the form. The form should be submitted only if the startdate is less than the enddate.
While I was able to get it working on the server side using PHP, I am unable to make it work at the browser level (possibly javascript which I am not very conversant with).
Any inputs on how this can be achieved?
This is the code I am trying but it is showing "valid date range" for all cases:
const first = document.getElementsByName('startdate')[0];
first.addEventListener('change', function() {
console.log(first.value);
});
const second = document.getElementsByName('enddate')[0];
second.addEventListener('change', function() {
console.log(second.value);
});
if (first.valueOf() > second.valueOf()) {
alert("date is not in valid range");
}else{
alert("date is in valid range");
return true;
}
Thanks
You'll have to use JavaScript for any client-side validations. You can make the PHP call from the JavaScript side.
You can validate date in JavaScript like:
(from here)
function validation(form) {
var v2 = document.getElementById('v2'),
date = new Date(v2.value),
d1 = date.getTime(),
d2 = new Date('12/12/2012').getTime(),
d3 = new Date('1/1/2013').getTime();
if (d1 > d2 || d1 < d3) {
return true;
}else{
alert("date is not in valid range")
}
}
It might seem like a complicated task, but you can actually divide it into more manageable chunks:
Listen to changes in the form fields' values.
Validate the new values, then either allow them or do something else (i.e. show an error message).
For (1) I'd suggest you use JS. For example:
const first = document.getElementsByName('startdate')[0];
first.addEventListener('change', function() {
console.log(first.value);
});
const second = document.getElementsByName('enddate')[0];
second.addEventListener('change', function() {
console.log(second.value);
});
<form method="POST" action="processform.php" target="_top">
<span>▶</span>
<select class="selectdate" name="startdate" required>
<option value='2019-12-31'>Tue, 31-Dec-19</option>
<option value='2019-12-30'>Mon, 30-Dec-19</option>
</select>
<span>▶</span>
<select name="enddate" required>
<option value='2020-01-03'>Fri, 03Jan20</option>
<option value='2020-01-10'>Fri, 10Jan20</option>
</select>
<input type="submit" value="Submit">
</form>
And then you can take it further and use the listeners' functions to actually compare the two dates.
As a side note, I also encourage you to use JS in order to produce those (too) similar <option> tags. Something like this:
const startDateElement = document.getElementsByName('startdate')[0];
const startDates = ['2019-12-31', '2019-12-30', '2019-12-27']; // etc.
startDates.forEach((date) => {
const newOption = document.createElement('option');
newOption.setAttribute('value', date);
newOption.innerHTML = date;
startDateElement.appendChild(newOption);
});
// And the same for end date
<form method="POST" action="processform.php" target="_top">
<span>▶</span>
<select class="selectdate" name="startdate" required>
</select>
</form>
Then your code will be much more generic, hence easier to read, maintain and update in the future.
The functionality helps to track the user selection from start date and time to the end date and time on the client side. PHP will evaluate on the server side (Not preferable)
The user may not be able to select the end date previous of the start date.
Here is the link given below with example
DEMO - https://jsfiddle.net/ssuryar/vr1zd8ep/
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/e8bddc60e73c1ec2475f827be36e1957af72e2ea/build/css/bootstrap-datetimepicker.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment-with-locales.js"></script>
<script src="https://cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/e8bddc60e73c1ec2475f827be36e1957af72e2ea/src/js/bootstrap-datetimepicker.js"></script>
</head>
<div class="container">
<div class='col-md-5'>
<div class="form-group">
<div class='input-group date' id='datetimepicker6'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<div class='col-md-5'>
<div class="form-group">
<div class='input-group date' id='datetimepicker7'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker6').datetimepicker();
$('#datetimepicker7').datetimepicker({
useCurrent: false //Important! See issue #1075
});
$("#datetimepicker6").on("dp.change", function (e) {
$('#datetimepicker7').data("DateTimePicker").minDate(e.date);
});
$("#datetimepicker7").on("dp.change", function (e) {
$('#datetimepicker6').data("DateTimePicker").maxDate(e.date);
});
});
</script>
</html>

Angular JS HTML 5 date input value get in YYYY-MM-DD format

I would like to know how to get HTML 5 date input value get to script. This date format should be in YYYY-MM-DD. This value should be store in date1 variable after click the submit button.
HTML Code:
<form ng-controller="validateCtrl" name="myaForm" novalidate>
<input class="datepicker validate" type="date" id="birthday" ng-model="birthday" placeholder="yyyy-MM-dd" required>
<button type="submit" ng-submit="submitfun()">Submit</button>
</form>
Script Code:
<script>
var app = angular.module('myApp', []);
app.controller('validateCtrl', function($scope) {
$scope.submitfun= function () {
birthday = $filter('date')(birthday, 'yyyy/MM/dd');
}
});
</script>
This code not working for me how to solve this problem.
You missed to declare scope variable. Write $scope.birthday.
There is no way possible to change the format of html5 input date type, look at possible solution in the below answer:
How can I load value on input date with angular?
I'll add to that if you would like to get the formatted string value of the date, then you either use $moment library like this:
<form ng-controller="validateCtrl" name="myaForm" novalidate>
<input class="datepicker validate" type="date" id="birthday" ng-model="birthdayModel" placeholder="yyyy-MM-dd" required>
<button type="submit" ng-submit="submitfun()">Submit</button>
</form>
$scope.submitfun= function () {
$scope.birthday = $moment($scope.birthdayModel).format('YYYY-MM-DD');
console.log($scope.birthday.toString());
}
or parse the date manually like this:
$scope.submitfun= function () {
var days = $scope.birthdayModel.getDate();
var months = $scope.birthdayModel.getMonth()+1;
var years = $scope.birthdayModel.getFullYear();
//Now you have them separate you can put them in whatever format you want
//like this for example:
$scope.birthday = days+'-'+months +'-'+years ;
console.log($scope.birthday);
}

Custom Directive for Required/ngRequired

I want to validate a dropdown with required. Default required only works if value is null or blank (correct me if I'm wrong). I want required to give error and make form invalid true if value is 'not assigned'.
<select name="first" class="select" title="Select Approver" ng-model="applications.first" ng-options="x.id as x.value for x in list1" ng-change="SetToAll(applications.first,'1')" required></select>
Using this I can show error message but this does make form invalid
<span class="error" ng-show="applications.first == 'not assigned'?true:false">Select Approver</span>
SOLUTION:-
1) If you want to use required then Check Shannon Hochkins solution.
<form name="formName">
<select name="first" class="select" title="Select Approver" ng-model="applications.first" ng-options="x.id as x.value for x in list1" ng-change="SetToAll(applications.first,'1')" required="true">
<option value="">Not Assigned</option>
</select>
<span class="error" ng-show="formName.first.$invalid ?true:false">Select Approver</span>
<pre>{{formName | json}}</pre>
</form>
He Added a option with blank value <option value="">Not Assigned</option>. and set required="true" in select. This works perfectly.
2) Using custom directive.
app.directive('req', [
function() {
var link = function($scope, $element, $attrs, ctrl) {
var validate = function(viewValue) {
var comparisonModel = $attrs.req;
var invalid = $attrs.invalid;
if (viewValue == invalid) {
// It's valid because we have nothing to compare against
ctrl.$setValidity('req', false);
} else {
ctrl.$setValidity('req', true);
}
};
$attrs.$observe('req', function(comparisonModel) {
// Whenever the comparison model changes we'll re-validate
return validate(ctrl.$viewValue);
});
};
return {
require: 'ngModel',
link: link
};
}
]);
And Your html code :
<select invalid="not assigned" req={{applications.first}} name="first" class="select" ng-model="applications.first" ng-options="x.id as x.value for x in list1" title="Select Approver" ></select>
<span class="error" ng-show="Step5.first.$error.req">Select Approver</span>
Here you will have to set invalid="not assigned" or any value like invalid='0' or invalid=' '. In directive it compares with invalid attribute if value matches it will show error.
Add the required value to the select element, then you can use the FORM object to check if the field is valid or not.
You can also use the forms name, to access fields in the form to check validity.
If you want to add a 'default' option, to the dropdown, you can add in an option with an empty value which is technically invalid on a required dropdown menu. You can choose to hide it if it is valid so the user can't pick it again after a correct option has been chosen.
<form name="formName" ng-controller="testCtrl">
<select name="first" ng-options="x.id as x.value for x in list1" ng-model="applications.first" required>
<option value="" ng-hide="formName.first.$valid">Not Assigned</option>
</select>
<pre>{{formName.first.$invalid | json}}</pre>
</form>
Inside your controller, setup some options:
angular.module('sandbox', []).controller('testCtrl', function($scope) {
$scope.list1 = [{
id: 1,
value: 'apples'
}, {
id: 2,
value: 'oranges'
}];
});
Demo: https://jsfiddle.net/suunyz3e/304/

Trigger html5 validation without form post

I want to achieve something like this without form post, as it will redirect the page.
here is my code
<form>
<input type="number" step="any" min="0" required oninvalid="this.setCustomValidity('Please enter price with decimal format, eg x.xx .')">
<button type="submit">submit</button>
</form>
I've did some research it seems like it has to be triggered with form post. Possible to trigger the html5 validtion with jquery function button click ?
Set a custom validation message on input change and intercept the form submit event:
var form = document.querySelector('form'),
input = document.querySelector('#input-price');
input.addEventListener("change", function (event) {
if (!input.checkValidity() || !/^\d+(\.\d+)?$/.test(input.value)) {
input.setCustomValidity("Please enter price with decimal format, eg x.xx .");
} else {
input.setCustomValidity("");
}
});
form.addEventListener("submit", function (event) {
event.preventDefault();
});
<form>
<input id="input-price" type="number" step="any" min="0" required>
<input type="submit">
</form>
input.checkValidity() returns true when the input value is a number as in 2, .1 and 1e10. The regex test then filters the two last cases (.1 and 1e10) out.
the html5 “pattern” attribute doesn't work in all Browsers
the only way is to use JavaScript code
try this code
Html
<input id="amount" maxlength="7" type="text" />
javaScript
$("#amount").on("keyup", function(){
var valid = /^\d{0,4}(\.\d{0,3})?$/.test(this.value),
val = this.value;
if(!valid){
alert("Please enter price with decimal format, eg x.xx!");
this.value = val.substring(0, val.length - 1);
}
});
to avoid accepting invalid input when pasting text (idea of #le_m)
try this second solution :
html
<input id="amount" maxlength="7" type="text" />
JS
$("#amount").on("change paste keyup", function(){
var valid = /^\d*(\.\d*)?$/.test(this.value),
val = this.value;
if(!valid){
alert("Please enter price with decimal format, eg x.xx!");
this.value = val.substring(0, val.length - 7);
}
});
result :
http://jsfiddle.net/vY39r/866/