AngularJS Date Pattern Validation Changes from v1.3 to v1.4 - angularjs

I recently asked this question about the changes to RegExp pattern validation that were introduced in AngularJS v1.3. The answer I received apparently solved my problem, but now I am trying to apply that approach, and I see that the behavior is again different in AngularJS v1.4.
Specifically, I want to apply pattern validation to a date input field, but the validation RegExp will be exposed as a property of the model, instead of being hard-coded into the form markup.
As suggested, I am specifying the name of the model property in the ng-pattern attribute ...
<input type="date" ng-model="myDate" name="myDate" ng-pattern="control.dateRegex" />
... and exposing the validation RegExp as a property of the model:
$scope.control = {
dateRegex: /^2015-\d+-\d+$/
};
This JSFiddle shows it working correctly with AngularJS v1.3 and this one demonstrates that the same implementation does not work with v1.4. I am unable to find any documentation that describes the correct implementation for use with v1.4.
Any suggestions please?

After asking a similar question on the AngularJS issues forum, I learned that this behavior is specific to date input validation. It arises because the model property used for date input binding has changed from a String to a Date object, which means that is no longer possible to use a RegExp to validate it.
It seems that the AngularJS team recognize this as a bug and that we can expect a fix in a forthcoming release. I will monitor the issue and update this thread when there is some progress.

Related

Angular validation: if dynamically add required attribute validation will break

Trying to dynamically add validation to input file if I choose first option from select. But if I add required attribute, it still ng-valid in class. If I load file to input file, it still ng-empty.
What's wrong? http://plnkr.co/edit/pjyCULes60jWf7yqNsyB?p=preview
The form validation in AngularJS depends on the ngModel attribute, which doesn't work with input type=file.
To solve this, either use ngFileUpload which helps you solve other problems you'll encounter with file upload in Angular as well, or see this or that answer.

md-select attribute name error Angular-Material

Im working with angularjs/1.3.6 and v0.10.0/angular-material.js with a md-select field with name="txtGenero" but when the form have been Submitted with ajax the md-selected has a dot at beginning of name field like '.txtGenero' in the image below.
https://plus.google.com/photos/+TommyHern%C3%A1ndezA/albums/6175087393788917697/6175087392180342338?pid=6175087392180342338&oid=118016940134163401130
I hope can help me thanks.
I don't exactly know why the ngFormController has the .txtGenero field.
However you should use ngModel to bind your form fields to a model and post that model, not the form controller itself. You can use angular.element.param($scope.registro) to get the the fields from your model as form data.
You don't need jQuery for any of it.
Updated plunkr: http://plnkr.co/edit/IFOsFgiQBo7vJVzkBxaf?p=preview
(I updated to angular-material master)
Try to provide your code well formatted, this is kind of a mess to work with.

ng-maxlength preventing a valid value from being databound to input field

I have the following field in a form:
<input type="text" name="dedicatedstaff" ng-model="staffingRecord.dedicatedStaff"
tabindex="9" ng-pattern="/^[0-9]{0,4}(\.[0-9]{1,2})?$/" ng-maxlength="7" />
The form is to edit an existing record. No matter what value is in the existing record, the field fails validation and the databind becomes undefined. Some example values that exist on the records are 1, 2.5, 12.5, 99.25, 4.0. I believe every one of these should pass both the pattern and maxlength validations, but it isn't working. I've checked the model and the values are present when loading the form.
When I remove the ng-maxlength directive and just have the ng-pattern, it works fine and those values pass validation. If I remove ng-pattern and just have max-length, it fails. It also doesn't matter if the INPUT is of type text or number. If ng-maxlength is present, it fails. Browser also does not make a difference (tested Chrome, IE & Firefox). I have also verified that it is the maxlength error in the error list.
I am also using ng-maxlength with almost every other field on this particular form, and they also work just fine. And if I type the exact values listed above after form load when ng-maxlength is present validates fine at that point. But that's not a reasonable workflow to make the client type the values over again every time they load the form.
I don't understand it as I use this same pattern in other forms within the app and they work fine. I can get by with just ng-pattern on this particular field, but I would much rather figure out why, in this one case, it won't validate properly on load.
I'm using AngularJS 1.2.14, with JQuery 1.9.1.
I figured it out. It was actually the INPUT type after all. After further testing, I realized my initial test of that variation was incorrect. Changing the INPUT type to NUMBER fixed the validation issues.
<input type="number" name="dedicatedstaff" ng-model="staffingRecord.dedicatedStaff"
tabindex="9" ng-pattern="/^[0-9]{0,4}(\.[0-9]{1,2})?$/" ng-maxlength="7" />

