0
votes

I'm using Smart-Table with default selection by using following helper directive to perform selection, highlight selected row and callback:

.directive('stSelectRowCustom', function () {
    return {
      restrict: 'A',
      require: '^stTable',
      scope: {
          row: '=stSelectRowCustom',
          callback: '&stSelected' // ADDED THIS
      },
      link: function (scope, element, attr, ctrl) {
        var mode = attr.stSelectMode || 'single';
        element.bind('click', function ($event) {
          scope.$apply(function () {
              ctrl.select(scope.row, mode, $event.shiftKey);
              scope.callback(); // AND THIS
          });
        });

        scope.$watch('row.isSelected', function (newValue) {
            if (newValue === true) {
              element.addClass('st-selected');
            } else {
              element.removeClass('st-selected');
            }
        });
      }
    };
  });

I'm use it as following:

<table st-table="displayedRowCollection" st-safe-src="rowCollection" class="table table-striped" >
        <thead>
          <tr>
              <th>first name</th>
              <th>last name</th>
              <th>birth date</th>
            <th>balance</th>
            <th>email</th>
        </tr>
        </thead>
        <tbody>
        <tr ng-repeat="row in rowCollection" st-select-row-custom="row" st-select-mode="single">
            <td>{{row.firstName}}</td>
            <td>{{row.lastName}}</td>
            <td>{{row.birthDate | date:'shortDate'}}</td>
            <td>{{row.balance}}</td>
            <td>{{row.email}}</td>
        </tr>
        </tbody>
    </table>

I need st-safe-src because I'm using filter and my rowCollection changes dynamically.

Controller's code as following:

controller('mainCtrl', ['$scope',
        function ($scope) {
          $scope.rowCollection = [
              {firstName: 'Laurent', lastName: 'Renard', birthDate: new Date('1987-05-21'), balance: 102, email: '[email protected]'},
              {firstName: 'Blandine', lastName: 'Faivre', birthDate: new Date('1987-04-25'), balance: -2323.22, email: '[email protected]'},
              {firstName: 'Francoise', lastName: 'Frere', birthDate: new Date('1955-08-27'), balance: 42343, email: '[email protected]'}
          ];

          $scope.rowCollection[0].isSelected = true;
        }
    ])

As you can see from above I select first row by: $scope.rowCollection[0].isSelected = true; and it indeed shown selected in a table, but when I click another row, first row remained selected until I click on it. When I select another row (now two rows are selected) and then select first one, both are unselected. Otherwise directive works as expected.

There's a plunkr with working example: http://plnkr.co/edit/N9jw6B?p=preview

Thank you in advance.

Update 1: From looking at source code here I can see that smart-table tracking last-selected row and unselecting it on the next selection, so when I pass arrays with PRE-selected row, lastSelected is undefined and it can't be unselected. At least I know the reason of this behaviour, right now trying to build a custom directive which will pass default row which should be selected, any help appreciated.

      if (lastSelected) {
        lastSelected.isSelected = false;
      }
      lastSelected = row.isSelected === true ? row : undefined;

Update 2: Ok, I've found solution here: https://stackoverflow.com/a/32633795/947111 It works but I don't really like because considering it as hack. Still working for more suitable solution based on a directive to which I'll pass row which should be selected by default.

1

1 Answers

1
votes

Duck rubber debugging :)

Here is my solution to this problem:

.directive('stDefaultValue', function () {
    return {
      restrict: 'A',
      require: '^stTable',
      scope: {
          selectedRow: '=stDefaultValue',
          stSafeSrc: '='
      },
      link: function (scope, element, attr, ctrl) {
          scope.$watch('stSafeSrc', function(newValue, oldValue) {
              if(typeof newValue !== 'undefined'){
                  ctrl.select(newValue[scope.selectedRow], 'single', false);
              }

          });
      }
    };
  });

You should use it in the following way:

<table st-table="displayedRowCollection" 
          st-default-value="1"
          st-safe-src="rowCollection"
        class="table table-striped" >

In this example I only pass index of row which I want to be selected, in my scenario it was enough, but of course you can pass any javascript object and with a little effort make it selected.

You can see working example here: https://plnkr.co/edit/ca7xLv?p=preview