Ordering and displaying data with AngularJS

Trying to maintain a constant gap of 5 between pagination elements, regardless of the total length. For instance, with $scope.itemsPerPage = 5 and total object length of 20, we should have 4 pages in pagination. However, if $scope.itemsPerPage = 2 and total length is still 20, then pagination should display 10 pages.

The goal is to keep this constant gap as 5.

<html xmlns:ng="http://angularjs.org" ng-app lang="en">
    <head>
        <meta charset="utf-8">
        <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap.no-icons.min.css" rel="stylesheet">
        <link href="http://netdna.bootstrapcdn.com/font-awesome/2.0/css/font-awesome.css" rel="stylesheet">
        <script src="http://code.angularjs.org/1.1.0/angular.min.js"></script>
        <script src="app.js"></script>
    </head>
    <body>
        <script type="text/javascript">
            var sortingOrder = 'name';
        </script>

        <div ng-controller="ctrlRead">
            <!--<div ng-include="'searchbox.html'"></div>-->
            <div class="input-append">
                <input type="text" ng-model="query" ng-change="search()" class="input-large search-query" placeholder="Search">
                <span class="add-on"><i class="icon-search"></i></span>
            </div>
            <table class="table table-striped table-condensed table-hover">
                <thead>
                    <tr>
                        <th class="id">Id&nbsp;<a ng-click="sort_by('id')"><i class="icon-sort"></i></a></th>
                        <th class="name">Name&nbsp;<a ng-click="sort_by('name')"><i class="icon-sort"></i></a></th>
                        <th class="description">Description&nbsp;<a ng-click="sort_by('description')"><i class="icon-sort"></i></a></th>
                        <th class="field3">Field 3&nbsp;<a ng-click="sort_by('field3')"><i class="icon-sort"></i></a></th>
                        <th class="field4">Field 4&nbsp;<a ng-click="sort_by('field4')"><i class="icon-sort"></i></a></th>
                        <th class="field5">Field 5&nbsp;<a ng-click="sort_by('field5')"><i class="icon-sort"></i></a></th>
                    </tr>
                </thead>
                <tfoot>
                <td colspan="6">
                    <div class="pagination pull-right">
                        <ul>
                            <li ng-class="{disabled: currentPage == 0}">
                                <a href ng-click="prevPage()">« Prev</a>
                            </li>
                            <li ng-repeat="n in range(pagedItems.length)"
                                ng-class="{active: n == currentPage}"
                                ng-click="setPage()">
                                <a href ng-bind="n + 1">1</a>
                            </li>
                            <li ng-class="{disabled: currentPage == pagedItems.length - 1}">
                                <a href ng-click="nextPage()">Next »</a>
                            </li>
                        </ul>
                    </div>
                </td>
                </tfoot>
                <tbody>
                    <tr ng-repeat="item in pagedItems[currentPage]| orderBy:sortingOrder:reverse">
                        <td>{{item.id}}</td>
                        <td>{{item.name}}</td>
                        <td>{{item.description}}</td>
                        <td>{{item.field3}}</td>
                        <td>{{item.field4}}</td>
                        <td>{{item.field5}}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
</html>

