Form validation - Required one of many in a group

后端 未结 8 1215
时光取名叫无心
时光取名叫无心 2020-12-05 18:31

In the project I\'m working on at the moment I currently have three textboxes and I need to validate that at least one of the text boxes has been populated.

I\'ve be

8条回答
  •  不思量自难忘°
    2020-12-05 19:17

    Here is a refactored take on ExpertSystems great post. I didn't need the destroy method so I gutted it.

    I also added a grayed out explanation that may help in your code. I use this directive for ALL my required fields. Meaning when I use this directive I no longer use ng-required, or required.

    If you want a field required just pass in a unique group name. If you don't want the field required then pass in null, and if you want to have many different groups just pass in a matching group name.

    I believe there is a little more refactoring that could be done here. Angularjs states that when using $setValidity, that instead you should use $validators pipeline instead, but I could not get that to work. I am still learning this complex animal. If you have more info, post it!

    app.directive('rsPartiallyRequired', function () {
    
     var allinputGroups = {};
    
     return {
       restrict: 'A',
       require: '?ngModel',
       scope: { },
    
       link: function(scope, elem, attrs, ctrl) {
         if( !ctrl || !attrs.rsPartiallyRequired ){ return } // no ngModel, or rsPartialRequired is null? then return.
    
        // Initilaize the following on load
        ctrl.$formatters.push( validateInputGroup ); // From model to view.
        ctrl.$parsers.unshift( validateInputGroup ); // From view to model.
    
        if ( ! allinputGroups.hasOwnProperty( attrs.rsPartiallyRequired )){ // Create key only once and do not overwrite it.
        allinputGroups[ attrs.rsPartiallyRequired ] = { isRequired: true } // Set new group name value to { isRequired: true }.
      }
    
        scope.inputGroup = allinputGroups[ attrs.rsPartiallyRequired ] // Pass { isRequired: true } to form scope.
    
        function validateInputGroup(value) {
        scope.inputGroup[ scope.$id ] = !ctrl.$isEmpty( value ); // Add to inputGroup ex: { isRequired: true, 01E: false }.
        scope.inputGroup.isRequired = setRequired( attrs.rsPartiallyRequired ); // Set to true or false.
        updateValidity(); // Update all needed inputs based on new user input.
        return scope.inputGroup.isRequired ? undefined : value
      }
    
        function setRequired(groupName) {
          if( ! allinputGroups[ groupName ] ){ return false } // No group name then set required to false.
          return Object.keys( allinputGroups[ groupName ] ).every( function( key ) { // Key is 'isRequired' or input identifier.
          return ( key === 'isRequired' ) || ! allinputGroups[ groupName ][ key ]
        });
      }
    
        scope.$watch('scope.inputGroup.isRequired', updateValidity); // Watch changes to inputGroup and update as needed.
    
        function updateValidity() { // Update input state validity when called.
          ctrl.$setValidity('required', scope.inputGroup.isRequired ? false : true );
        } 
      }
     }
    });
    
    // This directive sets input required fields for groups or individual inputs.  If an object in the template is given
    // to the directive like this: 
    // Object: { "name": "account_number", "attrs": { "required": { "group": "two"  }}}.
    // HTML: 
    // Or anything where the evaluation is a string, for example we could use "groupOne" like this...
    // HTML: 
    // Then this directive will set that group to required, even if it's the only member of group.  
    // If you don't want the field to be required, simply give the directive a null value, like this...
    // HTML: 
    // However, when you want to use this directive say in an ngRepeat, then just give it a dynamic string for each input
    // and link the inputs together by giving the exact matching string to each group that needs at least one field. ex:
    
    // 
    // 
    // 
    // 
    // 
    // 
    // 
    // 
    
    // In the above example, the first and fifth input are not required and can be submitted blank.
    // The input with group "two" is the only one in the group, so just that input will be required by itself.
    // The 2 inputs with "one" will be grouped together and one or the other will require an input before
    // the form is valid.  The same will be applied with group "three".
    // For this form to be valid, group "two" will be required, and 1 input from group one will be required,  
    // and 1 input from group three will be required before this form can be valid.
    

提交回复
热议问题