简体   繁体   中英

Pre-Select the only item in dropdown AngularJS

I am trying to create an attribute directive (because I need to use this logic at multiple places in my project) for Select dropdown which automatically selects the only item if the items array has only one element. I have the following HTML with an attribute directive named smart-select-dropdown :

<select class="form-control" ng-model="selectedItem" smart-select-dropdown
          ng-options="item as item.name for item in items | filter: {someFilter}">
    <option value="" ng-bind="Select Item"></option>
</select>

Here is my directive code:

angular.module('app').directive('smartSelectDropDown', function(){
   return{
      restrict: 'A',
      replace: true,
      link: function(scope, element){
         angular.element(document).ready(function () {
                if(element[0].options.length === 2){
                    element.find('select option:nth-child(2)').prop('selected', true);
                }
         });
      }
   }
});

Here is the controller code:

angular.module('app').controller('MyCtrl', function($scope){
   $scope.selectedItem = null;
   $scope.items = [
                    { 
                      id : 1,
                      name : 'Item 1'
                    },
                    { 
                      id : 2,
                      name : 'Item 2'
                    },
                    { 
                      id : 3,
                      name : 'Item 3'
                    }
                  ];
});

The problem I am facing is that element[0].options.length is not giving me the correct length. It is always giving me 1 which is actually the default 'Select Item' option. It does not contain the length of ng-options which is actually required. Can anyone let me know what am I missing here?

PS: I am using AngularJS version 1.2.17

You can get the selectedItem and items from the controller to your directive scope, and check the condition and set selectedItem accordingly.

angular.module('app').directive('smartSelectDropDown', function(){
 return{
   restrict: 'A',
   replace: true,
   scope: {
  items: '=',
  selectedItem: '=selectedItem'
   }
   link: function(scope){
      if(scope.items.count == 1){
       scope.selectedItem = scope.items[0];
     }
    }
   });
  }
 }
});

Though, you might have to modify the code for some corrections as I have not tested it.

Note : if you are using directive just for this purpose, then follow @Rangamannar answer.

This can be achieved without a directive.

Controller Code changes:

angular.module('app').controller('MyCtrl', function($scope){
  $scope.items = [
                { 
                  id : 1,
                  name : 'Item 1'
                },
                { 
                  id : 2,
                  name : 'Item 2'
                }
              ]
  });
  $scope.selectedItem = items[1]; // or items[0] as per your requirement

HTML Code Changes:

 <select class="form-control" ng-model="selectedItem"
      ng-options="item as item.name for item in items track by item.id">
    <!-- You may choose to remove this first option tag with in select -->
    <option value="" ng-bind="Select Item"></option>
 </select> 

There is even no need of a directive in your case, you can just check the $scope.items length and assign the first element to ng-model if its length is 1

Controller:

angular.module('app').controller('MyCtrl', function($scope){
   $scope.selectedItem = null;
   $scope.items = [
    {
        id : 1,
        name : 'Item 1'
    },
    {
        id : 2,
        name : 'Item 2'
    }
    ]
    if($scope.items.length == 1){
        $scope.selectedItem = $scope.items[0];
    }
});

HTML:

<select class="form-control" ng-model="selectedItem" ng-options="item as item.name for item in items">
    <option value="" ng-bind="Select Item"></option>
</select>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM