Comment avoir une option par défaut dans la boîte de sélection Angular.js

311

J'ai cherché sur Google et je ne trouve rien à ce sujet.

J'ai ce code.

<select ng-model="somethingHere" 
        ng-options="option.value as option.name for option in options"
></select>

Avec des données comme celle-ci

options = [{
   name: 'Something Cool',
   value: 'something-cool-value'
}, {
   name: 'Something Else',
   value: 'something-else-value'
}];

Et la sortie est quelque chose comme ça.

<select ng-model="somethingHere"  
        ng-options="option.value as option.name for option in options" 
        class="ng-pristine ng-valid">

    <option value="?" selected="selected"></option>
    <option value="0">Something Cool</option>
    <option value="1">Something Else</option>
</select>

Comment est-il possible de définir la première option dans les données comme valeur par défaut afin d'obtenir un résultat comme celui-ci.

<select ng-model="somethingHere" ....>
    <option value="0" selected="selected">Something Cool</option>
    <option value="1">Something Else</option>
</select>
iConnor
la source
3
Ce serait bien s'il y avait une réponse qui ne supposait pas que l'angulaire était utilisé pour construire les options. Que faire si les options font déjà partie du balisage?
pspahn
1
@pspahn - selon docs.angularjs.org/api/ng/directive/ngOptions : seulement a **single** hard-coded <option> element ... can be nested into the <select> element.Les options ne pouvaient pas déjà faire partie du balisage.
Le DIMM Reaper
1
@pspahn qui ne répondrait pas au PO, mais une question bien différente ...
Mario Trucco

Réponses:

366

Vous pouvez simplement utiliser ng-init comme ceci

<select ng-init="somethingHere = options[0]" 
        ng-model="somethingHere" 
        ng-options="option.name for option in options">
</select>
zs2020
la source
20
J'ai eu un problème avec ce travail, c'est que j'utilisais 'track by', le supprimant a résolu le problème, juste au cas où cela
aiderait
61
Rien de mal à cette réponse, mais ng-init a échoué pour moi dans mon cas spécifique. Le problème était que la valeur que j'utilisais n'était pas encore disponible au moment où ng-init a fonctionné: j'ai obtenu la valeur via un appel ajax et à ce moment le ng-init était déjà terminé. En fin de compte, j'ai utilisé un observateur sur cette valeur et dans cette fonction, j'ai fait la même chose que dans ng-init. Ça a marché.
maurits
2
J'ai également eu des problèmes pour que cela fonctionne, le commentaire de @maurits m'a conduit à ce stackoverflow.com/questions/22348886 Profitez-en!
Michael
5
La documentation d'Angular dit de mieux utiliser la portée $ du contrôleur pour initialiser ce type de valeurs docs.angularjs.org/api/ng/directive/ngInit
Fortuna
3
avertissement: l'utilisation de ng-init à cet effet peut entraîner des appels excessifs à la méthode $ digest (), ce qui peut faire en sorte que la sortie de votre console soit tout rouge et moche avec des messages comme "10 $ digest () itérations atteintes. Abandon!"
DMac the Destroyer
235

Si vous voulez vous assurer que votre $scope.somethingHerevaleur n'est pas écrasée lors de l'initialisation de votre vue, vous voudrez fusionner ( somethingHere = somethingHere || options[0].value) la valeur dans votre ng-init comme ceci:

<select ng-model="somethingHere" 
        ng-init="somethingHere = somethingHere || options[0].value"
        ng-options="option.value as option.name for option in options">
</select>
Ben Lesh
la source
22
Cette solution a bien fonctionné et est meilleure que la réponse sélectionnée.
MJ
le ng-init ne devrait-il pas ressembler à ceci ng-init = "somethingHere = somethingHere || options [0]" ??
infinitloop
1
Comment gérer le fait d' optionsêtre vide? Comme en cas de optionsdonnées provenant d'une source externe.
null
1
@suud, il vous suffit de vérifier les options && options.length> 0 dans votre ng-init. Vraiment, la plupart de cela devrait être fait dans votre contrôleur, donc c'est testable.
Ben Lesh
@BenLesh Si je veux écrire du texte (chaîne) au lieu de la première option. ng-init="somethingHere= somethingHere || 'Select one' " j'ai essayé comme ça. mais ça n'a pas marché. ce qui ne va pas dans mon code
codelearner
69

Essaye ça:

HTML

<select 
    ng-model="selectedOption" 
    ng-options="option.name for option in options">
