Skip to content

Instantly share code, notes, and snippets.

@ilianaza
Last active August 29, 2015 14:04
Show Gist options
  • Save ilianaza/a1bce83ffd14c6a7da2e to your computer and use it in GitHub Desktop.
Save ilianaza/a1bce83ffd14c6a7da2e to your computer and use it in GitHub Desktop.
AngularJS "partition" or "split" filter for ng-repeat directive

ng-repeat filter that splits data into multiple sorted columns

It breaks or splits an array of elements into multidimensional array where data is sorted either horizontally (by row) or vertically (by column).

partitionFilter(array, columns, vsort), where
array   - input array
columns - number of columns or partition size
vsort   - boolean value for vertical sort (default "true"), 
          if set to false then data sorted horizontally

Example:

arr = ["Austria","Belgium","Croatia","Denmark","Ecuador","Finland","Germany"]

partitionFilter(arr, 3) ->        [ ["Austria", "Denmark", "Finland" ],
partitionFilter(arr, 3, true) ->    ["Belgium", "Ecuador", "Germany" ],
                                    ["Croatia"                       ] ]
                                   
partitionFilter(arr, 3, false) -> [ ["Austria", "Belgium", "Croatia" ],
                                    ["Denmark", "Ecuador", "Finland" ],
                                    ["Germany"                       ] ]

Big shout-out to the answer by m59 on the Stackoverflow

<!-- Break an array of countries into 3-column matrix and sort elements vertically (default option) -->
<div class="container">
<div class="row-fluid" ng-repeat="countryRow in region.countries | partition: 3">
<div class="span4" ng-repeat="country in countryRow">
{{country.name}}
</div>
</div>
</div>
<!-- Break an array of countries into 3-column matrix and sort elements horizontally -->
<div class="container">
<div class="row-fluid" ng-repeat="countryRow in region.countries | partition: 3: false">
<div class="span4" ng-repeat="country in countryRow">
{{country.name}}
</div>
</div>
</div>
"use strict"
describe "filter", ->
beforeEach module("app.filters")
describe "partition", ->
it "should partition array and sort elements vertically",
inject((partitionFilter) ->
expect(partitionFilter(["a1","a2","a3"], 2))
.toEqual [["a1","a3"],["a2"]]
expect(partitionFilter(["a1","a2","a3","a4"], 3))
.toEqual [["a1","a3","a4"],["a2"]]
expect(partitionFilter(["a1","a2","a3","a4","a5"], 3))
.toEqual [["a1","a3","a5"],["a2","a4"]]
expect(partitionFilter(["a1","a2","a3","a4","a5","a6","a7"], 3))
.toEqual [["a1","a4","a6"],["a2","a5","a7"],["a3"]]
return
)
it "should partition array and sort elements horizontally",
inject((partitionFilter) ->
expect(partitionFilter(["a1","a2","a3"], 2, false))
.toEqual [["a1","a2"],["a3"]]
expect(partitionFilter(["a1","a2","a3","a4"], 3, false))
.toEqual [["a1","a2","a3"],["a4"]]
expect(partitionFilter(["a1","a2","a3","a4","a5"], 3, false))
.toEqual [["a1","a2","a3"],["a4","a5"]]
expect(partitionFilter(["a1","a2","a3","a4","a5","a6","a7"], 3, false))
.toEqual [["a1","a2","a3"],["a4","a5","a6"],["a7"]]
return
)
return
return
"use strict"
angular.module("app.filters", [])
.filter "partition", ->
_evenRows = (arr, cols) ->
rowsArr = _.clone(arr)
rows = Math.ceil rowsArr.length/cols
emptySlots = cols - (arr.length % cols)
if (emptySlots % cols) != 0
for slot in [1..emptySlots]
rowsArr.splice(((cols - emptySlots + slot) * rows) - 1, 0, null)
rowsArr
_toHorizontalOrderMatrix = (arr, cols) ->
rowsArr = []
arr = _evenRows(arr, cols)
rows = Math.ceil arr.length/cols
for row in [1..rows]
rowArr = []
for el, i in arr
if ((i+1) % rows) == row
rowArr.push el
else if (((i+1) % rows) == 0) && (row == rows)
rowArr.push el
rowsArr.push _.compact(rowArr)
rowsArr
_toVerticalOrderMatrix = (arr, cols) ->
rowsArr = []
i = 0
while i < arr.length
rowsArr.push arr.slice(i, i + cols)
i += cols
rowsArr
cache = {}
_filter = (arr, size, hOrder) ->
return unless arr
horizontalOrder = true
if typeof (hOrder) isnt "undefined"
horizontalOrder = hOrder
rowsArr = []
if horizontalOrder
rowsArr = _toHorizontalOrderMatrix arr, size
else
rowsArr = _toVerticalOrderMatrix arr, size
arrString = JSON.stringify(arr)
fromCache = cache[arrString + size]
return fromCache if JSON.stringify(fromCache) is JSON.stringify(rowsArr)
cache[arrString + size] = rowsArr
rowsArr
_filter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment