Anton Anton - 6 months ago 13
Javascript Question

filtering data by API calls

I have a table on my page and custom filters for this table, so by default I'm using API call that to load data.

$('#table').bootstrapTable('refreshOptions', {
url: 'http://address:8080/events-api1/rest/Events/'
});


On the left side I have filters. This filters I'm getting thru http get method

$http({
method: "GET",
url: "http://address:8080/events-api1/rest/EventTypeCategories"
}).then(function success(response) {
$scope.categories = response.data;
}, function error(response) {
$scope.categories = response.statusText;
});


and rendering filters thru scope function

$scope.selectCat = function () {
angular.forEach($scope.categories, function (category) {
if (category.selected) {

$scope.selectedAllCat = false;

if (category.name == "Study") {
$scope.checked = true;
$('#table').bootstrapTable('refreshOptions', {
url: 'http://address:8080/events-api1/rest/Events?category=1'
});
}
else if (category.name == "Corporate") {
$scope.checked = true;
$('#table').bootstrapTable('refreshOptions', {
url: 'http://address:8080/events-api1/rest/Events?category=2'
});
}
else if (category.name == "Safety") {
$scope.checked = true;
$('#table').bootstrapTable('refreshOptions', {
url: 'http://address:8080/events-api1/rest/Events?category=3'
});
}
else if (category.name == "Partners") {
$scope.checked = true;
$('#table').bootstrapTable('refreshOptions', {
url: 'http://address:8080/events-api1/rest/Events?category=4'
});
}
else if (category.name == "Standards") {
$scope.checked = true;
$('#table').bootstrapTable('refreshOptions', {
url: 'http://address:8080/events-api1/rest/Events?category=5'
});
}
else if (category.name == "Technology") {
$scope.checked = true;
$('#table').bootstrapTable('refreshOptions', {
url: 'http://address:8080/events-api1/rest/Events?category=6'
});
}
}

});
};


html

<div class="panel-body">
<table class="table">
<tr>
<td class="col-md-1"> <input type="checkbox" ng-model="selectedAllCat" ng-click="selectAllCat()">&nbsp;</td>
<td class="col-md-9">All</td>
<td class="col-md-2">
{{ categories.length }}
</td>
</tr>
<tr ng-repeat="category in categories | orderBy : 'id' ">
<td class="col-md-1"> <input type="checkbox" ng-model="category.selected" ng-click="selectCat()">&nbsp;</td>
<td class="col-md-9">{{ category.name }}</td>
<td class="col-md-2">
{{ category.selected }}
</td>
</tr>
</table>
</div>

<table id="table"
data-flat="true"
data-toggle="table"
data-toolbar="#toolbar"
data-search="true"
data-show-toggle="false"
data-show-columns="true"
data-show-export="true"
data-filter-control="true"
data-events="operateEvents"
data-formatter="operateFormatter"
data-response-handler="responseHandler"
class="table-striped">
</table>


My question is what do I have to do for multiple category selections?

Answer

EDIT: With more explanation.
Your goal here would be to compose the query string to be able to filter upon multiple categories.

When you want category 1, you do a request like:
http://address:8080/events-api/rest/Events?category=1

Now, you want to filter upon category 1 and 6 with a single request, so your request should be like this:

http://address:8080/events-api/rest/Events?category=1&category=6

So, in your code you should:
1 Change the markup from:

<td class="col-md-1"> <input type="checkbox" ng-model="category.selected" ng-click="selectCat()">&nbsp;</td>
to: <td class="col-md-1"> <input type="checkbox" ng-click="updateFilter(category.id)">&nbsp;</td>

2 The following function will help us to keep track of currently marked filters:

 $scope.selectedFilters = [];
    $scope.updateFilter = function(categoryId) {

        if ($scope.selectedFilters.indexOf(categoryId) > -1) {
            $scope.selectedFilters.push(categoryId);
        } else {
        $scope.selectedFilters.splice($scope.selectedFilters.indexOf(categoryId), 1);
    }

    //Optional, to reload on change.
    $scope.requestEvents();
}

3: The following function to request data, based on selected filters, will work also without filters at all.

$scope.requestEvents() {
    var url = 'http://address:8080/events-api/rest/Events';

    if ($scope.selectedFilters.length > -1) {
        var queryString = '?category=';
        queryString += $scope.selectedFilters.join('&category=');
        url += queryString;
    }
    $('#table').bootstrapTable('refreshOptions', {
        'url': url
    });
}

-- Old version -- Not sure if this will be clear from the first time, but it's due to lack of details from your side. So, keeping the code style as you already have it, you can write something like this.

$scope.filterByCategory = function(categories) {
    //Assuming you have in categories, an array of numbers, (or 
    //strings, anyway they should match categories from your backend)
    categories = categories.join('&category=');
    $('#table').bootstrapTable('refreshOptions', {
        url: 'http://address:8080/events-api/rest/Events?category=6' + categories
}

Note, depending on your backend, query string maybe should be joined by ('&category[]='), instead of ('&category=')