track item array angularjs ng-options

angularjs - item - ng-options filter



ng-opciones con filas deshabilitadas (11)

Angular agregó soporte para esto en 1.4.0-beta.5

<select ng-options="c.name disable when c.shade == ''dark'' group by c.shade for c in colors">

¿Es posible usar ng-options que se convertirá en filas deshabilitadas en función de los criterios?

esta:

<select ng-options="c.name group by c.shade for c in colors">

tal vez sea posible convertirlo en algo como esto:

<select ng-options="c.name group by c.shade for c in colors | disabled(c.shade)">

y digamos a través de un filtro que podría devolver disabled=''disabled'' para todos los colores que tienen shade = "dark"

<select> <optgroup label="dark"> <option value="0" disabled="disabled">black</option> <option value="2" disabled="disabled">red</option> <option value="3" disabled="disabled">blue</option> </optgroup> <optgroup label="light"> <option value="1">white</option> <option value="4">yellow</option> </optgroup> </select>


Como no puedo actualizar al último angularJS, he creado una directiva más simple para manejarlo.

.directive(''allowDisabledOptions'',[''$timeout'', function($timeout) { return function(scope, element, attrs) { var ele = element; var scopeObj = attrs.allowDisabledOptions; $timeout(function(){ var DS = ele.scope()[scopeObj]; var options = ele.children(); for(var i=0;i<DS.length;i++) { if(!DS[i].enabled) { options.eq(i).attr(''disabled'', ''disabled''); } } }); } }])

para más detalles: https://github.com/farazshuja/disabled-options


Como señaló @Lod Angular, se agregó soporte para esto en 1.4.0-beta.5.

Para js angulares > = 1.4.0-beta.5 .

<select ng-options="c.name disable when c.shade == ''dark'' group by c.shade for c in colors">

Y para js angulares <1.4.0-beta.5, consulte la solución a continuación:

Similar al proporcionado por @lucuma pero sin dependencia de jQuery .

Mira esto http://jsfiddle.net/dZDLg/46/

Controlador

<div ng-controller="OptionsController"> <select ng-model="selectedport" ng-options="p.name as p.name for p in ports" options-disabled="p.isinuse for p in ports"></select> <input ng-model="selectedport"> </div>

Directiva

