2
votes

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? - Austin Mullins
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. - tarrball

2 Answers

2
votes

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.

1
votes

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.