2

here's the situation. I've got an angular bootstrap dropdown that displays a list of "organizations" to be selected. It looks like this:

<button type="button" class="btn btn-primary dropdown-toggle" ng-disabled="disabled">
  <span class="caret"></span>
</button>
<ul class="dropdown-menu scrollable-menu" role="menu">
  <li ng-repeat="org in organizations | orderBy:'Name'"><a href="#" ng-click="pickNewOrg(org)">{{org.Name}}</a></li>
</ul>

I've also got a text input to allow for typing in the organization name, with angular's bootstrap typeahead and a custom validator to make sure the organization typed in is actually in my list of organizations. It looks like this:

<input name="organization" 
  type="text" 
  ng-model="activity.org" 
  typeahead="org as org.Name for org in organizations | filter:$viewValue" 
  valid-organization/> 

Here's the issue: the validation works fine if the text is typed into the input (where the validator's directive is), but the validation isn't called if an object is selected from the dropdown. So, if an incorrect organization is typed in, the validity is set to false, but if an organization is then clicked out of the menu, it remains false, not having been validated. Since anything clicked in the dropdown is valid, I'm wondering how I can re-use my validator on button click? Or perhaps another method would be better?

2
  • What happens if you add the valid-organization directive to the dropdown? Commented Jun 17, 2014 at 18:24
  • Nothin, when a button is clicked in the dropdown, the model changes on the scope, so the value in the input updates automatically, but doesn't trigger the validator in doing so. I wonder if there isn't a way to force the form to validate itself. Commented Jun 17, 2014 at 18:48

2 Answers 2

2

I had the same situation with my app and I decided to disable my add button if the item is not valid. In my case, I know that valid objects have a .id prop, so I did something like

    <input name="organization" 
  type="text" 
  ng-model="activity.org" 
  typeahead="org as org.Name for org in organizations | filter:$viewValue" />
  <button ng-click="doSomething()" ng-disabled="!activity.org.Name">Do Something</button>

In case an invalid organization was typed, you'll have just a text value in "activity.org" with no ".Name" property and thus the button will be disabled.

I'm not sure what you are doing with the selected organization, but I hope it gives you a direction. Anyhow, I don't see a simple way for you to re-use "valid-organization" in the dropdown.

Edit:

You can set your the validity manually using your form and input's name properties like this

$scope.formName.inputName.$setValidity('validOrganization',true);

Actually, it should work in your scenario even without it. Here's an attempt to recreate a simple fiddle to demonstrate - http://jsfiddle.net/B3WLH/ If you can, upload a minimal fiddle with the problem.

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

4 Comments

If I understand you correctly, this wouldn't allow me to type in something incorrect, change my mind and click the dropdown menu instead. For this application, I don't want that button ever disabled. It'd be great if I could just say "Hey form, validate yourself again" or have some way to explicitly set that validator to valid, whenever a button in the menu is clicked.
Hey Andy, I didn't mean to disable the dropdown, but the action that comes after the selection, but as it was not mentioned it's hard to know.
I updated my response above to include how to manually set the validation, but I tested a simple scenario and it looks like it should work.. if you can, upload a fiddle and I'll take a closer look :)
You are correct, the answer was in adding to $formatters in the directive as in your fiddle, not just $parsers, as was in my directive. I should've just posted my directive in the first place, but I didn't think that was relevant.
1

I tried this for over a day but could not get $setValidity to work as this question wanted. Instead, there is a property:

typeahead-editable="false"

in the typeahead library which kind of does the job. Its empties the input box on mouse out and also sets validity to false.

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.