https://plnkr.co/edit/zxTLC2VTfMkUu5zPs1Ss?p=preview
In the linked plunker I have 3 products listed out, each with a select box.
Each product has an array of records. If I was to select a record from the "Product One" row, I would expect "record one" to be disabled in the other two product row select boxes, but that is not happening.
It seems that the ngChange directive is being fired twice, though I'm not sure why. Maybe because I am changing the disabled state?
If it is correct that it should fire twice, then I am not sure why it is unselecting the value and setting the field to be blank again?
HTML:
<head>
<script data-require="[email protected]" data-semver="1.6.5" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<my-component></my-component>
<script src="script.js"></script>
</body>
</html>
JS:
angular
.module('app', [])
.component('myComponent', {
template: `
<div style="display: flex; margin-bottom: 10px;" ng-repeat="productField in $ctrl.selectedProduct.productFields track by $index">
<div style="padding-right: 5px">
{{ productField.label }} →
</div>
<div>
<select
ng-model="productField.recordKey"
ng-options="recordField.key as recordField.label disable when recordField.disabled for recordField in productField.recordFields"
ng-change="$ctrl.mappingFieldChange()">
</select>
</div>
</div>
`,
controller: function() {
$ctrl = this
this.selectedProduct = {
productFields: [
{
key: 'one',
label: 'Product One',
recordFields: [
{
key: 'one',
label: 'Record One',
disabled: false,
},
{
key: 'two',
label: 'Record Two',
disabled: false,
},
{
key: 'three',
label: 'Record Three',
disabled: false,
},
],
},
{
key: 'two',
label: 'Product Two',
recordFields: [
{
key: 'one',
label: 'Record One',
disabled: false,
},
{
key: 'two',
label: 'Record Two',
disabled: false,
},
{
key: 'three',
label: 'Record Three',
disabled: false,
},
],
},
{
key: 'three',
label: 'Product Three',
recordFields: [
{
key: 'one',
label: 'Record One',
disabled: false,
},
{
key: 'two',
label: 'Record Two',
disabled: false,
},
{
key: 'three',
label: 'Record Three',
disabled: false,
},
],
},
]
}
$ctrl.mappingFieldChange = () => {
console.log('mappingFieldChange')
const fieldsMapped = getSelectedFields()
$ctrl.selectedProduct.productFields.forEach((productField) => {
// Disable the record keys that are selected and enable any others
productField.recordFields.forEach(recordField => {
if (fieldsMapped.indexOf(recordField.key) >= 0) {
recordField.disabled = true
}
else {
recordField.disabled = false
}
})
})
}
function getSelectedFields() {
let fieldsMapped = []
// Create an array of record field keys that are already selected
$ctrl.selectedProduct.productFields.forEach((productField) => {
if (productField.recordKey) {
fieldsMapped.push(productField.recordKey)
}
})
return fieldsMapped
}
},
})
Because I was disabling the value that was being selected, AngularJS was then
null
ing the value (null
ing the disabled value was introduced in 1.6), hence why the select box would remain blank.To fix this, I left the value enabled for the product row it was selected in, but disabled it in the others.
The updated mappingChange function now looks like this: