23

I have a file upload control in my form.I am using Angular JS . When I put the required attribute to validate that the file is selected it is not working.

<input id="userUpload" name="userUpload" required type="file" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />

<button type="submit" class="btn btn-primary"><i class="icon-white icon-ok"></i>&nbsp;Ok</button>

Can you please suggest why the required is not working ?

2 Answers 2

43

It's the ngModelController that does the validation in Angular based on attributes like require. However, currently there is no support for input type="file" with the ng-model service. To get it working you could create a directive like this:

app.directive('validFile',function(){
  return {
    require:'ngModel',
    link:function(scope,el,attrs,ngModel){
      //change event is fired when file is selected
      el.bind('change',function(){
        scope.$apply(function(){
          ngModel.$setViewValue(el.val());
          ngModel.$render();
        });
      });
    }
  }
});

Example markup:

  <div ng-form="myForm">
    <input id="userUpload" ng-model="filename" valid-file name="userUpload" required type="file" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
    <button ng-disabled="myForm.$invalid" type="submit" class="btn btn-primary"><i class="icon-white icon-ok"></i>&nbsp;Ok</button>
    <p>
      Input is valid: {{myForm.userUpload.$valid}}
      <br>Selected file: {{filename}}
    </p>
  </div>

Check out my working plnkr example.

Sign up to request clarification or add additional context in comments.

7 Comments

I have already included SHIV for IE. I am going to put this code.will this work ?
I don't even know what your code does - my sniplet should be IE8 compatible. Include it, test it and if it doesn't work in IE8 create a new question
You can test run.plnkr.co/CEMX0RY3MX1TbcSZ in IE8 (I just did and it worked fine)
Your example throws an exception in jQuery.
@JonRimmer It's a little bug in the directive stackoverflow.com/questions/18383446/…
|
11

Extending @joakimbl code I will suggest the direct like this

.directive('validFile',function(){
    return {
        require:'ngModel',
        link:function(scope,el,attrs,ctrl){
            ctrl.$setValidity('validFile', el.val() != '');
            //change event is fired when file is selected
            el.bind('change',function(){
                ctrl.$setValidity('validFile', el.val() != '');
                scope.$apply(function(){
                    ctrl.$setViewValue(el.val());
                    ctrl.$render();
                });
            });
        }
    }
})

and in html you can use like this

<input type="file" name="myFile" ng-model="myFile" valid-file />
<label ng-show="myForm.myFile.$error.validFile">File is required</label>

2 Comments

It's kind of odd, but using your code properly sets myForm.myFile.$error.validFile to true, but ng-show is not working. Using myForm.myFile.$invalid is working properly. I don't get why is it. My angular inspector shows validFile as true...
Okay, I got it... i changed validFile to valid-file, and i was looking for myForm.myFile.$error.valid minus file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.