md-datepicker not working with maxlength and minlength - angularjs

I am trying to get the maxlength and minlength messages to work correctly. However, I am only getting the "required" message. It then stays there until I refresh the page also. Also, is there a way to put a mask on md-datepicker that forces a user to put in like 99/99/9999 (mm/dd/yyyy). I haven't found anything on this as of yet.
<md-input-container class="md-block">
<label>{{dynElm.dob.text}}</label>
<md-datepicker ng-change="dateChange()" type="text" name="dob" ng-model="signup.date" md-open-on-focus md-current-view="year" maxlength="9" minlength="6" ng-click="md-is-open" required></md-datepicker>
<div class="hint" align="center">(MM/DD/YYYY)</div>
<div ng-messages="signup.dob.$error" style="color:red;" role="alert">
<div ng-message="required">Date of Birth field is required</div>
<div ng-message="maxlength">Use MM/DD/YYYY format for entry</div>
<div ng-message="minlength">Use MM/DD/YYYY format for entry</div>
</div>
</md-input-container>

I would suggest that instead of checking maxlength and minlength for date, check whether date is valid or not. Verify below sample (found on google) which validate entered date and also allows you to mask your entered date.
DEMO
<md-datepicker-custom name="dateField"
ng-model="appCtrl.myDate"
md-placeholder="Enter date"
md-min-date="appCtrl.minDate"
md-max-date="appCtrl.maxDate"
md-custom-required="true"
md-custom-default-date="{{::appCtrl.defaultDate}}"
md-custom-mask="19/39/9999"
md-custom-clean-mask="false"
md-custom-restrict="reject">
</md-datepicker-custom>

Related

How to catch errors or validate angular material datepicker in the controller?

In angular material datepicker, Error messages are shown using ng-Messages but how do I catch those in the controller and validate if no error is there.
<form name="myForm">
<md-datepicker name="dateField" ng-model="myDate" md-placeholder="Enter date"
required md-min-date="minDate" md-max-date="maxDate" md-open-on-focus></md-datepicker>
<div class="validation-messages" ng-messages="myForm.dateField.$error">
<div ng-message="required">This date is required!</div>
<div ng-message="mindate">Date is too early!</div>
<div ng-message="maxdate">Date is too late!</div>
<div ng-message="valid">The entered value is not a date!</div>
</div>
{{myForm.dateField.$error}}
</form>
<button ng-click="check(myForm.dateField.$error)">Click</button>
I want to validate errors on click of button in the controller
$scope.check=function(errors){
};
Angularjs creates a scope variable for form whenever it is used to check the validation of that form. Now you can directly use form.$valid , formName.$invalid and many more pre-defined properties in html directly. But if you want to use it in the controller just pass it to the controller using md-button (while submitting the form).
<form name="myForm">
<md-datepicker name="dateField" ng-model="myDate" md-placeholder="Enter date" required="" md-min-date="minDate" md-max-date="maxDate" md-date-filter="onlyWeekendsPredicate"></md-datepicker>
<div class="validation-messages" ng-messages="myForm.dateField.$error">
<div ng-message="valid">The entered value is not a date!</div>
<div ng-message="required">This date is required!</div>
<div ng-message="mindate">Date is too early!</div>
<div ng-message="maxdate">Date is too late!</div>
<div ng-message="filtered">Only weekends are allowed!</div>
</div>
<md-button ng-click="check(myForm)">check/md-button>
</form>
Here is a working example. You can the whole object in console which is printed by controller as desired. http://codepen.io/next1/pen/rLebeK
You already got that right but missing the validation. The correct way is to check the property $scope.myForm.$valid, that will be true when the form is valid and false otherwise. Check the Developer Guide.
Other way is to check for the empty object (so no errors) but it checks for that input only:
in the HTML:
<button ng-click="check(myForm.myName.$error)">Click</button>
in the controller:
$scope.check = function (val){
// check if is empty
var ok = !!(Object.keys(val).length === 0 && val.constructor === Object);
}
I don't recommend this approach unless you want to do it yourself or deal with specific errors.
See this Plunker with both ways

