Reputation: 345
I am developing an app using HTML5, Knockouk and Jquery.
The UI presents a list of Orders. At first it will show 5 orders, and when a user clicks on a "Show More" button, the next 5 orders will show.
When an Order is clicked, I will show all the activities that are related to that Order and I will be showing the first 10 activites and so on when the user clicks on the "More" button.
I have created a small example based on the requirements. I have created the first step, but I'm not able to create step 2. I am unsure how to create a nested observable array. I have added a sample, which is working for step but not for the second step.
<h1>Using Observable Arrays<br /></h1>
<div id="divActivites">
<!-- ko foreach: Activities -->
<div data-bind="click:$root.showDesc, attr:{'name':name,'id':id}">
<td><span data-bind="text:name"></span></td>
<td><span data-bind="text:id"></span></td>
</div>
<!-- /ko -->
<input type="button" value="Show More" data-bind="click:addData" />
</div>
<div id="divActDec" data-bind="with:selectedData ">
<span data-bind="text:id"></span><br />
<span data-bind="text:name"></span><br />
<span data-bind="text:randomStringDesc()"></span>
</div>
<script type="text/javascript">
function ActivityListModel() {
var self = this;
var total = ko.observable();
self.Activities = ko.observableArray([]);
self.selectedData = ko.observable();
total = 0;
self.addData = function () {
var addtoArray = 5;
var finalVal = total + addtoArray;
for (var i = total+1; i <= finalVal; i++) {
self.Activities.push(
{
name: randomString(),
id: i
}
)
}
total = finalVal;
}
self.showDesc = function (ActivitiesDesc) {
$("#divActivites").hide();
$("#divActDec").show();
self.selectedData(ActivitiesDesc);
}
}
function ActivitiesDesc(data) {
var activitydesc = this;
activitydesc.name = data.name;
activitydesc.actid = data.id;
}
function randomString() {
var value = "";
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 10; i++) {
value += letters.charAt(Math.floor(Math.random() * letters.length));
}
return value;
}
function randomStringDesc() {
var value = "";
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 150; i++) {
value += letters.charAt(Math.floor(Math.random() * letters.length));
}
return value;
}
ko.applyBindings(new ActivityListModel());
</script>
Can someone tell me how to create ActivitiesDesc object as an observable array?
Thanks, Jollyguy
Upvotes: 0
Views: 329
Reputation: 22733
Here's a working version of what I think you're after:
Firstly I nested the details section into the foreach
block and created an observable to control it's visibility showDesc
and the click
binding was modified to call toggleDesc
, which switches the visibility on or off:
<!-- ko foreach: Activities -->
<div data-bind="click:$root.toggleDesc, attr:{'name':name,'id':id}">
<div>Name: <span data-bind="text:name"></span>
</div>
<div>Id: <span data-bind="text:id"></span>
</div>
</div>
<!-- added this block with a visible binding -->
<div id="divActDec" data-bind="visible: showDesc"
style="border: 1px solid #000;">
<h1>Details:</h1>
ID: <span data-bind="text:id"></span><br />
Name: <span data-bind="text:name"></span><br />
Desc: <span data-bind="text:randomStringDesc()"></span>
</div>
<!-- /ko -->
In the JS, you will see a new observable per Activity
that looks like this:
showDesc: ko.observable(false)
This is set to false by default. Then there is the method to toggle the description when you click an item:
self.toggleDesc = function (item) {
item.showDesc(!item.showDesc());
}
Full JS
function ActivityListModel() {
var self = this;
var total = ko.observable();
self.Activities = ko.observableArray([]);
self.selectedData = ko.observable();
total = 0;
self.addData = function () {
var addtoArray = 5;
var finalVal = total + addtoArray;
for (var i = total + 1; i <= finalVal; i++) {
self.Activities.push({
name: randomString(),
id: i,
showDesc: ko.observable(false)
})
}
total = finalVal;
}
self.toggleDesc = function (item) {
item.showDesc(!item.showDesc());
}
}
function ActivitiesDesc(data) {
var activitydesc = this;
activitydesc.name = data.name;
activitydesc.actid = data.id;
}
function randomString() {
var value = "";
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 10; i++) {
value += letters.charAt(Math.floor(Math.random() * letters.length));
}
return value;
}
function randomStringDesc() {
var value = "";
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 150; i++) {
value += letters.charAt(Math.floor(Math.random() * letters.length));
}
return value;
}
ko.applyBindings(new ActivityListModel());
Update:
I've updated the sample to nest an observableArray
in to the top level array. I have renamed the top level array to be Orders
, which now contains an array of activities
:
The for loop now looks like this:
for (var i = total + 1; i <= finalVal; i++) {
self.Orders.push({
name: randomString(),
id: i,
showDesc: ko.observable(false),
activities: ko.observableArray([{
"name": "Description 1",
"actid": 123
}, {
"name": "Description 2",
"actid": 456
}])
})
Upvotes: 1