</select>

Javascript

function Ctrl($scope) {
    $scope.options = [
        {
          name: 'Something Cool',
          value: 'something-cool-value'
        }, 
        {
          name: 'Something Else',
          value: 'something-else-value'
        }
    ];

    $scope.selectedOption = $scope.options[0];
}

Plunker ici .

Si vous voulez vraiment définir la valeur qui sera liée au modèle, changez l' ng-optionsattribut en

ng-options="option.value as option.name for option in options"

et le Javascript pour

...
$scope.selectedOption = $scope.options[0].value;

Un autre plongeur ici considérant ce qui précède.

Michael Benford
la source
2
Le problème est que je devrais le faire pour de nombreuses boîtes de sélection.
iConnor
Je ne l'ai pas compris. Que feriez-vous?
Michael Benford
Je devrais le faire manuellement pour peut-être plus de 50 boîtes sélectionnées
iConnor
Vous voulez dire définir la valeur par défaut pour chaque case de sélection? Si oui, je suppose que ce n'est pas clair dans votre question. Quoi qu'il en soit, ai-je raison de supposer que vous devrez charger les articles dans chaque boîte de sélection? Si c'est le cas, je ne pense pas que l'initialisation de leurs valeurs par défaut serait un gros problème.
Michael Benford
1
Mon problème est que l'index de l'option est renvoyé à partir d'une "soumission" sur le formulaire. Ce dont j'ai besoin, c'est de ce que vous appelez option.name, qui est ce qui a été renvoyé à partir d'un ancien formulaire de rails. La case à cocher et les boutons radio fonctionnent correctement puisque vous utilisez ng-repeat pour obtenir le balisage correct. Comment puis-je obtenir l'option.name retourné au moment de la soumission du formulaire?
pferrel
40

Une seule réponse de Srivathsa Harish Venkataramana mentionnéetrack by qui est en effet une solution pour cela!

Voici un exemple avec Plunker (lien ci-dessous) de la façon d'utiliser track bydans select ng-options :

<select ng-model="selectedCity"
        ng-options="city as city.name for city in cities track by city.id">
  <option value="">-- Select City --</option>
</select>

Si selectedCityest défini sur la portée angulaire et qu'il a une idpropriété avec la même valeur que n'importe laquelle idde cityla citiesliste, il sera automatiquement sélectionné lors du chargement.

Voici Plunker pour cela: http://plnkr.co/edit/1EVs7R20pCffewrG0EmI?p=preview

Voir la documentation source pour plus de détails: https://code.angularjs.org/1.3.15/docs/api/ng/directive/select

mikhail-t
la source
1
Merci ça m'a aidé;)
Brahim LAMJAGUAR
1
Impressionnant! Merci!
Iurii Golskyi,
33

Je pense que, après l'inclusion de «track by», vous pouvez l'utiliser dans ng-options pour obtenir ce que vous vouliez, comme suit

 <select ng-model="somethingHere" ng-options="option.name for option in options track by option.value" ></select>

Cette façon de faire est meilleure car lorsque vous souhaitez remplacer la liste de chaînes par une liste d'objets, vous allez simplement changer cela en

 <select ng-model="somethingHere" ng-options="object.name for option in options track by object.id" ></select>

où quelque chose est bien sûr un objet avec le nom et l'identifiant des propriétés. Veuillez noter que 'as' n'est pas utilisé de cette façon pour exprimer les options ng, car il ne définira que la valeur et vous ne pourrez pas la changer lorsque vous utilisez track by

Srivathsa Harish Venkataramana
la source
C'est ce qui a fonctionné pour moi. Je pense que angular avait besoin de quelque chose pour identifier l'objet dans le modèle de mon oscilloscope comme équivalent à un choix de la liste de référence. "track by guarantor.code" a fait l'affaire!
markbaldy
22

La réponse acceptée utilise ng-init, mais le document dit d'éviter si possible ng-init.

La seule utilisation appropriée de ngInit est d'aliaser les propriétés spéciales de ngRepeat, comme le montre la démonstration ci-dessous. Outre ce cas, vous devez utiliser des contrôleurs plutôt que ngInit pour initialiser des valeurs sur une étendue.

Vous pouvez également utiliser ng-repeat au lieu de ng-optionspour vos options. Avec ng-repeat, vous pouvez utiliser ng-selectedavecng-repeat des propriétés spéciales. c'est-à-dire $ index, $ impair, $ even pour que cela fonctionne sans aucun codage.

