For a object have multiple attributes, for example, a shoe may have different color, size and etc.
Now when we tried to display the shoe, and make the customer can choose different attributes, we use radio(the simplest): https://jsfiddle.net/mwqy6217/
But how to make the availability of the view according to the data?
For example, when the red shoes are sold out, the red radio should be un-checkable. So are different sizes.
We can use this data structure to represent the shoe: {shoe:{name:'',available:['red','black','40','41']}}.
However different attributes may have relationship with each other, for example, red shoes with 40 size have been sold out, while black shoes with 40 size have not.
I think this data structure:
{shoe:{name:'',available:{color:{red:[40,41,42]},black:[42,43]}}}
As the shoe may have other attributes like 'weight', and an attributes may have 10+ options.
So how to represent this kind of relationship in the database and make them readable by the front engineer to build the view?
Update:
https://jsfiddle.net/xqtgqzt2/
See the live demo, all the available options is pre-defined as:
var options= [
["A1","B1","C1","D1"],
["A1","B3","D2"],
["A2","B1","C3","D2"]
];
Now how to make the radio button state changed according to the options? For example, when A1 is checked, only B1 B3 can be checked(enabled), when A1 B1 are checked, only C1 D1 can be checked.
To display your radio buttons regarding the option multidimensionnal array, you can do something like :
var options = [
["A1", "B1", "C1", "D1"],
["A1", "B3", "D2"],
["A2", "B1", "C3", "D2"]
];
var firstLevel = [];
var selectedList = [];
//Enable first options, disable the others
$("input[type=radio]").each(function (indexInput) {
var that = this;
that.disabled = true;
$.each(options, function (index, value) {
firstLevel.push(value[0]);
if (value[0] == that.value) {
that.disabled = false;
}
});
});
//on check radio, change states
$("input[type=radio]").on("click", function () {
var thatClicked = this;
if (firstLevel.indexOf(thatClicked.value) !== -1) {
$('input[type=radio]').removeAttr('checked');
$(thatClicked).prop('checked', true);
}
var possibleOptions = [];
selectedList.push(thatClicked.value);
$.each(options, function (index, value) {
possibleOptions = possibleOptions.concat(value[0]);
var posInArray = value.indexOf(thatClicked.value);
if (posInArray !== -1 && typeof value[posInArray + 1] !== 'undefined') {
//check previous options
$.each(selectedList, function (indexSelectedList, valueSelectedList) {
if (value.indexOf(valueSelectedList) !== -1) {
possibleOptions = possibleOptions.concat(value[posInArray + 1]);
}
});
}
});
$("input[type=radio]").each(function (indexInput) {
if (possibleOptions.indexOf(this.value) !== -1) {
this.disabled = false;
} else {
this.disabled = true;
}
});
});
.section {
padding: 10px;
overflow: hidden;
}
label {
float: left;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class="section">
<label>
<input type="radio" value="A1" /> <span>A1</span>
</label>
<label>
<input type="radio" value="A2" /> <span>A2</span>
</label>
</div>
<div class="section">
<label>
<input type="radio" value="B1" /> <span>B1</span>
</label>
<label>
<input type="radio" value="B2" /> <span>B2</span>
</label>
<label>
<input type="radio" value="B3" /> <span>B3</span>
</label>
</div>
<div class="section">
<label>
<input type="radio" value="C1" /> <span>C1</span>
</label>
<label>
<input type="radio" value="C2" /> <span>C2</span>
</label>
<label>
<input type="radio" value="C3" /> <span>C3</span>
</label>
</div>
<div class="section">
<label>
<input type="radio" value="D1" /> <span>D1</span>
</label>
<label>
<input type="radio" value="D2" /> <span>D2</span>
</label>
</div>
</div>
<div id="info">var options= [ ["A1","B1","C1","D1"], ["A1","B3","D2"], ["A2","B1","C3","D2"] ];</div>
I would set my data up similar to your second option, however because the first thing they are going to care about is size (you can't change your shoe size), I would show available colours for a size, rather than available sizes for a colour. You would first of all list all availability because if a customer knows that a size 9 green "happy shoe" is potentially available, they might come back later to buy it. You would then loop through the available options to change whether that size or colour is available.
Here's the data set up:
var objShoes = [{
name: 'Happy Shoe',
sizes: [9,10,11,12,13],
colours: ['red','blue','green'],
available: [{
size: 9,
colours: ['red']
},{
size: 10,
colours: ['red', 'blue']
},{
size: 11,
colours: ['blue']
},{
size: 12,
colours: ['red', 'blue']
},{
size: 13,
colours: ['red']
}]
}, {
name: 'Scary Shoe',
sizes: [8,9,10,11,12],
colours: ['black','grey'],
available: [{
size: 8,
colours: ['black']
}]
}];
Here's an example of how that could work, although I used select boxes instead of radio buttons. They're neater :).
The easier way IMHO is to separate the data itself from the definition of an attribute, and not having a hierarchy between attributes. To do this you'll need every attribute value to have a unique id.
In this example I use the index of every attribute in the array as an id to reference it from the availability object.
{
attributes: [
{value: "red", type: "colour"}, // 0
{value: "green", type: "colour"}, // 1
{value: "black", type: "colour"}, // 2
{value: "brown", type: "colour"}, // 3
{value: 40, type: "size"}, // 4
{value: 41, type: "size"}, // 5
{value: 42, type: "size"}, // 6
{value: 43, type: "size"}, // 7
{value: 44, type: "size"}, // 8
{value: true, type: "with_shoelace"}, // 9
{value: false, type: "with_shoelace"}, // 10
],
products: [
{
name: 'some random shoe',
availability: {
0: [4, 7, 8, 9], // red is compatible with 40, 43 and 44, only with shoelace
1: [4, 5, 9, 10], // green is compatible with 40, 43 and 44, with or without shoelace
...
6: [2, 3, 9, 10], // 42 can be black or brown, with or without shoelace
7: [0, 1, 10], // 43 can be red or green, without shoelace
...
10: [1, 4, 6, 7, 8], // ...
}
},
{
name: 'another shoe',
availability: {
...
}
}
]
}
On the GUI, you'll have to intersect the availability arrays from each checked attribute in order to determine which option is usable.
Related
to make things clear... I want to explain the basis first.
I have a PRODUCT.
a PRODUCT has different VARIANTS (id, code, price).
VARIANTS have ATTRIBUTES (id, type[select, radio], name).
ATTRIBUTES have VALUES (id, label).
I have a REACT APP to handle variant selecting in product detail (where u add the product into the cart).
It's functioning is this:
All attributes are printed by ID and their selecting html input type is made according to their type (I've specified above).
So... WHAT I WANT TO ACCOMPLISH is THIS.
EXAMPLE:
I have 2 attributes: COLOR, SIZE.
COLOR has 2 values: WHITE, BLACK.
SIZE HAS 3 VALUES: M, L, S.
Product "A" has 2 variants:
#1 VARIANT - COLOR: WHITE; SIZE: M
#2 VARIANT - COLOR: BLACK; SIZE: L,
in a react APP.. I want to filter out ALL options that aren't available to select an existing variant. User CAN NOT select COLOR WHITE; SIZE L variant because it doesn't exist. So, I want to disable the option for him/her.
My REACT STATE structure is the following...
{
"attributes": [
{
"id": 1,
"type": "select",
"name": "size",
"values": [{id: 1, value: "M", selected: true}, {id: 2, value: "L", selected: false}, {id: 3, value: "S", selected: false}],
},
{
"id": 2,
"type": "radio",
"name": "color",
"values": [{id: 1, value: "WHITE", selected: false}, {id: 2, value: "BLACK", selected: false}],
}
],
"variants": [
{
id: 1,
values: [
{
attribute_id: 1,
id: 1
},
{
attribute_id: 2,
id: 1
}
]
},
{
id: 2,
values: [
{
attribute_id: 1,
id: 2
},
{
attribute_id: 2,
id: 2
}
]
}
]
}
so...when I select color WHITE and the size stays unselected... only the option "M" should be displayed. But when I select color BLACK... the size option should be "L" only.
but when NOTHING is selected => EVERYTHING should be visible.
This check should happen EVERYTIME any ATTRIBUTE VALUE Changes. (when I select a SIZE = FILTER OTHER ATTRIBUTES etc...) and it should work dynamically no matter how many attributes are available for a variant.
Any ideas on how to do this please?
THANKS FOR YOUR HELP :)
Description
I have a small product order system, where a user can add order lines, and on each order line add one or more products. (I realise it's quite unusual for more than one product to be on the same order line, but that's another issue).
The products that can be selected on each line is based on a hierarchy of products. For example:
Example product display
T-Shirts
V-neck
Round-neck
String vest
JSON data
$scope.products = [
{
id: 1,
name: 'T Shirts',
children: [
{ id: 4, name: 'Round-neck', children: [] },
{ id: 5, name: 'V-neck', children: [] },
{ id: 6, name: 'String vest (exclude)', children: [] }
]
},
{
id: 2,
name: 'Jackets',
children: [
{ id: 7, name: 'Denim jacket', children: [] },
{ id: 8, name: 'Glitter jacket', children: [] }
]
},
{
id: 3,
name: 'Shoes',
children: [
{ id: 9, name: 'Oxfords', children: [] },
{ id: 10, name: 'Brogues', children: [] },
{ id: 11, name: 'Trainers (exclude)', children: []}
]
}
];
T-Shirts isn't selectable, but the 3 child products are.
What I'm trying to achieve
What I'd like to be able to do, is have a 'select all' button which automatically adds the three products to the order line.
A secondary requirement, is that when the 'select all' button is pressed, it excludes certain products based on the ID of the product. I've created an 'exclusion' array for this.
I've set up a Plunker to illustrate the shopping cart, and what I'm trying to do.
So far it can:
Add / remove order lines
Add / remove products
Add a 'check' for all products in a section, excluding any that are in the 'exclusions' array
The problem
However, although it adds the check in the input, it doesn't trigger the ng-change on the input:
<table class="striped table">
<thead>
<tr>
<td class="col-md-3"></td>
<td class="col-md-6"></td>
<td class="col-md-3"><a ng-click="addLine()" class="btn btn-success">+ Add order line</a></td>
</tr>
</thead>
<tbody>
<tr ng-repeat="line in orderHeader.lines">
<td class="col-md-3">
<ul>
<li ng-repeat="product in products" id="line_{{ line.no }}_product_{{ product.id }}">
{{ product.name }} <a ng-click="selectAll(product.id, line.no)" class="btn btn-primary">Select all</a>
<ul>
<li ng-repeat="child in product.children">
<input type="checkbox"
ng-change="sync(bool, child, line)"
ng-model="bool"
data-category="{{child.id}}"
id="check_{{ line.no }}_product_{{ child.id }}"
ng-checked="isChecked(child.id, line)">
{{ child.name }}
</li>
</ul>
</li>
</ul>
</td>
<td class="col-md-6">
<pre style="max-width: 400px">{{ line }}</pre>
</td>
<td class="col-md-3">
<a ng-click="removeLine(line)" class="btn btn-warning">Remove line</a>
</td>
</tr>
</tbody>
</table>
Javascript
$scope.selectAll = function(product_id, line){
target = document.getElementById('line_'+line+'_product_'+product_id);
checkboxes = target.getElementsByTagName('input');
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].type == 'checkbox') {
category = checkboxes[i].dataset.category;
if($scope.excluded.indexOf(parseInt(category)) == -1)
{
checkboxes[i].checked = true;
// TODO: Check the checkbox, and set its bool parameter to TRUE
}
}
}
}
Update with full solution
There were a couple of issues with the above code. Firstly, I was trying to solve the problem by manipulating the DOM which is very much against what Angular tries to achieve.
So the solution was to add a 'checked' property on the products so that I can track if they are contained on the order line, and then the view is updated automatically.
One drawback of this method is that the payload would be significantly larger (unless it is filtered before being sent to the back-end API) as each order line now has data for ALL products, even if they aren't selected.
Also, one point that tripped me up was forgetting that Javascript passes references of objects / arrays, not a new copy.
The solution
Javascript
var myApp = angular.module('myApp', []);
myApp.controller('CartForm', ['$scope', function($scope) {
var inventory = [
{
id: 1,
name: 'T Shirts',
checked: false,
children: [
{ id: 4, name: 'Round-neck', checked: false, children: [] },
{ id: 5, name: 'V-neck', checked: false, children: [] },
{ id: 6, name: 'String vest (exclude)', checked: false, children: [] }
]
},
{
id: 2,
name: 'Jackets',
checked: false,
children: [
{ id: 7, name: 'Denim jacket', checked: false, children: [] },
{ id: 8, name: 'Glitter jacket', checked: false, children: [] }
]
},
{
id: 3,
name: 'Shoes',
checked: false,
children: [
{ id: 9, name: 'Oxfords', checked: false, children: [] },
{ id: 10, name: 'Brogues', checked: false, children: [] },
{ id: 11, name: 'Trainers (exclude)', checked: false, children: []}
]
}
];
$scope.debug_mode = false;
var products = angular.copy(inventory);
$scope.orderHeader = {
order_no: 1,
total: 0,
lines: [
{
no: 1,
products: products,
total: 0,
quantity: 0
}
]
};
$scope.excluded = [6, 11];
$scope.addLine = function() {
var products = angular.copy(inventory);
$scope.orderHeader.lines.push({
no: $scope.orderHeader.lines.length + 1,
products: products,
quantity: 1,
total: 0
});
$scope.loading = false;
}
$scope.removeLine = function(index) {
$scope.orderHeader.lines.splice(index, 1);
}
$scope.selectAll = function(product){
angular.forEach(product.children, function(item){
if($scope.excluded.indexOf(parseInt(item.id)) == -1) {
item.checked=true;
}
});
}
$scope.removeAll = function(product){
angular.forEach(product.children, function(item){
item.checked=false;
});
}
$scope.toggleDebugMode = function(){
$scope.debug_mode = ($scope.debug_mode ? false : true);
}
}]);
Click here to see the Plunker
You are really over complicating things first by not taking advantage of passing objects and arrays into your controller functions and also by using the DOM and not your data models to try to update states
Consider this simplification that adds a checked property to each product via ng-model
<!-- checkboxes -->
<li ng-repeat="child in product.children">
<input ng-model="child.checked" >
</li>
If it's not practical to add properties to the items themselves, you can always keep another array for the checked properties that would have matching indexes with the child arrays. Use $index in ng-repeat for that
And passing whole objects into selectAll()
<a ng-click="selectAll(product,line)">
Which allows in controller to do:
$scope.selectAll = function(product, line){
angular.forEach(product.children, function(item){
item.checked=true;
});
line.products=product.children;
}
With angular you need to always think of manipulating your data models first, and let angular manage the DOM
Strongly suggest reading : "Thinking in AngularJS" if I have a jQuery background?
DEMO
Why ng-change isn't fired when the checkbox is checked programatically?
It happens because
if($scope.excluded.indexOf(parseInt(category)) == -1)
{
checkboxes[i].checked = true;
// TODO: Check the checkbox, and set its bool parameter to TRUE
}
only affects the view (DOM). ng-change works alongside ngModel, which can't be aware that the checkbox really changed visually.
I suggest you to refer to the solution I provided at How can I get angular.js checkboxes with select/unselect all functionality and indeterminate values?, works with any model structure you have (some may call this the Angular way).
I am using KendoUI Scheduler control and here is initialization code
$("#Scheduler").kendoScheduler({
dataSource: [],
selectable: true,
height: 500,
editable: false,
eventTemplate: $("#event-template").html(),
views: [
"day",
{ type: "week", selected: true },
"month",
"agenda"
],
resources: [
{
field: "resourceviewid",
name: "ResourceViews",
dataColorField: "key",
dataSource: [
{ text: "Appointments", value: 1, key: "orange" },
{ text: "Delivery Specialist", value: 2, key: "blue" },
{ text: "Orientation Specialist", value: 3, key: "green" }
]
}
],
group: {
resources: ["ResourceViews"],
orientation: "horizontal"
}
});
Here "Appointments" group is default, it will be available always
I have check box in my screen
<div id="divResourceView">
<label><input checked type="checkbox" value="1" />Delivery Specialist</label>
<label><input checked type="checkbox" value="2" />Orientation Specialist</label>
</div>
On change event I wrote below code to get selected values from checkbox and updating GROUP datasource of KendoUI scheduler as below
$("#divResourceView :checkbox").change(function (e) {
var checked = $.map($("#divResourceView :checked"), function (checkbox) {
return parseInt($(checkbox).val());
});
});
var scheduler = $("#Scheduler").data("kendoScheduler");
var arrayOfStrings = checked.toString().split(",");
for (var i = 0; i < arrayOfStrings.length; i++)
{
if(arrayOfStrings[i] == 1)
{
var data = [{ text: "Delivery Specialist", value: 2, color: "blue" }];
scheduler.resources[1].dataSource.data(data);
}
if (arrayOfStrings[i] == 2) {
var data = [{ text: "Orientation Specialist", value: 3, color: "green" }];
scheduler.resources[2].dataSource.data(data);
}
}
scheduler.refresh();
But it removes all groups and add only one. I want to see both groups when arrayOfStrings has values "1,2",
I can see all groups during initialization But it disappears when i check the check box.
Images for reference
During Initialization
After
As you can see clearly, Delivery Specialist is missing in scheduler control
Found some link: http://www.telerik.com/forums/add-filter-to-resource-datasource
But not sure what they talking about? seems like refresh issue.
I have done this I believe you're right and your issue is to do with refreshing, I use the following to refresh it.
var scheduler = $("#scheduler").data("kendoScheduler");
scheduler.view(scheduler.view().name);
hope this helps through it is stupidly late (I'm currently looking up how to do this lazerly
I'm still pretty new to JavaScript programming and I'm having an issue.
JSFiddle: http://jsfiddle.net/Y4pPj/
HTML:
<form id="practiceForm" style="display:inline">
<select id="practiceList" size="1">
<option value="sampleA" selected="selected">Sample A</option>
<option value="sampleB">Sample B</option>
<option value="sampleC">Sample C</option>
</select>
</form>
<button onclick="changeSelection();">Select</button><br />
<span id="currentSelected">Nothing selected</span><br /><br />
Name: <span id="name"></span><br />
Size: <span id="size"></span><br />
Shape: <span id="shape"></span><br />
Value: <span id="value"></span>
JavaScript:
/* var stats = {
sampleA: { name: "Alpha", size: 3, shape: square, value: 1 },
sampleB: { name: "Delta", size: 1, shape: circle, value: 10 },
sampleC: { name: "Gamma", size: 25, shape, triangle, value: 200 }
}; */
function changeSelection() {
document.getElementById("currentSelected").innerHTML = practiceForm.practiceList.options[practiceForm.practiceList.selectedIndex].value;
document.getElementById("name").innerHTML = currentSelected.name;
document.getElementById("size").innerHTML = currentSelected.size;
document.getElementById("shape").innerHTML = currentSelected.shape;
document.getElementById("value").innerHTML = currentSelected.value;
}
What I'm trying to do is, have a combobox list of items with a button. When you click the button, I need to change parts of the HTML to values that I've set in variables at the start.
The code, as it stands, works in JSFiddle. But, as soon as I un-comment the variable declaration, 'stats', it messes up, which really confuses me. Also, please excuse all the undisciplined stuff, like inline styles :) This was just for debugging test.
One more thing while I'm here- is there a way to shorthand the first line in the changeSelection() function? I've seen many examples, but they are all different.
It wont work like this. you need to access the stats through the selected value.
var stats = {
'sampleA': { name: "Alpha", size: 3, shape: 'square', value: 1 },
'sampleB': { name: "Delta", size: 1, shape: 'circle', value: 10 },
'sampleC': { name: "Gamma", size: 25, shape: 'triangle', value: 200 }
};
function changeSelection() {
document.getElementById("currentSelected").innerHTML = practiceForm.practiceList.options[practiceForm.practiceList.selectedIndex].value;
document.getElementById("name").innerHTML = stats[practiceList.value].name;
document.getElementById("size").innerHTML = stats[practiceList.value].size;
document.getElementById("shape").innerHTML = stats[practiceList.value].shape;
document.getElementById("value").innerHTML = stats[practiceList.value].value;
}
look at this fiddle.
http://jsfiddle.net/9QXc4/
It's throwing a syntax error in the console due to your object.
var stats = {
sampleA: { name: "Alpha", size: 3, shape: "square", value: 1 },
sampleB: { name: "Delta", size: 1, shape: "circle", value: 10 },
sampleC: { name: "Gamma", size: 25, shape: "triangle", value: 200 }
};
The above is the correct syntax. Things needed fixing:
-Quote property values! square, circle, and triangle were unquoted.
-The "shape" property had a comma rather than a colon to declare the value
Use the console when programming, you'll see this error right away:
Uncaught SyntaxError: Unexpected token ,
Which was caused by:
sampleC: { name: "Gamma", size: 25, shape, "triangle", value: 200 }
^^
Just replace sampleC: { name: "Gamma", size: 25, shape, triangle, value: 200 } with this sampleC: { name: "Gamma", size: 25, shape: triangle, value: 200 }
You put a comma instead of a colon
I have an application that is using angular.js and I'm very new to it. I have a list of checkboxes that gets dynamically created based on a previous selection.
For example, if I have a dropdown of Fruits, the following html will get created:
<input type='checkbox' value="apple">apple</input>
<input type='checkbox' value="banana">banana</input>
<input type='checkbox' value="mango">mango</input>
<input type='checkbox' value="orange">orange</input>
<input type='checkbox' value="pear">pear</input>
<input type='checkbox' value="watermelon">water</input>
However, sometimes the amount of checkboxes that get generated gets more than 20 items, and I want to make use of some unused space.
So I was wondering if it's possible to split a list of checkboxes into two columns instead of one, so that a new column will generate filling up the rest of the checkboxes?
For example: If I have 18 items, instead of one large list of a single column containing 18 checkboxes, the final result will be to have 10 checkboxes in on column, and 8 checkboxes in another column next to it. I want to only have 2 columns as the maximum. Is this possible?
Here is what I have so far, I'm not sure if this is the best way of doing it. Otherwise I'll just make an answer for this question and mark it as such. Logic for splitting the data will be done in code-behind I guess.
example: http://jsfiddle.net/7843b/
Visual representation
X Apple X Pears
X Banana X Watermelon
X Mango
X Orange
The X represents a checkbox.
Seems like these solutions are a bit more complicated than needs to be. Let css handle putting them into columns:
Javascript:
$scope things = ["car", "box", "plant", "dice", "knife", "calendar"];
html:
<div class="checkbox-column" ng-repeat='thing in things'>
<input type="checkbox" /><span>{{thing}}</span>
</div>
in the css display each element with an inline-block and a width around 48%.
.checkbox-column{
display: inline-block;
width:48%;
}
The width of 48% will give it 2 columns. If you want 3 columns, then just use a width of like 30%.
This will also keep the columns aligned when the browser window is adjusted.
Another way is to add column number to each team in the $scope.teams.
http://jsfiddle.net/dkitchen/y5UzD/4/
This splits them into groups of 10...
function TeamListController($scope) {
$scope.teams = [
{ name: "apple", id: 0, isChecked: true, col:1 },
{ name: "banana", id: 1, isChecked: false, col:1 },
{ name: "mango", id: 2, isChecked: true, col:1 },
{ name: "orange", id: 3, isChecked: true, col:1 },
{ name: "pear", id: 4, isChecked: false, col:1 },
{ name: "john", id: 5, isChecked: true, col:1 },
{ name: "paul", id: 6, isChecked: false, col:1 },
{ name: "george", id: 7, isChecked: true, col:1 },
{ name: "ringo", id: 8, isChecked: true, col:1 },
{ name: "roger", id: 9, isChecked: false, col:1 },
{ name: "dave", id: 10, isChecked: true, col:2 },
{ name: "nick", id: 11, isChecked: false, col:2 }
];
}
You can do that at the data source, or you can assign the column number later in the controller.
For example, this bit re-groups them into 8 items per column:
var colCounter = 1;
var colLimit = 8;
angular.forEach($scope.teams, function(team){
if((team.id + 1) % (colLimit + 1) == 0) {
colCounter++;
}
team.col = colCounter;
});
Then in the view, you can filter each repeater by column number:
<div ng-app>
<div ng-controller="TeamListController">
<div class="checkboxList">
<div id="teamCheckboxList">
<div ng-repeat="team in teams | filter: { col: 1 }">
<label>
<input type="checkbox" ng-model="team.isChecked" /> <span>{{team.name }}</span>
</label>
</div>
</div>
</div>
<div>
<div id="teamCheckboxList1">
<div ng-repeat="team in teams | filter: { col: 2 }">
<label>
<input type="checkbox" ng-model="team.isChecked" /> <span>{{team.name}}</span>
</label>
</div>
</div>
</div>
</div>
This is not so surprising question at all. You can dynamically add the items in either js or else you can do the same in html itself. I am here mentioning how to split dynamically based on the number of items.
function TeamListCtrl($scope) {
$scope.teams = [
{ name: "apple", id: 0, isChecked: true },
{ name: "banana", id: 1, isChecked: false },
{ name: "mango", id: 2, isChecked: true },
{ name: "orange", id: 3, isChecked: true },
{ name: "pear", id: 4, isChecked: false },
{ name: "watermelon", id: 5, isChecked: true }
];
column1 = [];
column2 = [];
$.each($scope.teams, function(index){
console.log("index"+index);
if(index%2==0) {
column1.push($scope.teams[index]);
} else{
column2.push($scope.teams[index]);
}
});
$scope.columns.push(column1);
$scope.columns.push(column2);
}
And you can modify your html code as:
<div ng-app>
<div ng-controller="TeamListCtrl" class="checkboxList">
<div id="teamCheckboxList">
<div ng-repeat='column in columns'>
<div class='someClassToArrangeDivsSideBySide' ng-repeat="team in column">
<label>
<input type="checkbox" ng-model="team.isChecked" /> <span>{{team.name}}</span>
</label>
</div>
</div>
</div>
</div>
</div>