jQuery DataTablesのip-address

jQueryのDataTablesはテーブルに対して手軽にソート・検索・ページングの機能を追加できる。

このうち、ソート方法にもいろいろなpluginが用意されているのだが、`"type": "ip-address"`を、サブネット形式の場合に適用しようとしてうまくいかなかったので、備忘録。

まず、公式サイトに載っているのがこれ。

https://datatables.net/plug-ins/sorting/ip-address

ここのソースをみると、`1.2.3.4:80` のようにポート番号が指定されている場合には対応しているのだが、`1.2.3.0/24`のようにサブネット形式の場合にはうまくいかない。
なので、以下のように書き換えてみた。なお、もともとのものではIPv6を処理するコードも書かれているが、ここでは省略(私の周りにはIPv6屋ばかりなのだけど ;-)。

```javascript:ip-subnet.js
jQuery.extend( jQuery.fn.dataTableExt.oSort, {                                                                                       
     "ip-subnet-pre": function ( a ) {                                                                                               
         var i,decs,mask,nw_mask;                                                                                                     
 
         if (!a) { return 0 }                                                                                                         
                                                                                                                                      
         a = a.replace(/<[\s\S]*?>/g, "");                                                                                            
         nw_mask = a.split("/");                                                                                                      
         decs = nw_mask[0].split(".");                                                                                                
         if (decs.length != 4) { return 0; }                                                                                          
                                                                                                                                      
         mask = nw_mask.length === 2 ? nw_mask[1] : 32;                                                                              
         x = decs.map(function(n){return ("00"+n).slice(-3);})
         x += ("0"+(32 - mask)).slice(-2);                                                                                            
                                                                                                                                      
         return x;                                                                                                                    
     },                                                                                                                               
     "ip-subnet-asc": function ( a, b ) {                                                                                            
         return ((a < b) ? -1 : ((a > b) ? 1 : 0));                                                                                   
     },                                                                                                                               
                                                                                                                                      
     "ip-subnet-desc": function ( a, b ) {                                                                                           
         return ((a < b) ? 1 : ((a > b) ? -1 : 0));                                                                                   
     }                                                                                                                                
 });                      
```

やってることはわざわざ解説するほどのことではないだろうけど、"/"でsplitして、ネットマスクが指定されていなければ"/32"として扱う、というだけ。大小判定としては、オリジナルと同様、192.168.1.23なら、192168001023、と、各桁を3桁で0パディングしたものに、2桁で0パディングした 32-mask を連結した文字列を返している。もっとも、オリジナルのコードはかなり冗長かなという印象もなくはない(slice()を使わず、桁数をif～else if～elseで判別してパディングしている)。

一点、通常の運用だとあまりないと思うが、論理的な話として、`1.2.3.0/24`と`1.2.3.0/25`はどちらが「大きい」のか、という点については、ホスト部が広い方が大きいだろうということで、`32-mask`を使うことにした。

で、これで後は通常通り、

```javascript
     $('[id=subnet_table]').DataTable({
         "columnDefs": [
            { "type": "ip-subnet", "targets": 0 },
         ]
     }); 
```

のようにしてあげればおしまい。