Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to pass 'required' into an AngularJS directive?

I'm making a custom auto-complete directive that uses an <input> within itself, but I'm having a bit trouble figuring out how to pass the 'required' attribute down, other attributes that have values I can see but 'required' appears to be blank whether it is set or not. The first part of my return statement below:

return {
            restrict: 'E',
            template: tpl,
            replace: true,
            scope: {
                suggestionsPath: '=autoComplete',
                method: '@method',
                term: '@term',
                required: '@required',
                ngModel: "="
            }...

thanks!

like image 582
kreek Avatar asked Oct 14 '13 23:10

kreek


People also ask

What is restrict in AngularJS directive?

Restrict. Angular allows us to set a property named restrict on the object we return on our directive definition. We can pass through a string with certain letters letting Angular know how our directive can be used. function MyDirective() { return { restrict: 'E', template: '<div>Hello world!

Which of the following is not a AngularJS directive?

ng-state is not an AngularJS directive. Q 15 - Which of the following is true about ng-app directive? A - ng-app directive defines and links an AngularJS application to HTML.

What are the directive scopes in AngularJS?

The directive scope uses prefixes to achieve that. Using prefixes helps establish a two-way or one-way binding between parent and directive scopes, and also make calls to parent scope methods. To access any data in the parent scope requires passing the data at two places – the directive scope and the directive tag.


2 Answers

I've built a few extensions to inputs and the best (arguably) only way to extend existing ngModel bindings is using the ngModelController in your directive. You can require another directive's controller by using the "require" property. The documentation for ngModelController is here

This will allow you to get/set the model values as well as extend or replace the validation behavior as needed. Because you are now probably extending in combination AngularJS input directives you will also probably want to look at the input directives inside AngularJS for examples of how this work. They also can work in tangent with the ngFormController as a parent for the whole form. This took me a while to grasp so be patient but it is by far the best way to do this.

I would avoid isolate scopes here, they can be tricky, don't always play well with other directives (so typically only use it on new elements or things where only one directive will exists on it's own). I would design something like this:

return {
        restrict: 'E',
        template: tpl,
        replace: true,
        require: 'ngModel',
        link: function(scope, element, attrs, ngModelController) {
           // Use attrs to access values for attributes you have set on the lement
           // Use ngModelController to access the model value and add validation, parsing and formatting
           // If you have an attribute that takes an expression you can use the attrs value along with $scope.$watch to check for changes and evaluate it or the $parse service if you just want to evaluate it.
        }

I recommend getting as familiar as you can with directive design as custom inputs can get pretty tricky depending on what they do (we have built custom inputs that add +/- buttons as well as ones that format numbers as percentages, currencies or just numbers with commas while you type into them). Aside from the ngModelController docs these are useful to review:

  • Egghead.io tutorials
  • The AngularJS code for input directives and forms
like image 137
Chris Nicola Avatar answered Oct 18 '22 10:10

Chris Nicola


Required is a bit of a funny attribute by itself (see here Setting an attribute named "required" and any value, with JQuery, doesn't work). You will likely have a lot of trouble passing any sort of value through on this as its effect is determined by whether it is present, not by its value. Different browsers will treat it differently and may rewrite the value.

You will also have trouble because both required and ngModel are directives that will be compiled on your element if they are provided. required will talk to ngModel and you will need to implement ngModel properly if you want things to work.

A simpler option is to rename required and ngModel to other names. e.g. myRequired and myNgModel. You can then bind ng-model directly to scope.myNgModel and bind an ng-required to myRequired.

like image 30
Andyrooger Avatar answered Oct 18 '22 10:10

Andyrooger