1

Using angularjs and material, I want to be able to have a readonly textbox that displays the name for a selected object a user looks up (via a modal popup), but the textbox validation should show as required and fire off if a separate id property is not populated. Here is an example plnkr.

I was originally thinking that I could do this simply by adding a hidden field with an ng-model, name, and required attribute, it would create the associated form property for the field with required validator (which it does), and I would be able to show the validator on the readonly textbox like so:

<form name="myCtrl.myForm" novalidate>
  <input type="hidden" ng-model="myCtrl.id" name="id" required />
  <div layout="row">
    <md-input-container flex="50">
        <label>Selected Object</label>
        <input ng-model="myCtrl.selectedObject.selectedText" readonly />
        <div ng-messages="myCtrl.myForm.id.$error">
            <div ng-message="required">Please select an object.</div>
        </div>
    </md-input-container>
    <div>
        <md-button class="md-icon-button md-primary" ng-click="myCtrl.select($event)">
            <md-tooltip md-direction="top">
                Select Object
            </md-tooltip>
            <md-icon>search</md-icon>
        </md-button>
    </div>
  </div>
  <div>
    <md-button class="md-raised md-primary" type="submit">Submit</md-button>
  </div>
</form>

JS:

vm.select = function(evt) {
  // Set the selected Object
  vm.selectedObject = { selectedText: "Object id 1 selected", id: 1 };
  // Set the associated ID
  vm.id = 1;

};

However, the <div ng-message="required">Please select an object.</div> never displays when the form is submitted and validation fires. Any idea how I can accomplish this?

1 Answer 1

0

While I was typing up this question I had an idea - perhaps I should be creating a custom validator that I can apply to this input which references a separate property. That appeared to do what I needed. Here's the plnkr and here's the directive:

angular.module('MyApp', ['ngMessages', 'ngMaterial'])
  .directive('requiredOther', RequiredOther);

function RequiredOther() {

    return {
        require: "ngModel",
        scope: {
            requiredOtherValue: "=requiredOther"
        },
        link: function(scope, element, attributes, ngModel) {
            ngModel.$validators.requiredOther = function(modelValue) {
                return scope.requiredOtherValue !== undefined && scope.requiredOtherValue !== null && scope.requiredOtherValue !== '';
            };

            scope.$watch("requiredOtherValue", function() {
                ngModel.$validate();
            });
        }
    };
}

This is the updated HTML:

<form name="myCtrl.myForm" novalidate>
  <input type="hidden" ng-model="myCtrl.id" />
  <div layout="row">
    <md-input-container flex="50">
        <label>Selected Object</label>
        <input name="id" ng-model="myCtrl.selectedObject.selectedText" readonly required-other="myCtrl.id" />
        <div ng-messages="myCtrl.myForm.id.$error">
            <div ng-message="requiredOther">Please select an object.</div>
        </div>
    </md-input-container>
    <div>
        <md-button class="md-icon-button md-primary" ng-click="myCtrl.select($event)">
            <md-tooltip md-direction="top">
                Select Object
            </md-tooltip>
            <md-icon>search</md-icon>
        </md-button>
    </div>
  </div>
  <div>
    <md-button class="md-raised md-primary" type="submit">Submit</md-button>
  </div>
</form>

The required-other="myCtrl.id" directive references the id property and watches for changes and fires off validation on change:
I guess I don't really need the hidden input field anymore either.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.