My app.js file
function ctrlRead($scope, $filter) {
    // init
    $scope.sortingOrder = sortingOrder;
    $scope.reverse = false;
    $scope.filteredItems = [];
    $scope.groupedItems = [];
    $scope.itemsPerPage = 2;
    $scope.pagedItems = [];
    $scope.currentPage = 0;
    $scope.items = [
        {"id":"1","name":"name 1","description":"description 1","field3":"field3 1","field4":"field4 1","field5 ":"field5 1"}, 
        {"id":"2","name":"name 2","description":"description 1","field3":"field3 2","field4":"field4 2","field5 ":"field5 2"}, 
        {"id":"3","name":"name 3","description":"description 1","field3":"field3 3","field4":"field4 3","field5 ":"field5 3"}, 
        {"id":"4","name":"name 4","description":"description 1","field3":"field3 4","field4":"field4 4","field5 ":"field5 4"}, 
        {"id":"5","name":"name 5","description":"description 1","field3":"field3 5","field4":"field4 5","field5 ":"field5 5"}, 
        {"id":"6","name":"name 6","description":"description 1","field3":"field3 6","field4":"field4 6","field5 ":"field5 6"}, 
        {"id":"7","name":"name 7","description":"description 1","field3":"field3 7","field4":"field4 7","field5 ":"field5 7"}, 
        {"id":"8","name":"name 8","description":"description 1","field3":"field3 8","field4":"field4 8","field5 ":"field5 8"}, 
        {"id":"9","name":"name 9","description":"description 1","field3":"field3 9","field4":"field4 9","field5 ":"field5 9"}, 
        {"id":"10","name":"name 10","description":"description 1","field3":"field3 10","field4":"field4 10","field5 ":"field5 10"}, 
        {"id":"11","name":"name 11","description":"description 1","field3":"field3 11","field4":"field4 11","field5 ":"field5 11"}, 
        {"id":"12","name":"name 12","description":"description 1","field3":"field3 12","field4":"field4 12","field5 ":"field5 12"}, 
        {"id":"13","name":"name 13","description":"description 1","field3":"field3 13","field4":"field4 13","field5 ":"field5 13"}, 
        {"id":"14","name":"name 14","description":"description 1","field3":"field3 14","field4":"field4 14","field5 ":"field5 14"}, 
        {"id":"15","name":"name 15","description":"description 1","field3":"field3 15","field4":"field4 15","field5 ":"field5 15"}, 
        {"id":"16","name":"name 16","description":"description 1","field3":"field3 16","field4":"field4 16","field5 ":"field5 16"}, 
        {"id":"17","name":"name 17","description":"description 1","field3":"field3 17","field4":"field4 17","field5 ":"field5 17"}, 
        {"id":"18","name":"name 18","description":"description 1","field3":"field3 18","field4":"field4 18","field5 ":"field5 18"}, 
        {"id":"19","name":"name 19","description":"description 1","field3":"field3 19","field4":"field4 19","field5 ":"field5 19"}, 
        {"id":"20","name":"name 20","description":"description 1","field3":"field3 20","field4":"field4 20","field5 ":"field5 20"}
    
    ];

    var searchMatch = function (haystack, needle) {
        if (!needle) {
            return true;
        }
        return haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1;
    };

    // init the filtered items
    $scope.search = function () {
        $scope.filteredItems = $filter('filter')($scope.items, function (item) {
            for(var attr in item) {
                if (searchMatch(item[attr], $scope.query))
                    return true;
            }
            return false;
        });
        // take care of the sorting order
        if ($scope.sortingOrder !== '') {
            $scope.filteredItems = $filter('orderBy')($scope.filteredItems, $scope.sortingOrder, $scope.reverse);
        }
        $scope.currentPage = 0;
        // now group by pages
        $scope.groupToPages();
    };

    // calculate page in place
    $scope.groupToPages = function () {
        $scope.pagedItems = [];

        for (var i = 0; i < $scope.filteredItems.length; i++) {
            if (i % $scope.itemsPerPage === 0) {
                $scope.pagedItems[Math.floor(i / $scope.itemsPerPage)] = [ $scope.filteredItems[i] ];
            } else {
                $scope.pagedItems[Math.floor(i / $scope.itemsPerPage)].push($scope.filteredItems[i]);
            }
        }
    };

    $scope.range = function (start, end) {
        var ret = [];
        if (!end) {
            end = start;
            start = 0;
        }
        for (var i = start; i < end; i++) {
            ret.push(i);
        }
        return ret;
    };

    $scope.prevPage = function () {
        if ($scope.currentPage > 0) {
            $scope.currentPage--;
        }
    };

    $scope.nextPage = function () {
        if ($scope.currentPage < $scope.pagedItems.length - 1) {
            $scope.currentPage++;
        }
    };

    $scope.setPage = function () {
        $scope.currentPage = this.n;
    };

    // functions have been describe process the data for display
    $scope.search();

    // change sorting order
    $scope.sort_by = function(newSortingOrder) {
        if ($scope.sortingOrder == newSortingOrder)
            $scope.reverse = !$scope.reverse;

        $scope.sortingOrder = newSortingOrder;

        // icon setup
        $('th i').each(function(){
            // icon reset
            $(this).removeClass().addClass('icon-sort');
        });
        if ($scope.reverse)
            $('th.'+new_sorting_order+' i').removeClass().addClass('icon-chevron-up');
        else
            $('th.'+new_sorting_order+' i').removeClass().addClass('icon-chevron-down');
    };
};
ctrlRead.$inject = ['$scope', '$filter'];

Answer №1

 $scope.getRange = function() {
        return $scope.range( $scope.pagedItems.length  > 5  ? 5 : $scope.pagedItems.length);
    }
<ul>
                            <li ng-class="{disabled: currentPage == 0}">
                                <a href ng-click="prevPage()">« Prev</a>
                            </li>
                            <li ng-repeat="n in getRange()"
                                ng-class="{active: n == currentPage}"
                                ng-click="setPage()">
                                <a href ng-bind="n + 1">1</a>
                            </li>
                            <li ng-class="{disabled: currentPage == pagedItems.length - 1}">
                                <a href ng-click="nextPage()">Next »</a>
                            </li>
                        </ul>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the process of importing a JSON file in JavaScript?

Is there a way to import a JSON file into my HTML form by calling $(document).ready(function (){});? The properties defined in the JSON file are crucial for the functionality of my form. Can anyone guide me on how to achieve this? ...

Issue: missing proper invocation of `next` after an `await` in a `catch`

