angular-ui / ui-select

AngularJS-native version of Select2 and Selectize
MIT License
3.26k stars 1.81k forks source link

Selecting an item not in the list #1409

Open tharrington opened 8 years ago

tharrington commented 8 years ago

how can i select (or add) an item that is not in the list? I.e. when a user starts typing and filters to the point where there isnt a match, an option to create a new entry appears.

 <ui-select ng-model="order.email" theme="bootstrap">
      <ui-select-match placeholder="Search by email...">{{order.email}}</ui-select-match>
      <ui-select-choices repeat="item in customers | filter: $select.search">
        <div ng-bind-html="item.email | highlight: $select.search"></div>
      </ui-select-choices>
    </ui-select>
user378230 commented 8 years ago

See wiki: https://github.com/angular-ui/ui-select/wiki/ui-select

option description value default
tagging Enable tagging mode (add new items on the fly). Accepts a string which is a scope function. If your model is an array of objects, this string is required. The function will be passed the new item as a string and should return an object which is the transformed value to be pushed to the items array. string ($scope function) undefined
tagging-label Set a label for tags that appear in the dropdown. Expects a string or false. If false, then tagging happens without new items appearing in the dropdown. If empty or undeclared, tagging-label defaults to (new) string, boolean undefined

Example: https://github.com/angular-ui/ui-select/blob/master/examples/demo-tagging.html

tharrington commented 8 years ago

I'm getting a bunch of errors with these examples... One is if I don't even type anything and maybe a selection from the dropdown then switch the selection I get an error:

TypeError: g.selected.filter is not a function

code:

<ui-select tagging="tagTransform" ng-model="order.customer" theme="bootstrap">
                  <ui-select-match placeholder="Enter email...">{{$select.selected.email}}</ui-select-match>
                  <ui-select-choices repeat="customer in customers | filter: $select.search">
                    <div ng-if="customer.isTag" ng-bind-html="customer.email +' <small>(new)</small>'| highlight: $select.search"></div>
                    <div ng-if="!customer.isTag" ng-bind-html="customer.email | highlight: $select.search"></div>
        </ui-select-choices>
    </ui-select>
 $scope.tagTransform = function(tag) {
        var newCustomer = {
        first_name: '',
        last_name: '',
        email: tag.toLowerCase()
        };
        $scope.order.email = newCustomer.email;
        return newCustomer;

    }

When I start typing, another error appears:

Uncaught TypeError: Cannot read property 'length' of undefinedd @ select.min.js:7(anonymous function) @ select.min.js:7jQuery.event.dispatch @ jquery.js:4435elemData.handle @ jquery.js:4121

darioml commented 8 years ago

Did you end up getting this to work?

Looking at a non-multiple select object that lets me dynamically add values to the list. Seems similar here?

user378230 commented 8 years ago

There were some fixes that recently went in for single select tagging (#1439)

@darioml are you using the latest version of ui-select with this fix?

andrecbr commented 8 years ago

@user378230 I used the latest version in this plnkr but without success, do you have any idea what's wrong?

darioml commented 8 years ago

Using the latest (1.4.9 angular, 1.14.9 ui-select) with no luck. My tagging function is not even being called.

user378230 commented 8 years ago

Guess tagging with single select isn't currently supported.

PRs would be welcome I'm sure...

sqwk commented 8 years ago

Using v0.16.1 and v1.5.3 I do not get any error messages but new elements are not added to the array; they are simply ignored and the input is reset to the value before.

user378230 commented 8 years ago

As a workaround you can use multiple select mode with limit="1" https://github.com/angular-ui/ui-select/pull/1110

darioml commented 8 years ago

Have to say that's not a workaround, rather a different feature set. "multiple" changes the UI elements & UX.

I implemented this by using a custom filter. My list of options has an element with ID: new. The value / text for it is changed by my filter.

.filter('allowNew', ['$filter', $filter =>
    (input, optional1) => {
        let filtered = $filter('filter')(input, { name: optional1 });
        if (filtered) { filtered = $filter('filter')(filtered, { id: '!new' }); }

        if (optional1 && optional1.length > 1 && filtered) {
            const newone = $filter('filter')(input, { id: 'new' }, true);
            if (newone) {
                newone[0].name = optional1;
                filtered.push(newone[0]);
            }
        }
        return filtered;
    },
])

Not the best code, but worked.

solerman commented 8 years ago

Seemed to works for me setting tagging-label="false" but causes other problems

nielk commented 8 years ago

I encountered the same issue, my tagging function is not called, PR would be welcome…

gine commented 7 years ago

@darioml i don't understand how i can use you code. where i must call the filter? can you make me an example?