Skip to content
This repository was archived by the owner on Oct 2, 2019. It is now read-only.

Conversation

dimirc
Copy link

@dimirc dimirc commented Jul 1, 2014

When using ng-required a red border on control is shown (styles added all 3 themes)

The styles will show only if the control is dirty and invalid, so to reproduce it you should first fill values on each field and then press Clear ng-model

You can try it with this plunker

screen shot 2014-07-01 at 12 15 59 am

@dimirc dimirc mentioned this pull request Jul 1, 2014
@dimirc dimirc added this to the 0.3.x milestone Jul 1, 2014
dimirc added a commit that referenced this pull request Jul 3, 2014
style(ngRequired): mark when invalid
@dimirc dimirc merged commit 521eaf4 into master Jul 3, 2014
@dimirc dimirc deleted the style-ngrequired branch July 3, 2014 21:18
@j-walker23
Copy link

Hey guys, should this be working for the multiple attribute as well?

@hatpick
Copy link

hatpick commented Nov 6, 2014

+1 for multiple

@abobwhite
Copy link

+1 more for multiple. Hitting a roadblock now that I find out this isn't supported. Has anyone come up with a solution?

@hatpick
Copy link

hatpick commented Jan 27, 2015

@abobwhite Yes, you can watch the ng-model, if the selected array is empty $setValidity("required", false), otherwise $setValidity("required", true)

@ahuang321
Copy link

+1 for multiple

@jmorvan
Copy link

jmorvan commented May 29, 2015

@hatpick thank you!

I got it working like a charm with the following directive:

myModule.directive('uiSelectRequired', function () {
    return {
        require: 'ngModel',
        link: function (scope, element, attrs, ngModel) {
            scope.$watch(function () {
                return ngModel.$modelValue;
            }, function (newValue) {
                if (ngModel.$modelValue && ngModel.$modelValue.length) {
                    ngModel.$setValidity("required", true);
                }
                else {
                    ngModel.$setValidity("required", false);
                }
            });
        }
    };
});

@ma-zal
Copy link

ma-zal commented Jul 15, 2015

Better version without "$watch":

angular.module( "myApp" )
    .directive( 'uiSelectRequired', function() {
        return {
            require: 'ngModel',
            link: function( scope, element, attrs, ngModelController ) {
                var idName = attrs.name;
                ngModelController.$validators[idName] = function( modelValue, viewValue ) {
                    return modelValue !== undefined && modelValue !== null && modelValue && modelValue.length > 0;
                };
            }
        };
    });

@zjhiphop
Copy link

zjhiphop commented Aug 6, 2015

Cool!!

@tb
Copy link

tb commented Sep 9, 2015

I use this with angular-fromly for validate ui-select with multiple:

.directive('multipleRequired', function() {
  return {
    require: 'ngModel',
    link: function (scope, element, attrs, ngModel) {
      if (attrs.multipleRequired) {
        ngModel.$validators.multipleRequired = function(modelValue, viewValue) {
          return !!(modelValue || viewValue).length
        }
      }
    }
  };
})

Template:

<ui-select multiple ng-model="model[options.key]"
           multiple-required="{{to.required}}"
           ng-disabled="{{to.disabled}}">
...
</ui-select>

@dsalvagni
Copy link

Hey, guys!
I just made some changes to your code to enable/disable the required option.

.directive('uiSelectRequired', function(){
  return {
            restrict: "A",
            require: '^ngModel',
            scope: {
              uiSelectRequired:"="
            },
            link: function(scope, elm, attrs, ngModel) {
                ngModel.$validators.uiSelectRequired = function(modelValue, viewValue) {
                    var determineVal;
                    if (angular.isArray(modelValue)) {
                        determineVal = modelValue;
                    } else if (angular.isArray(viewValue)) {
                        determineVal = viewValue;
                    } 

                    return scope.uiSelectRequired ? determineVal.length > 0 : true;
                };
            }
        };
})

Template:

<ui-select multiple ng-model="...">
<ui-select-match ui-select-required="!filterModel.allOptions">
    {{$item.name}}
</ui-select-match>
<ui-select-choice>
    <div ng-bind-html="item.name | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>

@ma-zal
Copy link

ma-zal commented Nov 10, 2015

You are using ngModel.$validators.uiSelectRequired = ...
How does it works if you have more ui-selects in one <form> ?

It is because I used:

var idName = attrs.name;
ngModelController.$validators[idName] = ...

Is my way right or wrong?

@arkarkark
Copy link
Contributor

@dsalvagni I misread your template and added ui-select-required to the ui-select element and had a problem with two directives wanting different isolate scopes. it was easily fixed with removing the scope: from the directive object and replacing the return line with.

return scope.$eval(attrs.uiSelectRequired) ? determineVal.length > 0 : true;

(could also be !scope.$eval(attrs.uiSelectRequired) || determineVal.length > 0 )

It makes more sense to me to put this on the ui-select element since that's the one with the ng-model on it. (similar to ng-model and ng-required elsewhere).

@dsalvagni
Copy link

Great point, @arkarkark. Thanks for sharing it.

You're right, it makes more sense. I tried to add ui-select-required to the ui-select element but I had the same problem that you mentioned. I didn't realized that I could use the scope.$eval to execute an expression on an attribute. I'll fix my code.

The second point, about the return statement, I think this is more readable:

return scope.$eval(attrs.uiSelectRequired) ? determineVal.length > 0 : true;

@arkarkark
Copy link
Contributor

yeah, I kinda agree wth you on the return value @dsalvagni 👍

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.