Start date and end date validations angularjs

This is not a duplicate of this
I have a form which has start date and end date with date pickers. The user can add more than one date in the form. In this case the first from date and to date select boxes will be cloned and appended to the form.
I need to check the validity of the dates in each from date and to date pair. That is if to date is smaller than from date error message should be displayed near the to date. I have added the code below. Thanks.
<form name="myForm">
<span ng-repeat="data in userdata">
<ng-form name="repeatForm">
<input type="text" name="expFromDate" ng-model="form.fromDate"/>
<input type="text" name="expToDate" ng-model="form.toDate"/>
<span class="error input-icon fui-alert input-icon-check" ng-show="repeatForm.expToDate.$error.expFromDate"></span>
</ng-form>
</form>
Rather than cloning the date boxes with jQuery or so, you should use an ng-repeat like:
<input ng-repeat="fromDate in ctrl.fromDates" type="text" name="expFromDate" ng-model="fromDate"/>
<input ng-repeat="toDate in ctrl.toDates" type="text" name="expFromDate" ng-model="toDate"/>
Then you can have a method on your controller to do the validation:
<span class="error input-icon fui-alert input-icon-check" ng-show="!ctrl.datesValid()"></span>
public datesValid(): boolean {
return _.all(this.fromDates, date => ...)
&& _.all(this.toDates, date => ...);
};

angular ui date picker causing $valid to be set to false

I have three radio buttons: Active, Dissolved, Concluded.
If Active chosen then "Active" is stored in the column in the table.
If Dissolved is chosen then an input with a date picker is displayed. This is the same for Dissolved. Therefore the column is set to nvarchar.
What I'm finding is when I save the screen nothing happens. I stepped through the code and got to this line:
if ($scope.addeditregulatoryapprovalForm.$valid)
$valid evaluates to false. If I hover over it, I see $error, if I expand that I see date, if I expand that I see an array with one element, when I expand that I see the date that is displaying in the input field.
If what I'm seeing is correct and that it's the date that is causing the issue I just don't know why it's causing an issue. I have to pick a date, even if it's the same date that's already picked, before I can save.
Any ideas?
Here's the code:
<div class="col-xs-7 form-inner-group padRt0">
<div class="clearfix stackDate">
<input name="DissolutionConcludedStatusDate" id="DissDate1_0" type="radio" ng-model="vm.regulatoryApproval.DissolutionConcludedStatusID" ng-value="1"> Active<br />
</div>
<div class="clearfix stackDate">
<input name="DissolutionConcludedStatusDate" id="DissDate1_1" type="radio" ng-model="vm.regulatoryApproval.DissolutionConcludedStatusID" ng-change=vm.setDate() ng-value="2">
Dissolved <span ng-if="vm.regulatoryApproval.DissolutionConcludedStatusID==2">
<input class="form-field cal-field" type="text" ng-required="vm.regulatoryApproval.DissolutionConcludedStatusID==2"
name="DissolvedStatusDate"
ng-model="vm.regulatoryApproval.DissolutionConcludedStatusDate"
datepicker-popup="dd-MMM-yyyy" close-text="Close" ng-model="vm.regulatoryApproval.DissolutionConcludedStatusDate"><br />
<div ng-show="addeditregulatoryapprovalForm.submitted || addeditregulatoryapprovalForm.DissolvedStatusDate.$touched">
<span class="error" ng-show="addeditregulatoryapprovalForm.DissolvedStatusDate.$error.required">Please select a Dissolved date</span>
</div>
</span>
</div>
<div class="clearfix stackDate">
<input name="ConcludedStatusDate" id="DissDate1_2" ng-model="vm.regulatoryApproval.DissolutionConcludedStatusID" type="radio" ng-change=vm.setDate() ng-value="3">
Concluded <span ng-if="vm.regulatoryApproval.DissolutionConcludedStatusID==3">
<input type="date" class="form-field cal-field" ng-required="vm.regulatoryApproval.DissolutionConcludedStatusID==3"
name="ConcludedDate"
ng-model="vm.regulatoryApproval.DissolutionConcludedStatusDate"
datepicker-popup="dd-MMM-yyyy" close-text="Close" ng-model="vm.regulatoryApproval.DissolutionConcludedStatusDate"><br />
<div ng-show="addeditregulatoryapprovalForm.submitted || addeditregulatoryapprovalForm.ConcludedStatusDate.$touched">
<span class="error" ng-show="addeditregulatoryapprovalForm.ConcludedStatusDate.$error.required">Please select a Concluded date</span>
</div>
</span>
</div>
</div>
I figured out what the issue was. Because I had to save the date as a string in the database when the form was being saved it was considered invalid because it wanted a date from the datepicker. I had to convert the string to a date when it pulled it from the database before assigning it to the model.

