Cognitronic
Cognitronic

Reputation: 1436

How to programmatically select ng-option value?

I have a view that is filled with dropdownlists to filter a report. I also have a view of saved filters that are displayed as links. When a user clicks on their saved filters, I want the appropriate values of the dropdownlists to be selected. The drop downs are being populated properly. On the saved filter link there is an ng-click that will call a function that iterates through the collection of saved filter values and automatically selects the correct one. I cannot figure out how to programmatically set the selected option. Any help is much appreciated!

<select uid="locSelect" 
        class="span12" 
        ng-model="reportDetail.selectedLoc" 
        ng-options="loc.dbid as loc.serviceName for loc in reportDetail.locList | orderBy:'name'">
    <option uid="unselectedLocOption" value="">-- Select One --</option>
</select>

Here is the list of saved filters:

<div class=" well fixed-search" style="overflow-x: hidden;overflow-y: auto;">
<div class="well-header">
    Saved Filters
</div>
<div ng-if="!hasSavedFilters">
    <span>No saved filters</span>
</div>
<ul ng-if="hasSavedFilters" class="nav nav-list dashboard-list">
    <li ng-repeat="filter in reportDetail.savedFilters">
        <a uid="savedFilter" href="" ng-click="reportDetail.loadSavedFilters(filter.filters)">
            <span ng-bind="filter.title"></span>
        </a>
    </li>
</ul>

And here is my controller

(function(){
'use strict';

var ReportDetailController = function(ReportsService, $scope){
    var _locList = {};
    var _hospitalStatusList = {};
    var _providerStatusList = {};
    var _savedFilters = [];
    var _sourceTypeList = {};
    var _dateRangeList = {};

    var _init = function(){
        ReportsService.getCurrentReportSavedFilters().then(function(data){
            $scope.reportDetail.savedFilters =data;
            $scope.hasSavedFilters = ReportsService.hasSavedFilters();
        });

        ReportsService.getLOCListForDDL().then(function(data){
            $scope.reportDetail.locList = data;
            //$scope.reportDetail.selectedLoc = $scope.reportDetail.locList[0];
        });

        ReportsService.getSelectListData()
            .then(function(data){
                $scope.reportDetail.sourceTypeList = data.CONNECTION_TARGET_STATUS;
                $scope.reportDetail.hospitalStatusList = data.CONNECTION_SOURCE_STATUS;
            });
        ReportsService.getDateRangesForDDL()
            .then(function(data){
                $scope.reportDetail.dateRangeList = data;
            });

        $scope.reportDetail.providerStatusList = ReportsService.getProviderStatusForDDL();


    };



    var _loadSavedFilters = function(filters){
        for(var i = 0, l = $scope.reportDetail.locList.length; i<l; i++){
            if($scope.reportDetail.locList[i].serviceName == filters.levelOfCare){
                 $scope.reportDetail.selectedLoc = $scope.reportDetail.locList[i];
                console.log($scope.reportDetail.selectedLoc);
            }
        }
    }

    var _isActive = function(filter){
        for(var i = 0, l = $scope.reportDetail.savedFilters.length; i<l; i++){
            if(filter.title == $scope.reportDetail.savedFilters[i].title){
                return true;
            }
            return false;
        }
    }

    var _generateReport = function(){
        return ReportsService.generateReport();
    };

    $scope.reportDetail = {
        init: _init,
        selectedLoc: null,
        isActive: _isActive,
        locList: _locList,
        selectedHospitalStatus: 'NOTIFIED',
        hospitalStatusList: _hospitalStatusList,
        selectedProviderStatus: 'NEW',
        providerStatusList: _providerStatusList,
        selectedSourceType: 'CONNECTED',
        sourceTypeList: _sourceTypeList,
        selectedDateRange: '',
        dateRangeList: _dateRangeList,
        savedFilters: _savedFilters,
        loadSavedFilters: _loadSavedFilters,
        generateReport: _generateReport
    };

    $scope.reportDetail.init();
};

app.controller('ReportDetailController', ['ReportsService', '$scope',  ReportDetailController]);
})();

Upvotes: 7

Views: 11771

Answers (5)

Fabio Moura
Fabio Moura

Reputation: 1

If I understand, in summary, you have a select filled with a list, and you want to programmatically set one of those to be selected, type it as the default right?

If so, you can easily solve this with ng-options, just associate your controller instance with scope and assign the position of the list you want to the model of select, for example:

Select HTML

<select ng-model="vm.aluno_id" name="aluno_id" ng-options="aluno.nome for aluno in alunos">

Controller

app.controller("auxiliarController", function( $scope){

     //instancia controller;(Controller instance;)
     var vm = this;
     $scope.vm = vm;

     //carregando lista no scope, que será utilizado pelo angular no select
    //Loading list in scope, which will be used by angular in select
     $scope.alunos = [{id: 1, nome: "aa"}, {id: 2, nome: "bb"}];

     //setando item default no select
     $scope.vm.aluno_id = $scope.alunos[0];

});

I hope I have helped

Upvotes: -1

Cognitronic
Cognitronic

Reputation: 1436

Due to time constraints I ended up going a different route. I created an event bus of sorts in my service layer and subscribe to the even in my controller, updating the model, and used ng-repeat with ng-selected.

I'm still interested to understand why this was not working with ng-options. The model and ng-options types matched, and everything appeared to be wired up correctly. When I have more time i'll re-address the original issue. Thanks for all who responded!

Upvotes: 1

adolfo_isassi
adolfo_isassi

Reputation: 229

The ng-model and the expression feeding ng-options -must- match in order for Angular to compare values and see what option is 'selected'. Just as 'dave' indicated.

Upvotes: 1

Medet Tleukabiluly
Medet Tleukabiluly

Reputation: 11940

You need custom directive, or something similar to this two approaches

<div ng-controller="MyCtrl">
<h1>Approach 1</h1>
<span ng-repeat="val in dbs">
    <input type="checkbox" ng-model="val.checked">{{val.name}}
</span>
<hr/>
<h1>Approach 1</h1>
<select multiple>
    <option ng-repeat="val in dbs" name="val.name" value="val.name" ng-selected="val.checked">{{val.name}}</option>
</select>
<h4>Source (note scope changes)</h4>
{{dbs}}
</div>

also you can use ng-change to do some complex ops

Upvotes: 0

dave
dave

Reputation: 64677

You just need to set the ng-model to whatever it should be, so in this case you would set reportDetail.selectedLoc to whatever loc.dbid it should be.

For example: http://jsfiddle.net/uWLua/1/

Note: Make sure they have the same type, so in your example make sure they are either both integers, or both strings, it will not know they are the same if you have one as 5073 and one as "5073"

I updated the fiddle to show that the string and number do not do the same thing.

Upvotes: 7

Related Questions