Angular validation: if dynamically add required attribute validation will break - angularjs

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.

Related

access angularjs form field that contains a number

I have a list of form fields that are generated as the result of an ng-repeat . As such I use the {{$index}} of the repeat loop to name the fields, i.e. ` which leads to:
<input name="myInput0">
<input name="myInput1">
<input name="myInput2">
...
etc. Now I'm trying to access the fields' $valid attribute from the form in the standard angularjs way i.e. myForm.myInput{{$index}}.$valid which resolves to e.g. myForm.myInput0.$valid which I understand won't work because it's accessing a variable and numbers won't be allowed.
However I then tried to access it with myForm['myInput{{$index}}'].$valid, e.g. myForm['myInput0'].$valid which I thought might work but still doesn't. Is there any way possible to access the form field when it contains a numeral? (or other illegal char like a hyphen)?
e: I'm using angularjs 1.2 which might explain why this isn't working. Does anyone know of a workaround for pre 1.3 angular?
The correct expression will look like myForm['myInput' + $index].$valid
I can think of two ways of workaround.
First option:
Put a ng-change on each input and validates it there manually.
Second option:
Retrieve all input elements, interate over each and validates manually
You can get them with this
var inputs = $document[0].querySelectorAll('#rankingForm input');

Add input in Angular bootstrap confirm module

I am trying to use Angular Bootstrap Confirm by Matt.
In his demo (click here), it is mentioned that html can be used in the message. His code:
Are you really <b>sure</b> you want to do this?
I changed that to
Are you really <b>sure</b><br> you want to do this?
and it still worked. But if I try to add any complex element like input or button, it does not work.
Enter <b>Yes</b><br> <input type='text'> <br>and click 'Yes'
Is there a way to add input or textarea to the message?
You would have to fork their code, based on the source, it is using a class, so you could not do this through the interface.
https://github.com/mattlewis92/angular-bootstrap-confirm/blob/master/src/angular-bootstrap-confirm.html

AngularJS - Form validation triggered on load

I added field validation attributes like "required" and "pattern" in my form, and the form is inside a ng-controller. The validation works. But it seems the validations are triggered on page load, and I see all the fields are marked as invalid with error message when the page load.
I tried to add "novalidation" attribute to the form as indicated in the examples on AngularJS website, but no luck.
I would like to have the validation triggered the first time the user tries to interact with it. How can I do that?
Update
Here's an example https://jsfiddle.net/davidshen84/00t197gx/
<div class="mdl-cell mdl-cell-6-col mdl-textfield mdl-js-textfield">
<input class="mdl-textfield__input" type="text" id="screenname" pattern="[a-zA-Z0-9]{3,}" ng-model="comment.screenname" required/>
<label class="mdl-textfield__label" for="screenname">Screen Name</label>
</div>
On load, you should see all the input fields had a red line under them which indicate they are in the invalid state. And the line turns to blue once validated.
Note: The style on the check button does not work...should not be a concern in the problem.
Angular is going to check the form the same way at any point (load or later) and render the result. If you don't want to display the results on load, add logic to check whether the form has been interacted with. You can hide your error messages using ng-if="yourFormName.$dirty", or display according to the status of an individual field with yourFormName.yourFieldName.$dirty.
Click here for live demo.
What is currently implemented (wrong IMHO) is that MDL automatically validates input and doesn't mind "novalidate" form attribute. I had to implement check for empty input value (skip validation and remove is-invalid class) and, since angular form validation requires "novalidate" attribute, check:
if (input.form.novalidate = true) // skip validation
that way you can actually turn off mdl validation and leave everything to angular.
One more thing is actually required. You can create angular directive which validates expression and add is-invalid class if necessary:
div class="mdl-textfield" mdl-validator="form.email.$error"

Using the same directive more than once in the same form

I'm having trouble with a task that seems trivial to me, but I just haven't got it right yet. I have a form and in that form I use a home-cooked directive called time-range. This directive has two input fields for start-date and end-date. Later on, in the view where the form is defined I want to validate each field using code similar to this:
<li ng-show="form.createAssignment.fromDateField.$error.dateinput">{{::$parent.lang.from_date | capitalize}} {{::$parent.lang.has_to_be_on_format}} {{::$parent.lang.yyyy_mm_dd}}</li>
Well, this works just fine, BUT only for validating the input field in the last directive in the form. If I enter something wrong in the first directive, the form is invalid (and thus the error list is shown) but the text that specifies what is wrong does not show up, presumably because the input in the last directive is correct.
So, somehow I would like to be able to qualify which directive I refer to, maybe something like:
<li ng-show="form.createAssignment.directive1.fromDateField.$error.dateinput">{{::$parent.lang.from_date | capitalize}} {{::$parent.lang.has_to_be_on_format}} {{::$parent.lang.yyyy_mm_dd}}</li>
However, I haven't yet succeeded with this. Does anyone have a suggestion how this can be done?
ng-form uses input name for validation, so it's hard to target specific input if you are using ng-repeat or repeated directives.
One option would be using ng-form directive, which means creating an inner form inside the form. There are plenty of guides on how to do this.
Another option would be passing a unique name (prefix/suffix) via your directive parameter. But unfortunately the variable name won't work automatically, you'll have to compile the template again after the name is passed in.

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" />

Resources