md-datepicker forcing to input value - angularjs

i have simple angular application, contain date picker of material input.
<form name="xyz" ng-submit="xyz.$valid && submitMyForm()">
<md-input-container class="md-block">
<label>Available From</label>
<md-datepicker
ng-model="user.availableFrom"
ng-required="false"
md-open-on-focus
name="availableFrom"
id="availableFrom">
</md-datepicker>
</md-input-container>
<input type="Submit" value="Submit">
</form>
when i click on submit button then it shows red underline and forcing me to select any date, i want to submit blank input.
Thanks.

I know, it might be a little late, but maybe it's helping somebody else.
I assume your model variable is an empty string. I tried with tanmay's fiddle and changed it a little.
When you change
$scope.user.availableFrom = "";
to
$scope.user.availableFrom = null;
or completely remove this line, it will work.

Related

Angular: Elegant way to toggle visibility of two related inputs

I have 2 related inputs in angular one is type number and the other is type text.
They both display the same value with the only difference being that the type text input displays the value of the type number input formatted for currency.
Only one of these is displayed at any given time. The behaviour I'd like is for the text input to be displayed initially and then on the click event the text input is hidden and the number input is shown. Similarly when the blur event happens on the number input the number input is hidden and the text input is shown.
The markup for this looks something like this:
<div>
<input type="number" ng-model="aValue" ng-blur="hideMeAndShowInputBelow">
<input type="text" ng-value="aValue | currency:'': '0'" ng-click="hideMeAndShowAndFocusInputAbove" readonly="readonly">
</div>
I know I could add extra properties to make this work but being relatively new to Angular this feels like the sort of thing that there is probably an elegant solution for.
Any help would be much appreciated.
You can assign a variable in ng-blur/ng-click and hide/show the inputs depending on the variable value.
<div>
<input type="number" ng-model="aValue" ng-show="showNumber" ng-blur="showNumber = false">
<input type="text" ng-value="aValue | currency:'': '0'" ng-show="!showNumber" ng-click="showNumber = true" readonly="readonly">
</div>
Check the plunker here:
https://plnkr.co/edit/yMFiXWuUF1R9BPGr2usT?p=preview
Alternatively, if this is a component you're going to use multiple times around your app, you could create a custom directive that achieves the same functionality, and thus avoid a lot of code duplication etc.
Try out something like this
<div ng-app="myApp" ng-controller="myCtrl">
<button class="btn btn-success" type="text" ng-model="firstName" ng-show="display" ng-click="display=!display"> BUTTON 1</button>
<br />
<button class="btn btn-warning" ng-click="display=!display" ng-model="lastName" ng-show="!display"> BUTTON 2
</button>
</div>
DEMO
Thanks for the suggestions. I followed the same approach but because I had some additional requirements (I wanted the value to be focussed when switching to the edit mode so the user can edit immediately without having to click the input again) I ended up writing a directive. It's here:
PLUNKER
But here is the markup.
<div class="mt-flight-input" ng-class="{'mt-dirty': value.newvalue != value.initial, 'mt-zero': value.newvalue == 0}">
<input type="number" class="mt-input" placeholder="0" ng-show="value.isAuthoring" ng-model="value.newvalue" ng-blur="checkValue('blur', value)" ng-focus="checkValue('focus', value)">
<input type="text" class="mt-input" placeholder="0" ng-show="!value.isAuthoring" ng-value="value.newvalue | currency:'': '0'| comma2dots" ng-click="showEditor($event, value)" ng-focus="showEditor($event, value)" readonly="readonly">
</div>

Using md-chips in forms with other inputs

I am trying to make use of md-chips alongside other inputs in a form that are inside md-input-containers.
I have had to add my own css hacks to get the placeholder text of the input, plus padding and margin applied to get it to look as close enough to an input inside an md-input-container as best I can.
I know I can't get md-chips to work inside an md-input-container (I dont think its supported yet)
Here is how I have an input followed by an md-chips appearing:
<div layout="row">
<md-input-container flex>
<label translate>Name</label>
<input ng-model="ctrl.name">
</md-input-container>
<div class="chips-container" flex>
<md-chips ng-model="ctrl.fruitNames">
<md-chip-template>
<span><strong>{{$chip}}</strong></span>
</md-chip-template>
<input type="text" placeholder="Enter Something">
<button md-chip-remove class="chip">
<md-icon class="material-icons">clear</md-icon>
</button>
</md-chips>
</div>
</div>
Working Codepen
Has anyone faced a similar situation needing to get md-chips with inputs aligning correctly alongside other inputs in similar layouts?
Just looking for suitable solutions, I can't see any combination examples on the Angular Material input demos.
Thanks

