I keep running into this problem and haven’t found a good solution that doesn’t cause layout issues. What’s the best way to display an array of items, sorted alphabetically, in columns? I’m using ng-repeat to iterate over an array and display a checkbox for each item. I want the data to be displayed in n columns, alphabetically i.e., not alphabetically in rows.
alphabetically in colums
|item a| |item d| |item g|
|item b| |item e| ...
|item c| |item f| ...
current implementation – alphabetically in rows
<div class="checkbox col-xs-12 col-sm-12 col-md-3 col-lg-3" ng-repeat="user in user.results | orderBy:'lastName' track by user.id">
<input id="{{ user.id }}" type="checkbox">
{{ user.lastName }}, {{ user.firstName }}
<label for="{{ user.id }}" class="pull-left checkbox-label"></label>
</div>
Edit
I originally went with the dynamic bootstrap method but this actually screwed up the checkbox behavior i.e., clicking a checkbox resulted in the incorrect checkbox being checked. I’m trying fix this using flexbox but I haven’t used it before and don’t understand how to dynamically change the column count without having to set a fixed height on the flex container. I would like to have one column on small/extra small screens and three columns for medium/large screens.
.flex-box {
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
.flex-item {
background: green;
width: 33%;
}
/* Small screens */
@media all and (max-width: @container-tablet) {
.flex-item {
width: 100%;
}
}
<div class="flex-box">
<div class="flex-item" ng-repeat="country in region.countries | orderBy:'name' track by $index">
<input id="{{ country.isoCode }}" checklist-model="vm.selectedCountries.value[region.name]" checklist-value="country" type="checkbox" ng-change="vm.setRegionCountry(region, country, checked)">
<label for="{{ country.isoCode }}" class="pull-left checkbox-label"></label>
<span>{{ country.name | limitTo:17 }}{{country.name.length > 17 ? '...' : ''}}</span>
</div>
</div>
Solution
.flex-box {
display: flex;
flex-flow: column wrap;
}
/* Small screens */
@media all and (min-width: @screen-sm-min) {
.flex-box {
max-height: 375px;
}
}
/* Medium screens */
@media all and (min-width: @screen-md-min) {
.flex-box {
max-height: 550px;
}
}
/* Large screens */
@media all and (min-width: @screen-lg-min) {
.flex-box {
max-height: 375px;
}
}
3
Answers
You could do this without bootstrap using columns. See this fiddle: https://jsfiddle.net/ojzdxpt1/1/
#wrapper
contains each repeater. See more about css columnsUsing CSS flexbox you can dynamically add as many column as required for your data set https://css-tricks.com/snippets/css/a-guide-to-flexbox/
You can tweak little bit as below if you want to use with
bootstrap
. Otherwise you can use eitherflex-box
orcolumn-count
.