$first est l'une des propriétés spéciales ng-repeat.

  <select ng-model="foo">
    <option ng-selected="$first" ng-repeat="(id,value) in myOptions" value="{{id}}">
      {{value}}
    </option>
  </select>

---------------------- EDIT ----------------
Bien que cela fonctionne, je préférerais @ mik-t's répondez lorsque vous savez quelle valeur sélectionner, https://stackoverflow.com/a/29564802/454252 , qui utilise track-byet ng-optionssans utiliser ng-initou ng-repeat.

Cette réponse ne doit être utilisée que lorsque vous devez sélectionner le premier élément sans savoir quelle valeur choisir. par exemple, je l'utilise pour la complétion automatique qui nécessite de choisir le premier élément tout le temps.

allenhwkim
la source
5
Cela fonctionne mais ne devrait pas être utilisé car il ng-optionsest plus rapide et plus optimisé que ng-repeat.
Iso
@Vous n'êtes pas non plus en désaccord avec vous, mais avez-vous une source pour ces informations?
Adam Plocher
1
Ici dans les documents: docs.angularjs.org/api/ng/directive/ngOptions «plus de flexibilité dans la façon dont le <select>modèle de est attribué via la select aspartie de l'expression de compréhension», «réduction de la consommation de mémoire en ne créant pas de nouvelles possibilités pour chaque instance répétée "," augmentation de la vitesse de rendu en créant les options dans un documentFragmentau lieu de individuellement "
Iso
16

Ma solution à cela était d'utiliser du HTML pour coder en dur mon option par défaut. Ainsi:

En HAML:

%select{'ng-model' => 'province', 'ng-options' => "province as province for province in summary.provinces", 'chosen' => "chosen-select", 'data-placeholder' => "BC & ON"}
  %option{:value => "", :selected => "selected"}
    BC &amp; ON

En HTML:

<select ng-model="province" ng-options="province as province for province in summary.provinces" chosen="chosen-select" data-placeholder="BC & ON">
  <option value="" selected="selected">BC &amp; ON</option>
</select>

Je veux que mon option par défaut renvoie toutes les valeurs de mon API, c'est pourquoi j'ai une valeur vide. Excusez également mon haml. Je sais que ce n'est pas directement une réponse à la question du PO, mais les gens trouvent cela sur Google. J'espère que ceci aide quelqu'un d'autre.

penner
la source
1
J'ai essayé de convertir cela en html mais cela a échoué dans tous les convertisseurs en ligne que j'ai essayés.
iConnor
5
Pourquoi ne pas poster du HTML? Je veux dire, est-ce que publier le code comme ça était vraiment nécessaire? Ce n'est pas comme si l'OP utilisait un moteur de modèles dans la question.
arg20
14

Utilisez le code ci-dessous pour remplir l'option sélectionnée à partir de votre modèle.

<select id="roomForListing" ng-model="selectedRoom.roomName" >

<option ng-repeat="room in roomList" title="{{room.roomName}}" ng-selected="{{room.roomName == selectedRoom.roomName}}" value="{{room.roomName}}">{{room.roomName}}</option>

</select>
Jayen Chondigara
la source
Lekker travaillé pour moi. L'appel asynchrone responsable des options de liaison pour ma liste de sélection était un peu plus lent que celui qui a apporté ng-model, donc cette approche m'a beaucoup aidé. Merci Eebbesen :-)
ajaysinghdav10d
Cela fonctionne aussi pour moi. Simple et compréhensible.
Kent Aguilar du
10

Selon le nombre d'options dont vous disposez, vous pouvez mettre vos valeurs dans un tableau et remplir automatiquement vos options comme ceci

<select ng-model="somethingHere.values" ng-options="values for values in [5,4,3,2,1]">
   <option value="">Pick a Number</option>
</select>
Alex Hawkins
la source
10

Dans mon cas, je devais insérer une valeur initiale uniquement pour dire à l'utilisateur de sélectionner une option, donc j'aime le code ci-dessous:

<select ...
    <option value="" ng-selected="selected">Select one option</option>
</select>

Lorsque j'ai essayé une option avec la valeur! = D'une chaîne vide (nulle), l'option a été remplacée par angulaire, mais, lorsque j'ai mis une option comme ça (avec une valeur nulle), la sélection apparaît avec cette option.

Désolé par mon mauvais anglais et j'espère que j'aiderai quelque chose avec ça.

