Alex Cipcigan Ratiu
Alex Cipcigan Ratiu

Reputation: 68

Have a multiple ng-model workaround

I am displaying a list of users in a table, the last column of each row being a button. When the button is clicked a popup appears, that can edit the user related to the clicked row. Each user has a list of interests. In the popup, I have a multiple select in which I would like to display the user's current interests. When the popup appears for the first time, it fetches the right data, but when I try to click other rows several times, the data remains the same. I know this is because of the ng-model directive, so what workaround would be ideal for this situation?

Here is my multi-select

<select id="multipleSelect"
    data-placeholder="Select interests..."
    chosen
    multiple
    ng-model="$ctrl.activeInterests"
    ng-options="interest for interest in $ctrl.interests"
    style="width:370px; height:100px;">
    <option value=""></option>
</select>

When the button from the last column of the table is clicked this function is called

this.editButtonClicked = function(tableRowUser) {
    $scope.firstName = tableRowUser.firstName;
    $scope.lastName = tableRowUser.lastName;
    $scope.email = tableRowUser.email;
    $scope.role = tableRowUser.role;
    $scope.tag = tableRowUser.tag;
    $scope.username = tableRowUser.username;

    // Fetch the active interests
    fetchInterests($scope.tag);

    // Fetch the available interests the user can choose
    fetchAllAvailableInterests();

    // After this, make the Edit Form visible
    togglePopupClass();
}

And in the 'fetchInterests' function I make the data which is bonded to the ng-model empty again, without any success.

function fetchInterests(newInterests) {
    self.activeInterests = []; // <- Here I make it empty
    var interests = newInterests.split('|');

    for (i = 0; i < interests.length; i++) {
        // Trim the excess whitespace.
        var tag = interests[i].replace(/^\s*/, "").replace(/\s*$/, "");
        self.activeInterests.push(tag);
    }
}

The official documentation says that ng-model only re-renders if it assigned to an entirely new object or collection. I have tried this as well, but without any success.

Upvotes: 0

Views: 699

Answers (1)

jeti
jeti

Reputation: 1908

Unfortunately, I can't tell you what's wrong with your solution based on the code you provided.

Here's a quick demo which may help you solve your issue.

// Code goes here
angular.module('myApp', [])
.controller('myCtrl', ['$scope', function($scope){
  
  $scope.allInterests = ['Cars', 'Football', 'Fishing', 'Pets', 'Cooking'];
  
  $scope.users = [
    {
      name: 'Bob',
      age: 34,
      interests: ['Cars', 'Football']
    },
    {
      name: 'Mary',
      age: 33,
      interests: ['Pets', 'Cooking']
    }
    ];
    
    $scope.showDetails = function(user){
      $scope.selectedUser = user;
    };
}]);
<!DOCTYPE html>
<html>

  <head>
    <script data-require="[email protected]" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-app="myApp" ng-controller="myCtrl">
    
    <table>
      <tr ng-repeat="user in users">
        <td>{{user.name}}</td>
        <td>{{user.age}}</td>
        <td><button ng-click="showDetails(user)">Show interests</button></td>
      </tr>
    </table>
    
    <hr>
    
    Editing: {{selectedUser.name}} <br>
    Age: {{selectedUser.age}} <br>
    
    <select multiple ng-model="selectedUser.interests" ng-options="interest for interest in allInterests"></select> <br>
    
    Selected interests: {{selectedUser.interests.join(',')}}
    
  </body>

</html>

Upvotes: 1

Related Questions