3

I have followed the instructions in the documentation regarding persisting the filter state. (http://plnkr.co/edit/ekwiNt?p=preview)

When re-loading the page, the table state (including filters) is restored, however the <select> box appears blank, even though the filter does work.

The text filter works fine.

Angular 1.4.7 Smart-table 2.1.5

Here is the plunker https://embed.plnkr.co/fK6WfZSZrgSeIG732R2X/

.directive('stPersist', function() {
  return {
    require: '^stTable',
    link: function(scope, element, attr, ctrl) {
      var nameSpace = attr.stPersist;

      //save the table state every time it changes
      scope.$watch(function() {
        return ctrl.tableState();
      }, function(newValue, oldValue) {
        if (newValue !== oldValue) {
          localStorage.setItem(nameSpace, JSON.stringify(newValue));
        }
      }, true);

      //fetch the table state when the directive is loaded
      if (localStorage.getItem(nameSpace)) {
        var savedState = JSON.parse(localStorage.getItem(nameSpace));
        var tableState = ctrl.tableState();

        angular.extend(tableState, savedState);
        ctrl.pipe();

      }

    }
  };
});;
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
darkbluesun
  • 817
  • 8
  • 15

3 Answers3

1

I would add in the ngSelected attribute in the Select statement:

<select st-search="category" st-input-event="change" class="input-sm form-control">
    <option value="">All</option>
    <option data-ng-repeat="category in categories" ng-selected="category.id == selectedCategory" value="{{category.id}}">{{category.name}}</option>
</select>

and retrieve the category value from storage:

//fetch the table state when the directive is loaded
if (localStorage.getItem(nameSpace)) {
    var savedState = JSON.parse(localStorage.getItem(nameSpace));
    var tableState = ctrl.tableState();

    // retrieve category filter (Note: it won't be present when 'All' is selected)
    scope.selectedCategory = savedState.search.predicateObject.category || "";

    angular.extend(tableState, savedState);
    ctrl.pipe();
}

If you want to visualise how the data is persisted (and how I came up with 'savedState.search.predicateObject.category') then add in the following JS to the above:

console.log(JSON.stringify(savedState));

https://plnkr.co/edit/bMbIVJ8OkEnfoYbWidu3?p=preview

K Scandrett
  • 16,390
  • 4
  • 40
  • 65
  • Nice work, thanks. I've not used the ngSelected attribute before, as I usually use ngOptions on the select. This solution taken literally would require me to identify the variable I want in the directive, and I've used the directive in quite a few places with different filters - so I exposed the whole table state to the scope. I can use that for pagination, etc too. – darkbluesun Oct 11 '16 at 01:57
  • For more flexibility you could save the entire predicate array (scope.filter = savedState.search.predicateObject) and then in the ngSelected use filter.category (or filter.[whatever]). – K Scandrett Oct 11 '16 at 02:01
0

This is how i solved it: for each property of the search.predicateObject it dinamically create a property in the scope added with "_SelectedValue", so each control can bind it in the html.

      <select data-st-search="AbiSearch" data-st-input-event="change">
        <option value="">All</option>
        <option data-ng-repeat="row in rowCollection | unique:'AbiSearch' | orderBy: 'AbiSearch'"
                data-ng-selected="row.AbiSearch == AbiSearch_SelectedValue"
                value="{{row.AbiSearch}}">{{row.AbiSearch}}</option>
      </select>

JS:

  if ($localStorage[nameSpace]) {
    var savedState = $localStorage[nameSpace];
    var tableState = ctrl.tableState();

    for (var propertyName in savedState.search.predicateObject) {
      if (savedState.search.predicateObject.hasOwnProperty(propertyName)) {
        scope[propertyName + "_SelectedValue"] = savedState.search.predicateObject[propertyName] || "";
      }
    }

    angular.extend(tableState, savedState);
    ctrl.pipe();
  }
0

Better solution if you have more tables in the same page with same filter name. In this case it will create many objects to store indipendently each properties

HTML:

      <select data-st-search="Enabled" data-st-input-event="change">
        <option value="">All</option>
        <option data-ng-repeat="row in rowCollection | unique:'Enabled' | orderBy: 'Enabled'"
                data-ng-selected="row.Enabled.toString() == {{StPersistName}}.Enabled_SelectedValue"
                value="{{row.Enabled}}">{{row.Enabled}}</option>
      </select>

JS:

  //fetch the table state when the directive is loaded
  if ($localStorage[nameSpace]) {
    var savedState = $localStorage[nameSpace];
    var tableState = ctrl.tableState();

    //Verifica che l'oggetto sia inizializzato
    if (!angular.isDefined(scope[nameSpace])) {scope[nameSpace] = {};}

    //Indispensabile per preselezionare il filtro in caso di menu a tendina
    for (var propertyName in savedState.search.predicateObject) { 
      if (savedState.search.predicateObject.hasOwnProperty(propertyName)) {
        scope[nameSpace][propertyName + "_SelectedValue"] = savedState.search.predicateObject[propertyName] || "";
      }
    }

    angular.extend(tableState, savedState);
    ctrl.pipe();
  }