function TreeNode(id, parentId, name) {
var self = this;
self.id = id;
self.parentId = parentId;
self.name = name;
self.isOpen = ko.observable(true);
}
$getCountries = function () {
var countries = [{ "CountryID": 2008, "parentId": 0, "fullName": "Asia", "PARENT": 0, "GROUP_CODE": 0, "LocalName": "Asia", "LatinName": "Asia" }, { "CountryID": 2009, "parentId": 0, "fullName": "Africa", "PARENT": 0, "GROUP_CODE": 0, "LocalName": "Africa", "LatinName": "Africa" }, { "CountryID": 2010, "parentId": 0, "fullName": "Europe", "PARENT": 0, "GROUP_CODE": 0, "LocalName": "Europe", "LatinName": "Europe" }, { "CountryID": 2011, "parentId": 0, "fullName": "Australia", "PARENT": 0, "GROUP_CODE": 0, "LocalName": "Australia", "LatinName": "Australia" }, { "CountryID": 2012, "parentId": 0, "fullName": "North America", "PARENT": 0, "GROUP_CODE": 0, "LocalName": "North America", "LatinName": "North America" }, { "CountryID": 2013, "parentId": 0, "fullName": "South America", "PARENT": 0, "GROUP_CODE": 0, "LocalName": "South America", "LatinName": "South America" }, { "CountryID": 2014, "parentId": 2009, "fullName": "Algeria", "PARENT": 0, "GROUP_CODE": 2009, "LocalName": "Algeria", "LatinName": "Algeria" }, { "CountryID": 2015, "parentId": 2009, "fullName": "Angola", "PARENT": 0, "GROUP_CODE": 2009, "LocalName": "Angola", "LatinName": "Angola" }, { "CountryID": 2016, "parentId": 2011, "fullName": "Australia", "PARENT": 0, "GROUP_CODE": 2011, "LocalName": "Australia", "LatinName": "Australia" }, { "CountryID": 2017, "parentId": 2009, "fullName": "Cameroon", "PARENT": 0, "GROUP_CODE": 2009, "LocalName": "Cameroon", "LatinName": "Cameroon" }, { "CountryID": 2018, "parentId": 2009, "fullName": "Egypt", "PARENT": 0, "GROUP_CODE": 2009, "LocalName": "ُEgypt", "LatinName": "Egypt" }, { "CountryID": 2019, "parentId": 2010, "fullName": "France", "PARENT": 0, "GROUP_CODE": 2010, "LocalName": "France", "LatinName": "France" }, { "CountryID": 2020, "parentId": 2010, "fullName": "Italy", "PARENT": 0, "GROUP_CODE": 2010, "LocalName": "Italy", "LatinName": "Italy" }, { "CountryID": 2021, "parentId": 2010, "fullName": "Portugal", "PARENT": 0, "GROUP_CODE": 2010, "LocalName": "Portugal", "LatinName": "Portugal" }, { "CountryID": 2022, "parentId": 2010, "fullName": "England", "PARENT": 0, "GROUP_CODE": 2010, "LocalName": "England", "LatinName": "England" }, { "CountryID": 2023, "parentId": 2010, "fullName": "Spain", "PARENT": 0, "GROUP_CODE": 2010, "LocalName": "Spain", "LatinName": "Spain" }, { "CountryID": 2024, "parentId": 2013, "fullName": "Argentina", "PARENT": 0, "GROUP_CODE": 2013, "LocalName": "Argentina", "LatinName": "Argentina" }, { "CountryID": 2025, "parentId": 2013, "fullName": "Brazil", "PARENT": 0, "GROUP_CODE": 2013, "LocalName": "Brazil", "LatinName": "Brazil" }, { "CountryID": 2026, "parentId": 2013, "fullName": "Colombia", "PARENT": 0, "GROUP_CODE": 2013, "LocalName": "Colombia", "LatinName": "Colombia" }, { "CountryID": 2027, "parentId": 2012, "fullName": "USA", "PARENT": 0, "GROUP_CODE": 2012, "LocalName": "USA", "LatinName": "USA" }, { "CountryID": 2028, "parentId": 2012, "fullName": "Canada", "PARENT": 0, "GROUP_CODE": 2012, "LocalName": "Canada", "LatinName": "Canada" }, { "CountryID": 2029, "parentId": 2012, "fullName": "Mexico", "PARENT": 0, "GROUP_CODE": 2012, "LocalName": "Mexico ", "LatinName": "Mexico" }, { "CountryID": 2030, "parentId": 2008, "fullName": "Malaysia", "PARENT": 0, "GROUP_CODE": 2008, "LocalName": "Malaysia ", "LatinName": "Malaysia" }, { "CountryID": 2031, "parentId": 2008, "fullName": "KSA", "PARENT": 0, "GROUP_CODE": 2008, "LocalName": "KSA", "LatinName": "KSA" }, { "CountryID": 2032, "parentId": 2008, "fullName": "China", "PARENT": 0, "GROUP_CODE": 2008, "LocalName": "China", "LatinName": "China" }, { "CountryID": 2033, "parentId": 2008, "fullName": "India", "PARENT": 0, "GROUP_CODE": 2008, "LocalName": "India", "LatinName": "India" }];
var mapped = _.map(countries, function (c) { return new TreeNode(c.CountryID, c.parentId, c.fullName); });
mapped.unshift(new TreeNode(0, null, 'root'));
return mapped;
};
$getClubs = function () {
var clubs = [{ "ClubID": 1, "CountryID": 2014, "ClubName": "CO Harrach" },
{ "ClubID": 2, "CountryID": 2018, "ClubName": "Ahly" },
{ "ClubID": 3, "CountryID": 2018, "ClubName": "Zamalek" },
{ "ClubID": 4, "CountryID": 2017, "ClubName": "Bonaberi FC" },
{ "ClubID": 5, "CountryID": 2015, "ClubName": "Benfica de Luanda" },
{ "ClubID": 6, "CountryID": 2019, "ClubName": "FC Mantes" },
{ "ClubID": 7, "CountryID": 2020, "ClubName": "Milan" },
{ "ClubID": 8, "CountryID": 2020, "ClubName": "Parma" },
{ "ClubID": 9, "CountryID": 2020, "ClubName": "Juventus" },
{ "ClubID": 10, "CountryID": 2022, "ClubName": "Liverpool" },
{ "ClubID": 11, "CountryID": 2022, "ClubName": "Mansfield" },
{ "ClubID": 12, "CountryID": 2022, "ClubName": "Arsenal" },
{ "ClubID": 13, "CountryID": 2022, "ClubName": "Manchester United" },
{ "ClubID": 14, "CountryID": 2023, "ClubName": "Real Madrid*" },
{ "ClubID": 15, "CountryID": 2023, "ClubName": "Real Sociedad" },
{ "ClubID": 16, "CountryID": 2023, "ClubName": "Barcelona" },
{ "ClubID": 17, "CountryID": 2025, "ClubName": "Santos" },
{ "ClubID": 18, "CountryID": 2025, "ClubName": "Grêmio" },
{ "ClubID": 19, "CountryID": 2025, "ClubName": "Atlético Paranaense" },
{ "ClubID": 20, "CountryID": 2025, "ClubName": "ABC Natal" }];
return _.map(clubs, function (c) { return new TreeNode(c.ClubID, c.CountryID, c.ClubName); });
};
function MyViewModel() {
var self = this;
self.countries = ko.observableArray($getCountries());
self.clubs = ko.observableArray($getClubs());
self.merge = ko.observableArray(self.countries().concat(self.clubs()));
self.getChildren = function (parent, list) {
return _.filter(list, function (item) { return parent.id == item.parentId; });
};
}
ko.applyBindings(new MyViewModel());
ul {
list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<ul data-bind="template: { name: 'mytemplate', data: _.find(merge(), function (c) { return c.id == 0 }) }">
</ul>
<script type="text/html" id='mytemplate'>
<li>
<span data-bind="click: () => { isOpen(!isOpen()); }, text: isOpen() ? '-' : '+'">
</span>
<span data-bind="text: name"></span>
<!-- ko if: isOpen-->
<ul data-bind="template: { name: 'mytemplate', foreach: $root.getChildren($data, $root.merge()) }"></ul>
<!-- /ko -->
</li>
</script>