Maciel Bombonato
la source
8

Utilisation selectde ngOptionset définition d'une valeur par défaut:

Voir la documentation ngOptions pour plus d' ngOptionsexemples d'utilisation.

angular.module('defaultValueSelect', [])
 .controller('ExampleController', ['$scope', function($scope) {
   $scope.data = {
    availableOptions: [
      {id: '1', name: 'Option A'},
      {id: '2', name: 'Option B'},
      {id: '3', name: 'Option C'}
    ],
    selectedOption: {id: '2', name: 'Option B'} //This sets the default value of the select in the ui
    };
}]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<body ng-app="defaultValueSelect">
  <div ng-controller="ExampleController">
  <form name="myForm">
    <label for="mySelect">Make a choice:</label>
    <select name="mySelect" id="mySelect"
      ng-options="option.name for option in data.availableOptions track by option.id"
      ng-model="data.selectedOption"></select>
  </form>
  <hr>
  <tt>option = {{data.selectedOption}}</tt><br/>
</div>

plnkr.co

Documentation officielle sur HTMLSELECT élément avec liaison de données angulaire.

Liaison selectà une valeur non chaîne via l' ngModelanalyse / formatage:

(function(angular) {
  'use strict';
angular.module('nonStringSelect', [])
  .run(function($rootScope) {
    $rootScope.model = { id: 2 };
  })
  .directive('convertToNumber', function() {
    return {
      require: 'ngModel',
      link: function(scope, element, attrs, ngModel) {
        ngModel.$parsers.push(function(val) {
          return parseInt(val, 10);
        });
        ngModel.$formatters.push(function(val) {
          return '' + val;
        });
      }
    };
  });
})(window.angular);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.1/angular.min.js"></script>
<body ng-app="nonStringSelect">
  <select ng-model="model.id" convert-to-number>
  <option value="1">One</option>
  <option value="2">Two</option>
  <option value="3">Three</option>
</select>
{{ model }}
</body>

plnkr.co

Autre exemple:

angular.module('defaultValueSelect', [])
 .controller('ExampleController', ['$scope', function($scope) {
   $scope.availableOptions = [
     { name: 'Apple', value: 'apple' }, 
     { name: 'Banana', value: 'banana' }, 
     { name: 'Kiwi', value: 'kiwi' }
   ];
   $scope.data = {selectedOption : $scope.availableOptions[1].value};
}]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<body ng-app="defaultValueSelect">
  <div ng-controller="ExampleController">
  <form name="myForm">
    <select ng-model="data.selectedOption" required ng-options="option.value as option.name for option in availableOptions"></select>
  </form>  
  </div>
</body>

jsfiddle

shilovk
la source
4

Cela a fonctionné pour moi.

<select ng-model="somethingHere" ng-init="somethingHere='Cool'">
    <option value="Cool">Something Cool</option>
    <option value="Else">Something Else</option>
</select>
Bishan
la source
3

Dans mon cas, car la valeur par défaut varie d'un cas à l'autre dans le formulaire. J'ajoute un attribut personnalisé dans la balise de sélection.

 <select setSeletected="{{data.value}}">
      <option value="value1"> value1....
      <option value="value2"> value2....
       ......

dans les directives, j'ai créé un script qui vérifie la valeur et lorsque angulaire le remplit définit l'option avec cette valeur sur sélectionnée.

 .directive('setSelected', function(){
    restrict: 'A',
    link: (scope, element, attrs){
     function setSel=(){
     //test if the value is defined if not try again if so run the command
       if (typeof attrs.setSelected=='undefined'){             
         window.setTimeout( function(){setSel()},300) 
       }else{
         element.find('[value="'+attrs.setSelected+'"]').prop('selected',true);          
       }
     }
    }

  setSel()

})

vient de traduire cela à partir de coffescript à la volée au moins le coup est correct sinon le truc du trou.

Ce n'est pas le moyen le plus simple mais faites-le lorsque la valeur varie

Bruno
la source
3

En réponse à la réponse de Ben Lesh , il devrait y avoir cette ligne

ng-init="somethingHere = somethingHere || options[0]" 

au lieu de

ng-init="somethingHere = somethingHere || options[0].value" 

C'est,

<select ng-model="somethingHere"
        ng-init="somethingHere = somethingHere || options[0]"
        ng-options="option.name for option in options track by option.value">
</select>

Li Tianjiang
la source
3

Utilisez simplement ng-selected="true"comme suit:

<select ng-model="myModel">
        <option value="a" ng-selected="true">A</option>
        <option value="b">B</option>
</select>
Shevon Silva
la source
2

Je définirais le modèle dans le contrôleur. Ensuite, la sélection sera par défaut à cette valeur. Ex: html:

<select ng-options="..." ng-model="selectedItem">

Contrôleur angulaire (en utilisant la ressource):

myResource.items(function(items){
  $scope.items=items;
  if(items.length>0){
     $scope.selectedItem= items[0];
//if you want the first. Could be from config whatever
  }
});
Jens Alenius
la source
2

Cela fonctionne pour moi

ng-selected="true" 
Je ne sais pas
la source
Le meilleur moyen est d'utiliser ng-initcar vous définissez un ngModel.
Juanjo Salvador
1

Si vous utilisez ng-optionspour effectuer un rendu vers le bas, la optionmême valeur que celle de ng-modal est sélectionnée par défaut. Prenons l'exemple:

<select ng-options="list.key as list.name for list in lists track by list.id" ng-model="selectedItem">

L'option ayant la même valeur de list.keyet selectedItemest donc sélectionnée par défaut.

Rubi saini
la source
1

J'avais besoin que la valeur par défaut «Veuillez sélectionner» ne soit pas sélectionnable. J'avais également besoin de pouvoir conditionnellement définir une option sélectionnée par défaut.

J'ai réalisé cela de la manière simpliste suivante: Code JS: // Retournez ces 2 pour tester la valeur par défaut sélectionnée ou aucune valeur par défaut avec le texte par défaut «Veuillez sélectionner» //$scope.defaultOption = 0; $ scope.defaultOption = {clé: '3', valeur: 'Option 3'};

$scope.options = [
   { key: '1', value: 'Option 1' },
   { key: '2', value: 'Option 2' },
   { key: '3', value: 'Option 3' },
   { key: '4', value: 'Option 4' }
];

getOptions();

function getOptions(){
    if ($scope.defaultOption != 0)
    { $scope.options.selectedOption = $scope.defaultOption; }
}

HTML:

<select name="OptionSelect" id="OptionSelect" ng-model="options.selectedOption" ng-options="item.value for item in options track by item.key">
<option value="" disabled selected style="display: none;"> -- Please Select -- </option>
</select>
<h1>You selected: {{options.selectedOption.key}}</h1>         

J'espère que cela aide quelqu'un d'autre qui a des exigences similaires.

Le "Please Select" a été accompli grâce à la réponse de Joffrey Outtier ici .

Spencer Sullivan
la source
0

Si vous avez quelque chose au lieu de simplement lancer la partie date, vous pouvez l'utiliser ng-init()en le déclarant dans votre contrôleur et en l'utilisant en haut de votre HTML. Cette fonction fonctionnera comme un constructeur pour votre contrôleur, et vous pourrez y initier vos variables.

angular.module('myApp', [])
 .controller('myController', ['$scope', ($scope) => {
   $scope.allOptions = [
     { name: 'Apple', value: 'apple' }, 
     { name: 'Banana', value: 'banana' }
   ];
   $scope.myInit = () => {
      $scope.userSelected = 'apple'
      // Other initiations can goes here..
   }
}]);


<body ng-app="myApp">
  <div ng-controller="myController" ng-init="init()">
    <select ng-model="userSelected" ng-options="option.value as option.name for option in allOptions"></select>
   </div>
</body>
ofir_aghai
la source
0
    <!--
    Using following solution you can set initial 
default value at controller as well as after change option selected value shown as default.
    -->
    <script type="text/javascript">
      function myCtrl($scope)
        {
          //...
            $scope.myModel=Initial Default Value; //set default value as required
          //..
        }
    </script>
    <select ng-model="myModel" 
                ng-init="myModel= myModel"
                ng-options="option.value as option.name for option in options">
        </select>
Mohammad Rahman
la source
0

essayez ceci dans votre contrôleur angulaire ...

$ somethingHere = {name: 'Something Cool'};

Vous pouvez définir une valeur, mais vous utilisez un type complexe et l'angulaire recherchera la clé / valeur à définir dans votre vue.

Et, si cela ne fonctionne pas, essayez ceci: ng-options = "option.value as option.name for option in options track by option.name"

Wesley Rocha
la source
-1

Je pense que le moyen le plus simple est

 ng-selected="$first"
Cesar Alonso
la source
6
Cette réponse ne fournit aucun contexte.
pspahn