Search code examples
angularjsdrop-down-menuangular-ngmodelangularjs-ng-changeng-controller

Bootstrap dropdown and AngularJS the same ng-model for dropdown inside ng-repeat


I have list of rules, inside each rule there is property attribute, which it should be seted and geted from dropdown of attributes. In ng-repet I display all rules, that that every attrbute has the same ng-model, ng-controller and ng-change. This is probably confusing the application. I do not know how to set attrbiute on dropdown which is readed from ruleList[i].attribute. When selecting from dropdown, the right selectedAttribute is chooseen - ng-change. When want to set value from dropdown it does not work. How to add some index or something? I have writen it accorind to this example: http://www.infragistics.com/community/blogs/dhananjay_kumar/archive/2015/06/29/how-to-work-with-the-bootstrap-dropdown-in-angularjs.aspx

HTML code:

<tr ng-repeat="r in vm.ruleset.ruleList track by $index" ng-init="$ruleIndex = $index">
    <td align='right'>
        <div ng-controller="vm.attributeDropdown" init-data="$ruleIndex" class="col-xs-12 col-sm-4 col-md-3">
            <div class="form-group" ng-class="{ 'has-error': vm.rulesetForm.attribute.$touched && vm.rulesetForm.attribute.$invalid }">
                <div>
                    <span>{{selectedAttribute}}</span>
                        <select class="form-control" required ng-model="selectedAttribute" ng-options="i.attributenamecap for i in vm.attributes" id="vm.rulesetForm.attribute" ng-change="correctAttribute($ruleIndex, selectedAttribute)">
                            <option style="display:none" translate="rulesets.ruleset.form.placeholder.attribute""></option>
                        </select>
                        </div>
                       <div class="help-block" ng-show="vm.rulesetForm.$submitted || vm.rulesetForm.attribute.$touched">
                       <span ng-show="vm.rulesetForm.attribute.$error.required" translate=  "rulesets.ruleset.form.error.required.attribute"></span>
                </div>
            </div>
        </div>
    </td>
</tr>

Controller on ng-change:

 $scope.correctAttribute = function(index, selectedAttribute){
    if(index !== undefined || index !== null){
        vm.ruleset.ruleList[index].attribute = selectedAttribute;
    }
}

Controller on ng-controller:

function attributeDropdown($scope){
    var index = $scope.$ruleIndex;
    $scope.vm.attributes = vm.attributes;
    $scope.vm.attributes.unshift('');
    if(!isNew()){
        if(vm.ruleset.ruleList[index].attribute === ''){
            vm.ruleset.ruleList[index].attribute = null;
            $scope.selectedAttribute = vm.ruleset.ruleList[index].attribute;
            vm.original = angular.copy(vm.ruleset);
        }else{
            $scope.selectedAttribute = vm.ruleset.ruleList[index].attribute;
        }
    }else if(vm.ruleset.ruleList[index].attribute !== undefined ){
    $scope.selectedAttribute = vm.ruleset.ruleList[index].attribute;
    }
}

Solution

  • use ng-model="r.selectedAttribute" instead of ng-model="selectedAttribute"

    something like this

     <select class="form-control" required ng-model="r.selectedAttribute" ng-options="i.attributenamecap for i in vm.attributes" id="vm.rulesetForm.attribute" ng-change="correctAttribute($ruleIndex, r.selectedAttribute)">
             <option style="display:none" translate="rulesets.ruleset.form.placeholder.attribute""></option>
        </select>