I had a simple route that was functioning well until I refactored it using catch. Suddenly, it stopped working and threw an UnhandledPromiseRejectionWarning: router.get('/', async (req, res, next) => { const allEmployees = await employees.fi ...

What is the method to retrieve the base host in AngularJS?

I need assistance with the following URL: https://192.168.0.10/users/#!/user-profile/20 When I use $location.host, it returns 192.168.0.10 However, I only want to extract https://192.168.0.10 What is the best way to achieve this? ...

The File is not being successfully sent to the controller in MVC due to AJAX returning an undefined value

I recently created an AJAXUpload method within a cshtml file in my C# MVC project: function AjaxUpload(url, method, data, successFunction, errorFunction, skipErrorDlg) { $.ajax({ contentType: false, processData: false, url: url ...

What is the best method for choosing these elements and surrounding them with a wrapper?

I need to style a title with two radio inputs by wrapping them in a form: <p><strong>Country</strong></p> <div class="radioWrapper"> <span class="label">Canada</span> <span class="radio"> ...

What is the best way to incorporate a sliding effect into my cookie form?

I created a cookie consent form for my website and I'm looking to include a sliding effect when it first appears and when it disappears after the button is clicked. How can I implement this sliding effect into the form? Here's the HTML, CSS, and ...

Error encountered during JSON object conversion

How can I convert the string below into an object? "{"taskStatus":"Not Started","taskFields":{"originalTransactionDate":"${datafield:feerefund:originalTranDate}","transactionPostingDate":"${datafield:feerefund:tranPostingDate}","referenceNumber":"${data ...

Creating a classification for a higher order function

In the code snippet below, I have a controller that acts as a higher order method: const CourseController = { createCourse: ({ CourseService }) => async (httpRequest) => { const course = await CourseService.doCreateCourse(httpRequest. ...

Modifying Characteristics of Elements Added Dynamically

How do I change the type attribute for dynamically added buttons? In the code below, the label names are changing perfectly, but when I try to change button types, it applies to all dynamically added buttons. My requirement is to change every button type t ...

What is the best way to establish a default selection in Angular?

After retrieving JSON data from the server, it looks something like this: $scope.StateList = {"States": [ { "Id": 1, "Code": "AL", "Name": "Alabama" }, { "Id": 2, "Code": "AK", "Name": "Alask ...

How about this: "Looking to Share on Social Media with ME

After developing an app using MEAN.js, I made enhancements to the Articles (blog) section to improve SEO, readability, and design. However, one issue I'm struggling with is how to properly share these Articles on social media platforms like Facebook, ...

Tips on updating content at a specific time without the need to refresh the page

I'm working on a digital signage script that needs to be time scheduled. I was able to accomplish this using JavaScript and refreshing the page every 15 minutes. However, my question is, how can I track the time and update the content at specific hour ...

Encountering a MiniCssExtractPlugin error while trying to build with npm

I have encountered an issue while trying to execute "Npm Run Build" on my reactjs website. The error message I keep receiving is as follows: /usr/local/lib/node_modules/react-scripts/config/webpack.config.js:664 new MiniCssExtractPlugin({ ^ TypeErr ...

The executable file installed by WebdriverManager for Chrome is experiencing issues

There is a discrepancy in the logs where webdrivermanager successfully downloads the chrome binary in .m2, but it is being picked up from another location. This particular implementation works fine locally, but encounters issues in the Azure Pipeline envi ...

Adding items to a dropdown list using AngularJS

I'm attempting to add an item to my dropdown list by targeting its ng-class after a save function in AngularJS. However, I am struggling to understand what the issue might be as I am still new to AngularJS. Any advice would be greatly appreciated: Dr ...

Tips for preventing a React component from re-fetching data when navigating back using the browser button

In my React app using Next.js and the Next Link for routing, I have two pages set up: /product-list?year=2020 and /product-list/details?year=2020&month=4 Within the pages/product-list.js file, I am utilizing React router to grab the query parameter ye ...

Accessing instance variables from a chained observable function in Angular 2/Typescript

Currently, I am utilizing Angular2 along with Typescript. Let's assume that there is a dummy login component and an authentication service responsible for token authentication. In one of the map functions, I intend to set the variable authenticated as ...

Is it necessary to specify the JavaScript version for Firefox? (UPDATE: How can I enable `let` in FF version 44 and below)

Our recent deployment of JavaScript includes the use of the let statement. This feature is not supported in Firefox browsers prior to version 44, unless JavaScript1.7 or JavaScript1.8 is explicitly declared. I am concerned about the potential risks of usi ...

I am facing an issue with effectively passing properties from a parent state to its child component

In the Login component, I set the authentication state using the token as false initially. After a successful login, the token is changed to true. function Login() { const [user, setUser] = useState({ name: '', email: '' }); const [ ...

Setting the borderRadius for a web view on Android Maps V3: A complete guide

In my application, I am using Android Map V3 and have encountered a bug specific to the Kit-Kat version. The chromium kit throws up an error message - nativeOnDraw failed; clearing to background color, which prevents the map from being displayed. Despite ...