label hiding input text field value in md-input-container when retrieving with ng-value

When using angularjs to retrieve a value for a text input field with ng-value, the label the overlays the field doesn't transition above the field after the value is retrieved. I can only see the value in the input field after clicking on that field.
I'm using material's md-input-container:
<md-input-container>
<label>Name</label>
<input type="text" ng-value="profileInfo.name" ng-model="savedProfileInfo.name" class="provider-name" id="providerName" name="providerName" />
</md-input-container>
Here's the Inspect Element code:
<md-input-container class="">
<label for="providerName">Name</label>
<input type="text" ng-value="profileInfo.name" ng-model="savedProfileInfo.name" class="provider-name ng-pristine ng-untouched ng-valid md-input" id="providerName" name="providerName" aria-invalid="false" value="a"><div class="md-errors-spacer"></div>
</md-input-container>
You can clearly see that value="a" which was pulled after the page loaded using ng-value. But, the field still looks like this:
Only after I click on the field does it look how I would expect:
Is this a bug? Am I missing something? I though AngularJS and Material were supposed to play nice.
Available plunker here
In a roundabout way troig's comment helped me figure this out.
This form is used to display and update a user's profile information. I was using ng-model to update the user's profile and ng-value to display any existing user profile info from the database.
ng-value spits back the value="" attribute which does not play nice with md-input-container. To get this to work properly, I removed ng-value, replaced ng-model's value with profileInfo.name, and modified my controller to allow me to save profileInfo.name instead of savedProfileInfo.name.
Code translation:
<form ng-submit="saveProfile(profileInfo)">
<md-input-container>
<label>Name</label>
<input type="text" ng-model="profileInfo.name" class="provider-name" id="providerName" name="providerName" />
</md-input-container>
Moral of the story, ng-value does not play nice with md-input-container and form labels.

validating minlength and maxlength in md-text-float

I want to validate if the user is entering an input between 4-20 characters of length into a md-text-float (angular material directive), with plain angular I would just insert the ng-minlength and ng-maxlength attributes into an tag then validate. But in it doesn't work. How should I validate if the text float holds the required string length and enable the submit button?
<md-text-float label="password" data-ng-model="formPassword"
data-ng-minlength="4" data-ng-maxlength="20" type="password" data-ng-required="true"></md-text-float>
and then enabling.
<md-button class="md-raised md-primary" data-ng-click="submitLogin()" data-ng-disabled="loginForm.$invalid">login</md-button>
Actually For md-text-float directive ng-minlenght and all will not work, validations are still in progress,You can see the link also
https://github.com/angular/material/issues/372
Still, if you want to validate then try to validate it in controller itself to handle validation.
If you want to validate material design inputs, I would suggest using md-input-group directly rather than md-text-float (which uses md-input-group internally), until it supports validation out-of-the-box. I couldn't do a plunker for you, as the site is down - will try to do later on, once the site is back up.
But to give you an idea, the html will look something like this:-
<div class="field" layout="column" layout-align="center center">
<md-input-group>
<label for="email">Email</label>
<md-input type="email" id="email" name="email" required maxlength="50"
ng-model="loginVm.user.email"></md-input>
</md-input-group>
<span class="error-message email-error" ng-if="loginform.$submitted && loginform.email.$invalid">Please enter a valid email address.</span>
</div>

How to show 'invalid date' validation message for AngularStrap datetimepicker

