Search code examples
javascriptangularjssortingangularjs-orderby

Angularjs orderBy sorting issues - ie, sorts 10 before 8


I'm working on this app that is supposed to sort py IP address, so to get around issues of soring by what is essentially a string I break the IP address into octets and attempt to sort by each octect consecutively. But I'm having some issues with Angularjs's "orderBy" function when applied to my data:

<tr ng-hide="row.length" class="tablehover tr-list" ng-repeat="row in entries | filter:search | orderBy:['ipA','ipB','ipC','ipD']">
                <td class="table-item col-1 col"><img ng-src="./img/{{row.health}}" class="status-color"></td>
                <td class="table-item col-2 col text-ip">{{ row.ipaddr }}</td>
                <td class="table-item col-3 col">{{ row.nickname }}</td>
                <td class="table-item col-4 col text-dns">{{ row.dnsname }}</td>
                <td class="table-item col-5 col text-type">{{ row.type }}</td>
                <td class="table-item col-6 col"><center><img ng-src="./img/{{row.reserved}}" class="status-reserved"></center></td>
                <td class="table-item col-7 col"><div id="editBtn" class="flat icon" name="editBtn" ng-model="editBtn" type="button" ng-click="edit(row)"><img src="./img/edit.png" class="inline-icon edit"></button></div>
                <td class="table-item col-8 col"><div id="deleteBtn" class="flat icon" name="deleteBtn" value="./img/delete.png" ng-click="delete(row)"><img src="./img/cancel.png" class="inline-icon delete"></div></td>
                <!-- these are for sorting purposes only -->
                <td class="hidden">{{ row.subnet }}</td>
                <td class="hidden">{{ row.location }}</td>
                <td class="hidden">{{ row.vlan }}</td>
                <td class="hidden">{{ row.notes }}</td>
                <td class="">{{row.ipA}}.{{row.ipB}}.{{row.ipC}}.{{row.ipD}}</td>
            </tr>

In theory this is supposed to order like:

1.1.1.1
8.8.8.8
10.10.10.10

But in reality it orders like this:

1.1.1.1
10.10.10.10
8.8.8.8

I'd like to avoid having to take the octect and converting it to a 3-digit integer (ie, 001.001.001.001); I feel like this should be something easy and I've just screwed up something simple.

Things I've already tried:

forcing angular to see each octect as a number (doesn't work)

{{ row.ipA | number }}

converting each octect to a float when each new record is saved to the DB:

var octets = ($scope.ipaddr).split(".");
$scope.ipA = parseFloat(octets[0]);
$scope.ipB = parseFloat(octets[1]);
$scope.ipC = parseFloat(octets[2]);
$scope.ipD = parseFloat(octets[3]);

Thanks!


Solution

  • Try doing this:

    In your controller add this function:

    $scope.ipOrder = function(row){
        return (
                (parseInt(row.ipA)*Math.pow(256,3))+
                (parseInt(row.ipB)*Math.pow(256,2))+
                (parseInt(row.ipC)*256)+
                parseInt(row.ipD));
    }
    

    And then in your ng-repeat do this:

    ng-repeat="row in entries | filter:search | orderBy:ipOrder
    

    Working Example