The main reason your code doesn't work is because you are not using $compile again on the element, once you have added the attribute.
Angular needs to re-parse the element and run the 'ng-required' directive after you have added it as an attribute, otherwise angular doesn't know about it because the DOM has already been rendered.
The other thing is that you can do so during the compile phase rather than the link phase as I can see that you are not using anything from the scope.
So here is what you can do:
angular.module('app')
.directive('customDirective', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true,
priority: 1000,
compile: function compile(element, attrs) {
element.attr('required', 'required');
element.removeAttr("custom-directive"); //remove the attribute to avoid indefinite loop
$compile(element)(scope);
}
};
});
You can read more in this SO answer