I am able to validate my AngularStrap datetimepicker, but I cannot differentiate between a required validation failure and an invalid date failure. The only error that ever shows on screen is the required error, whether it is required or an invalid string. Is it possible in cases where a string has been entered that is invalid to show a different validation message? Here is my code :
<div class="control-group" ng-class="{error: form.BirthDate.$invalid}">
<label class="control-label" for="BirthDate">{{'_BirthDate_' | i18n}}</label>
<div class="controls">
<input id="BirthDate" name="BirthDate" title="BirthDate" type="text" ng-model="user.BirthDate" data-date-format="dd/mm/yyyy" bs-datepicker required>
<span ng-show="form.BirthDate.$dirty && form.BirthDate.$error.required">{{'_BirthDateRequired_' | i18n}}</span>
<!--<span ng-show="form.BirthDate.$dirty && form.BirthDate.$error.pattern">{{'_BirthDateInvalid_' | i18n}}</span>-->
</div>
</div>
What I want is something similar to the ng-pattern check but specific to the datetimepicker.
first of all, I think this has no real link with the date picker or not, if I understand your problem, you are trying to display different messages according to the error that lead to the $invalid for the form
If it's the case, the code you provided will only show a message when the date is invalid (but only because you commented the part for the pattern ;) )
I was super lazy while testing, so I didn't use the datepicker, you'll have to enter a date manually, but I did this fiddle : http://jsfiddle.net/DotDotDot/ELf5A/2/
As I didn't know exactly in what context you were using it, I used different methods to display validation error messages
The HTML part is simple. There is a form, two fields required, one with a pattern check for the date, the other only for the required validation. I added 2 error messages for the date, one displayed when the form hasn't been touched, telling you what format is expected, the other only shows up when the pattern is wrong.
You can click on the button to check the whole validation and then show another message, which will tell you if the form is valid or not, and if not, if it's because of the pattern of the date.
<div ng-controller='theCtrl'>
<form name='theForm'>
Enter something here : <input type='text' ng-model='someField' name='someField' required /> <br/>
Enter a date here : <input type='text' ng-model='theDate' name='theDate' ng-pattern='datePattern' required />
<span ng-show='theForm.theDate.$error.pattern'>Your date format is invalid, please check it again</span>
<span ng-show='theForm.theDate.$pristine'>Enter a valid date here : DD/MM/YYYY</span>
<br/> <input type='button' ng-click='validation(theForm)' value='Try to validate me!' />
<br /> {{errorMsg}}
</form>
</div>
The JS part is not very complicated either. When you click on the button, the form is being sent to the validation function, which will actually do all the checks you want, I only did the one corresponding to the pattern, but you could totally check whatever you want about the validation
$scope.validation=function(aForm){
//console.log(aForm)
if(aForm.theDate.$error.pattern)
$scope.errorMsg='The pattern you entered isn\'t good enough, try again !'
else{
if(aForm.$invalid)
$scope.errorMsg='Something is invalid, please check all the fields !'
else//valid
{
$scope.errorMsg='Not bad !'
alert("good job !")
//maybe you can also submit this form here ;)
}
}
}
This validation function could totally be used as the trigger in a ng-show/ng-hide too, this is why I also added another function :
$scope.whatToDisplay=function(aForm){
if(aForm.$valid)
return 'valid';
if(aForm.theDate.$error.pattern)
return 'date';
if (aForm.$invalid)
return 'notdate';
}
This will return a string corresponding to what is happening during the validation, which will be handled with ng-show :
<span ng-show='whatToDisplay(theForm)=="date"'>Displayed if the date is wrong</span>
<span ng-show='whatToDisplay(theForm)=="notdate"'>This is displayed if the form is invalid, but not because of the date format</span>
<span ng-show='whatToDisplay(theForm)=="valid"'>Displayed if the form is valid</span>
To summarize a bit, you can use 4 different methods
A validation function triggered with a click (useful for submit buttons), corresponding to the validation() function in my fiddle
A function associated with some ng-show, which will automatically watch every change, like the whatToDisplay() function
The ng-show associated with only the form attributes, like what you were doing with your code
The class automatically applied to the form ( I didn't explain it, but you can see it in the fiddle, the border change if the pattern is wrong or if it's only invalid )
Sorry, I had some difficulties to make this short, I let you play with the code, it's easier to understand that way, I hope this will help you
You should use ngMessages in AngularJS 1.3 to do the error messaging with less code and complexity. The bs-angular directive creates a message for the "date" string value of ng-message in your list of messages.
<div class="control-group" ng-class="{error: form.BirthDate.$invalid}">
<label class="control-label" for="BirthDate">
{{'_BirthDate_' | i18n}}
</label>
<div class="controls">
<input id="BirthDate" name="BirthDate" title="BirthDate" type="text"
ng-model="user.BirthDate" data-date-format="dd/mm/yyyy"
bs-datepicker required>
<span ng-show="form.BirthDate.$dirty && form.BirthDate.$error.required">{{'_BirthDateRequired_' | i18n}}</span>
</div>
<div class='alert alert-danger' ng-messages='myForm.BirthDate.$error'
ng-if='!myForm.BirthDate.$valid'>
<div ng-message="date">Please enter a valid date</div>
<div ng-message="required">Birthdate is required</div>
</div>
</div>
This code helps to show the invalid datetime error message
$scope.date=='Invalid Date'
{
err('Your error message');
}

Resources