AngularJS Format date in read only field

I am having trouble formatting a date in a read-only field using AngularJS. This is my html code -
<div class="row">
<label class="col-md-2">Date Last Login:</label>
<div class="col-md-3">
<input type="datetime" name="dateLastLogin" class="form-control" data-ng-model="loginDate" readonly />
</div>
</div>
I have tried to format it using this code in my controller -
$scope.$watch('vm.account.dateLastLogin', function(newValue) {
$scope.loginDate = $filter('date')(newValue, 'MM/DD/yyyy');
});
Putting a break point in the controller, I see the function being called but nothing is displayed.
If I leave my html like this -
<div class="row">
<label class="col-md-2">Date Last Login:</label>
<div class="col-md-3">
<input type="text" name="dateLastLogin" class="form-control" data-ng-model="vm.account.dateLastLogin" readonly />
</div>
</div>
I get a displayed value that includes the date and time but not formatted as I need it. What am I missing?
According to this answer, the W3C removed the datetime input type from the HTML5 Specification. date and datetime-local are still valid.
In your example, throw out the formatting filter and simply use the ng-model="vm.account.dateLastLogin" on a valid date input, like:
<input type="date" ng-model="vm.account.dateLastLogin" />
or
<input type="datetime-local" ng-model="vm.account.dateLastLogin" />
These date formats are formatted correctly to the client browsers locale.
Or, if you actually just want it in some text field, put the filter directly in the ng-model but still use a valid Date object, like:
<input type="text" ng-model="vm.account.dateLastLogin | date:'MM/dd/yyyy'" readonly />
See this jsBin for some examples

How to get the element inputName through ng-messages directive?

how do I trigger the error messages without knowing the input name? See the code below:
<input class="form-control"
id="{{field.field_id}}"
set-name="{{field.field_id}}"
type="text"
ng-model="field.field_value"
ng-minlength="field.field_char_num_min"
ng-maxlength="field.field_char_num_max"/>
<div ng-messages="don't know the input name yet" class="my-messages">
<div ng-message="minlength">Your field is too short</div>
<div ng-message="maxlength">Your field is too long</div>
</div>
In ng-messages should be written the path to errors from the input, like myForm.inputName.$error. But the Inputs will be generated and appended automatically so I can't write the name because a generator sets the names. I have to get a hold of the input name. How can I do it?
Try something like this in in ng-message
<form name="formName">
<input type="text" id="anyName" name="anyName" required/>
<span ng-show="formName.anyName.$error.required"> Please enter a value.</span>
</form>
You could use field[field.field_id]['$invalid'] to determine whether field is valid or not, and then by using field[field.field_id]['$error'] show minlength & maxlength error
Markup
<div ng-show="field[field.field_id]['$invalid']" class="my-messages">
<div ng-message="field[field.field_id]['$error'].minlength">Your field is too short</div>
<div ng-message="field[field.field_id]['$error'].maxlength">Your field is too long</div>
</div>

Resources