Setup bi-directional binding from an object defined in an html attribute in AngularJS

I have implemented a remote validation directive which queries a specified JSON API endpoint once an input is blurred. It expects the response { valid: true|false }.
I now have to extend it to allow for it to send a request involving multiple values from the parent scope.
My tag definition looks as follows:
<input remote-validate endpoint="/api/action/:value" ng-model="MyInput" />
where :value is substituted with a urlencoded value of $scope.MyInput.
This is working well.
What I require is given an endpoint like this /api/action/:value/:person/:thing, the :person and :thing substitutions are bound to the parent scope values.
My initial thought is to have a bindings attribute which maps the parent scope to the endpoint.
<input remote-validate endpoint="/api/action/:value/:person/:thing" bindings="{person: 'firstName', thing: 'thingName'}" ng-model="MyInput" />
(...)
<input ng-model="firstName" /> <input ng-model="thingName" />
given var bindings = scope.$eval(attrs.bindings); is there any way to loop through the bindings object and create a two way binding to the parent scope?
EDIT: A workaround may be to do this:
<input validate-remotely
endpoint="api/action/:value/:param1/:param2"
param1="person"
param2="thing" />
which obviously means I can only use the number of parameters I specify in the scope definition. Which is a good work around for me here. Would be nice to know if there was a way to create these bindings dynamically at compile/link time.
I can provide a fiddle but I don't have the time right now, so I'm hoping that someone will have a good idea if/how this is possible.
As I learned yesterday, you can use $parse on your 'binding' attributes. See this post. This is a good way to $watch an attribute for changes that come from parent or children
Example:
<div parse-test bindings="{person: 'firstName', thing: 'thingName'}"></div>
// in your directive link function:
scope.bindings = $parse(attrs.bindings)(scope);
scope.$watch('bindings', function(val){
for (i in scope.bindings){
scope[i] = scope.bindings[i];
}
}, true);
Experiment with this plunk
This is how I solved it in a not so ideal way.
See this plunker, which has a copy of the directive I use live and works well in my app but doesn't work in Plunker (I expect the randomly chosen plunker api endpoint to be called and fail, but it is not called due to some strange errors I don't care to debug).
The problem I had with the proposed workaround in the EDIT of this question is that it seems you cannot use scope and require in the same directive. I would love it if someone could elaborate on if this is the case and why.
The Workaround
I used a params attribute to specify additional data in object notation to be extended to go to the resource request. I used the handlebars syntax in the params attribute to dynamically change the object notation string.
<input ng-model="value2" ... />
<input validate-remotely
endpoint="/api/:value/?thing=:anotherValue"
params="{ anotherValue: '{{ value2 }}' }" ... />
Not so great :/ but it works.
Then on blur of the validated input, I re-$eval the object string (app.js:40 in the plunker) and extend the resources data to include this object, which using ngResources colon (:) notation, replaces the URL.
The validation has 3 states:
remoteValidityPending: field validation fails because it is still being checked - good for showing a spinner.
remoteValidityUnchecked: The field has changed since it has been checked but has not yet blurred - ensures that any `ng-disable="form.$invalid"' submit buttons stay disabled until we know that the backend has returned a response.
remoteValidity: If this passes, the fields endpoint has been called and '{valid: true}' has been returned from the server.
I'm almost certain there are better/different ways to solve this, and I'll be happy to change the answer if someone improves this directive. I hope this helps someone out there.

AngularJS : Validating against multiple datepickers

Considering 3 dates : myDate1, myDate2, myDate3.
I'd like to validate that myDate1 < myDate2 < myDate3
Dates are set by the date picker directive found in angular-ui.
Here is a plunker : http://plnkr.co/edit/FTcJNHxuv3RFtBCUw7Ck
I'm having difficulties founding the right way to do that.
I'm using ui-validate but it looks like when a condition is evaluated to false, the model is set to undefined.
Edit : It turns out that model being set to undefined is normal Angular behaviour. However there is a bug in the ui-validate directive. I'll update this post once it's resolved. See : https://github.com/angular-ui/ui-utils/issues/25
Please have a look at this fiddle. http://plnkr.co/edit/p0cq1idV6xTF2LyorQ06?p=preview.
Instead of using ui-validate i used ng-change and an extra scope variable formValid to track the validity of form.

Resources