angular.module(''myApp'', []) .directive(''optionsDisabled'', function($parse) { var disableOptions = function(scope, attr, element, data, fnDisableIfTrue) { // refresh the disabled options in the select element. var options = element.find("option"); for(var pos= 0,index=0;pos<options.length;pos++){ var elem = angular.element(options[pos]); if(elem.val()!=""){ var locals = {}; locals[attr] = data[index]; elem.attr("disabled", fnDisableIfTrue(scope, locals)); index++; } } }; return { priority: 0, require: ''ngModel'', link: function(scope, iElement, iAttrs, ctrl) { // parse expression and build array of disabled options var expElements = iAttrs.optionsDisabled.match( /^/s*(.+)/s+for/s+(.+)/s+in/s+(.+)?/s*/); var attrToWatch = expElements[3]; var fnDisableIfTrue = $parse(expElements[1]); scope.$watch(attrToWatch, function(newValue, oldValue) { if(newValue) disableOptions(scope, expElements[2], iElement, newValue, fnDisableIfTrue); }, true); // handle model updates properly scope.$watch(iAttrs.ngModel, function(newValue, oldValue) { var disOptions = $parse(attrToWatch)(scope); if(newValue) disableOptions(scope, expElements[2], iElement, disOptions, fnDisableIfTrue); }); } }; });

Nota : Esta solución no funciona con group by correctamente señalada por todos. Consulte la solución a continuación con @DHlavaty si desea que funcione con group by .


Desde febrero de 2015, ha habido una forma de desactivar las opciones en su etiqueta ng-options.

Este enlace muestra la adición de la función en github

Descubrí que al usar angular 1.4.7, la sintaxis había cambiado de ''desactivar por'' a ''desactivar cuando''.

La sintaxis para esto es:

''ng-options'': ''o.value as o.name disable when o.unavailable for o in options''


La respuesta de @luuma (originalmente la respuesta aceptada) era correcta, pero por ahora debería actualizarse, porque esto se solucionó en Angular 1.4. Consulte los documentos de ng-options, que también contiene un example .

Estoy usando Angular 1.5 y esto funciona para mí:

Ver

<select ng-model="$ctrl.selectedItem" ng-options="item as item.label disable when item.disabled for item in $ctrl.listItems">

Controlador

vm.items = [ { id: ''optionA'', label: ''Option A'' }, { id: ''optionB'', label: ''Option B (recommended)'' }, { id: ''optionC'', label: ''Option C (Later)'', disabled: true } ]; vm.selectedItem = vm.items[1];


No creo que haya una manera de hacer lo que estás pidiendo solo usando ng-options . Este problema se planteó en el proyecto angular y aún está abierto:

https://github.com/angular/angular.js/issues/638

Parece que la solución alternativa es utilizar una directiva a la que se hace referencia aquí y en el número de github: http://jsfiddle.net/alalonde/dZDLg/9/

Aquí está el código completo de jsfiddle para referencia (el siguiente código es de jsfiddle de alande):

<div ng-controller="OptionsController"> <select ng-model="selectedport" ng-options="p.name as p.name for p in ports" options-disabled="p.isinuse for p in ports"></select> <input ng-model="selectedport"> </div> angular.module(''myApp'', []) .directive(''optionsDisabled'', function($parse) { var disableOptions = function(scope, attr, element, data, fnDisableIfTrue) { // refresh the disabled options in the select element. $("option[value!=''?'']", element).each(function(i, e) { var locals = {}; locals[attr] = data[i]; $(this).attr("disabled", fnDisableIfTrue(scope, locals)); }); }; return { priority: 0, require: ''ngModel'', link: function(scope, iElement, iAttrs, ctrl) { // parse expression and build array of disabled options var expElements = iAttrs.optionsDisabled.match(/^/s*(.+)/s+for/s+(.+)/s+in/s+(.+)?/s*/); var attrToWatch = expElements[3]; var fnDisableIfTrue = $parse(expElements[1]); scope.$watch(attrToWatch, function(newValue, oldValue) { if(newValue) disableOptions(scope, expElements[2], iElement, newValue, fnDisableIfTrue); }, true); // handle model updates properly scope.$watch(iAttrs.ngModel, function(newValue, oldValue) { var disOptions = $parse(attrToWatch)(scope); if(newValue) disableOptions(scope, expElements[2], iElement, disOptions, fnDisableIfTrue); }); } }; }); function OptionsController($scope) { $scope.ports = [{name: ''http'', isinuse: true}, {name: ''test'', isinuse: false}]; $scope.selectedport = ''test''; }


Puede deshabilitar el uso de ngOptions en angular 1.4.1 o superior

Plantilla HTML

<div ng-app="myapp"> <form ng-controller="ctrl"> <select id="t1" ng-model="curval" ng-options=''reportingType.code as reportingType.itemVal disable when reportingType.disable for reportingType in reportingOptions''> <option value="">Select Report Type</option> </select> </form>

Código de controlador

angular.module(''myapp'',[]).controller("ctrl", function($scope){ $scope.reportingOptions=[{''code'':''text'',''itemVal'':''TEXT'',''disable'':false}, {''code'':''csv'',''itemVal'':''CSV'',''disable'':true}, {''code'':''pdf'',''itemVal'':''PDF'',''disable'':false}];

})


Se puede lograr un efecto similar usando ng-repeat y ng-disabled en la opción misma, evitando el uso de una nueva directiva.

HTML

<div ng-controller="ExampleController"> <select ng-model="myColor"> <option ng-repeat="c in colors" ng-disabled="c.shade==''dark''" value="{{$index}}"> {{c.name}} </option> </select> </div>

Controlador

function ExampleController($scope, $timeout) { $scope.colors = [ {name:''black'', shade:''dark''}, {name:''white'', shade:''light''}, {name:''red'', shade:''dark''}, {name:''blue'', shade:''dark''}, {name:''yellow'', shade:''light''} ]; $timeout(function() { $scope.myColor = 4; // Yellow }); }

Violín

http://jsfiddle.net/0p4q3b3s/

Problemas conocidos:

  • No usa ng-options
  • No funciona con group by
  • Selecciona el índice, no el objeto
  • Requiere $timeout de $timeout para la selección inicial

Solución similar "sin jQuery" como la de , pero funciona con group by

En mi caso, group by no funciona, porque mi primera <option> no tiene valor, solo con Please select and item from dropdown texto Please select and item from dropdown . Esta es una versión ligeramente modificada, que soluciona esta situación particular:

El uso es similar a @ Vikas-Gulati respuesta: https://.com/a/20790905/1268533

Directiva

angular.module(''disabledModule'', []) .directive(''optionsDisabled'', function($parse) { var disableOptions = function(scope, attr, element, data, fnDisableIfTrue) { var realIndex = 0; angular.forEach(element.find("option"), function(value, index){ var elem = angular.element(value); if(elem.val()!="") { var locals = {}; locals[attr] = data[realIndex]; realIndex++; // this skips data[index] with empty value (IE first <option> with ''Please select from dropdown'' item) elem.attr("disabled", fnDisableIfTrue(scope, locals)); } }); }; return { priority: 0, require: ''ngModel'', link: function(scope, iElement, iAttrs, ctrl) { // parse expression and build array of disabled options var expElements = iAttrs.optionsDisabled.match(/^/s*(.+)/s+for/s+(.+)/s+in/s+(.+)?/s*/); var attrToWatch = expElements[3]; var fnDisableIfTrue = $parse(expElements[1]); scope.$watch(attrToWatch, function(newValue, oldValue) { if(newValue) disableOptions(scope, expElements[2], iElement, newValue, fnDisableIfTrue); }, true); // handle model updates properly scope.$watch(iAttrs.ngModel, function(newValue, oldValue) { var disOptions = $parse(attrToWatch)(scope); if(newValue) disableOptions(scope, expElements[2], iElement, disOptions, fnDisableIfTrue); }); } }; });


También oculté las opciones desactivadas y agregué la siguiente línea:

$(this).css("display", fnDisableIfTrue(scope, locals) ? "none" : "block");

Era necesario ya que no podía simplemente filtrarlos, ya que el valor inicial de esta selección podría ser una de las opciones desactivadas.


Tuve una situación interesante. Una matriz de listas desplegables y necesito desactivar las opciones que ya estaban seleccionadas en cada uno de los menús desplegables, pero también lo necesito para mantener activada la que ya se seleccionó ...

aquí está mi plunker: habilitar / deshabilitar valores con ng-opciones

var app = angular.module(''ngoptions'', []); app.controller(''MainCtrl'', function($scope) { // disable the fields by default $scope.coverage = [ { CoverageType: '''', CoverageName: ''No Coverage'' }, { CoverageType: ''A'', CoverageName: ''Dependent Only'' }, { CoverageType: ''B'', CoverageName: ''Employee Plus Children'' }, { CoverageType: ''C'', CoverageName: ''Employee Only'' }, { CoverageType: ''D'', CoverageName: ''Employee Plus One'' }, { CoverageType: ''E'', CoverageName: ''Employee Plus Two'' }, { CoverageType: ''F'', CoverageName: ''Family'' }, ]; // values already set ex: pulled from db $scope.rates = [''A'',''C'', ''F'']; $scope.changeSelection = function (index, rate){ $scope.rates[index] = rate; disableRecords(); } // start by disabling records disableRecords(); function disableRecords () { // set default values to false angular.forEach($scope.coverage, function (i, x) { i.disable = false; }); // set values to true if they exist in the array angular.forEach($scope.rates, function (item, idx) { angular.forEach($scope.coverage, function (i, x) { if (item == i.CoverageType) { i.disable = true; } }); }); } });

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script> <!DOCTYPE html> <html ng-app="ngoptions"> <head> <meta charset="utf-8" /> <title>AngularJS Plunker</title> <script data-require="[email protected]" data-semver="1.4.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script> <script>document.write(''<base href="'' + document.location + ''" />'');</script> <link rel="stylesheet" href="style.css" /> <script src="app.js"></script> </head> <body ng-controller="MainCtrl"> <table> <thead></thead> <tbody> <tr ng-repeat="rate in rates"> <td> <select ng-model="rate" ng-change="changeSelection($index, rate)" ng-options="type.CoverageType as type.CoverageName disable when (type.disable == true && type.CoverageType != rate) for type in coverage"></select> </td> </tr> </tbody> </table> </body> </html>