Allow manually entered text in ui-select

后端 未结 5 556
北海茫月
北海茫月 2020-12-05 13:24

I am using a select box from ui-select. All is working fine, but I want to allow manually entered text and do not want to restrict the user from the values available in the

相关标签:
5条回答
  • 2020-12-05 13:39

    You could use the tagging attribute as explained in the documentation: https://github.com/angular-ui/ui-select/wiki/ui-select

    <ui-select multiple tagging tagging-label="(custom 'new' label)" ng-model="multipleDemo.colors">
    ...
    </ui-select>
    
    0 讨论(0)
  • 2020-12-05 13:39

    I use keyup to add a new option represents the text entered. With this approach, if user press enter, they can select what they have input so far (the default active item is the first item).

    This supports both cases when the data list contains plain text or object (attribute value-prop is required).

    Directive:

    commonApp.directive("uiSelectFreeText", function () {
        return {
            restrict: "A",
            require: "uiSelect",
            link: function (scope, element, attrs, $select) {
                var searchInput = element.querySelectorAll("input.ui-select-search");
    
                if (searchInput.length !== 1) {
                    console.log("Error! Input not found.");
                    return;
                }
    
                searchInput.on("keyup", function () {
                    var valueProp = attrs["valueProp"];
                    var addNewObjOption = function () {
                        // add new item represent free text option
                        var newOption = { isFreeText: true };
                        newOption[valueProp] = $select.search;
                        $select.items.unshift(newOption);
                    };
    
                    if ($select.items.length > 0) {
                        var firstItem = $select.items[0];
    
                        if (valueProp) {
                            // items is list of Object
                            if (firstItem.isFreeText) {
                                firstItem[valueProp] = $select.search;
                            } else {
                                addNewObjOption();
                            }
                        } else {
                            // items is list of string
                            if (firstItem === $select.search) {
                                return;
                            } else {
                                $select.items.push($select.search);
                            }
                        }
                    } else {
                        if (valueProp) {
                            addNewObjOption();
                        } else {
                            // items is list of string
                            $select.items.push($select.search);
                        }
                    }
                });
            }
        };
    });
    

    HTML:

    <ui-select class="ui-select-control"
               ui-select-free-text value-prop="Label"
               ng-model="keyword">
    </ui-select>
    
    0 讨论(0)
  • 2020-12-05 13:43

    I think I found a way to allow the user to create new entries. Use the "on-select" attribute to pass a function that takes $select as a parameter as below:

    <ui-select ng-model="person.selected"
          theme="select2"
          on-select="peopleSel($select)"
          tagging
          reset-search-input="false"
          >
    
        <ui-select-match placeholder="Enter a name...">{{$select.selected.name}}</ui-select-match>
        <ui-select-choices repeat="sel in people | filter: {name: $select.search}">
        <div ng-bind-html="sel.name | highlight: $select.search"></div>
        </ui-select-choices>
      </ui-select>
    

    Then create the function that adds a new entry when the clickTriggeredSelect variable is false:

    $scope.peopleSel= function(sel) {
      if ( sel.search && ! sel.clickTriggeredSelect ) {
        if ( ! sel.selected || sel.selected.name != sel.search ) {
          //Search for an existing entry for the given name
          var newOne= personSearch( sel.search ); 
          if ( newOne === null ) {
            //Create a new entry since one does not exist
            newOne= { name: sel.search, email: 'none', country: 'unknown' };
            $scope.people.push( newOne );
          }
          //Make the found or created entry the selected one
          sel.selected= newOne;
        }
      }
      sel.search= ''; //optional clearing of search pattern
    };
    

    Note that personSearch definition is not provided here. Also this approach of testing the clickTriggeredSelect can be used to allow the user to unselect the field if a blank entry is the preference.

    PVC

    0 讨论(0)
  • 2020-12-05 13:57

    I've forked the ui-select project to allow this functionality through the allow-free-text attribute

    <ui-select allow-free-text="true" ng-model="ctrl.freeTextDemo.color2" theme="bootstrap" style="width: 800px;" title="Choose a color">
        <ui-select-match placeholder="Select color...">{{$select.selected}}</ui-select-match>
        <ui-select-choices repeat="color in ctrl.availableColors | filter: $select.search">
          <div ng-bind-html="color | highlight: $select.search"></div>
        </ui-select-choices>
    </ui-select>
    

    Here is the plnker

    Until my pull request is accepted by the angular-ui team, you can get the ui-select build that includes my patch on my own repo

    0 讨论(0)
  • 2020-12-05 14:02

    here is a solution:

    HTML -

    <ui-select ng-model="superhero.selected">
      <ui-select-match placeholder="Select or search a superhero ...">{{$select.selected}}</ui-select-match>
      <ui-select-choices repeat="hero in getSuperheroes($select.search) | filter: $select.search">
        <div ng-bind="hero"></div>
      </ui-select-choices>
    </ui-select>
    

    CONTROLLER -

    $scope.getSuperheroes = function(search) {
     var newSupes = $scope.superheroes.slice();
      if (search && newSupes.indexOf(search) === -1) {
        newSupes.unshift(search);
      }
      return newSupes;
    }
    

    Here is the CodePen solution.

    0 讨论(0)
提交回复
热议问题