AngularJS Set Input Required in Directive

2.2k views Asked by At

I need to dynamically make an input field required (or not) and would like to set this value in a directive. I know there is the ng-required directive and can be set as ng-required="datamodel.required" but ultimately, I want to pull a settings object in the directive and turn on/off the required parameter based on that config. The config is in a service and I don't want to inject the service for each of my form controller - hence why I am needing to set this up in a directive.

Here is a JSFiddle starting point: http://jsfiddle.net/hm2b771z/2/

app.directive('requiredConfig', function($compile){
    return {
        link: function(scope, element, attrs){
            console.log(attrs.requiredConfig);
            console.log(attrs.ngRequired);
            attrs.ngRequired = (attrs.requiredConfig == "true") ? true : false;
            $compile( element.contents() )( scope );
            console.log(attrs.ngRequired);
            console.log('_______________________');
        }
    }
});

What I expect is the field that is the first field option to be required while the second one remains optional.

Thanks!

2

There are 2 answers

0
SM Adnan On

Instead of

attrs.required = (attrs.requiredConfig == "true") ? true : false;

Use

if (attrs.requiredConfig == "true"){
    element.attr('required', 'true');
}
0
snazzyHawk On

Here's what I ended up doing thanks to Angular directive how to add an attribute to the element?:

angular.module( 'app' )
.directive
(
    'requiredByConfig',
    function( $compile, Utils ){
        var directive = {
            terminal: true,
            priority: 1001,
            compile: function( element, scope ){
                var configKey = element.attr( 'required-by-config' );
                var req = Utils.getRequiredFromConfig(configKey) // Injected;

                // Remove this directive in order to avoid infinite compile loop.
                element.removeAttr( 'required-by-config' );

                // Add the required directive with the required value.
                element.attr( 'ng-required', req );

                // Compile the new directive
                $compile( element.contents() )( scope );

                var fn = $compile( element );
                return function( scope ){
                    fn( scope );
                };
            }
        };

        return directive;
    }
);

However, a much better solution was to use a filter:

angular.module( 'app' ).filter
( 'requiredByConfig',
    function( Utils ){
        return function( initialValue, configKey, visible ){
            if( angular.isDefined( visible ) && !visible ){
                // If the input is hidden, we don't want to require it.
                return false;
            }

            // Get the config setting. If available, overwrite the default.
            if( angular.isDefined( Utils.SETTINGS[ configKey ] ) ){
                // A config exists for this field. Return the value of the config.
                return Utils.getBoolean( Utils.SETTINGS[ configKey ] );
            } else {
                // Return the initial required value
                return initialValue;
            }
        }
    }
)