Reputation: 979
I am looking for a bit of advice on what would be the best way to handle two arrays of objects (one being a subset of another) and checkboxes.
Basically I have this fiddler as an example. The code I am actually working with is full on with database support and everything.
I am trying to achieve a binding between of checkboxes between a full set of members and a selected subset of members.
// member model
var Member = function(item) {
var self = this;
self.id = item.id;
self.avatar = item.avatar;
self.name = item.name;
};
Basically I have the following model with three properties which I will not be modifying.
// card model
var Card = function (item) {
var self = this;
self.cardId = item.id;
self.title = ko.observable(item.title);
self.description = ko.observable(item.description);
self.contentItemId = ko.observable(item.contentItemId);
self.dueDate = ko.observable("");
self.comments = ko.observable(0);
self.openItems = ko.observable(0);
self.completedItems = ko.observable(0);
self.labels = ko.observable("");
self.members = ko.observable("");
...
};
And this is where the magic needs to happen. By definition database stores Members as a comma separated list e.g. (",1,2,3,4,5"). I already written code to retrieve full list of members and individual members to populate
self.members = ko.observable([]);
What I am thinking is to update individual Card with appropriate Member as card is being initialised for the first time.
So far so good!
In the view I want to trigger self.editMembers function which by definition should hide all content in cardLeftColumn (well maybe apart from Cards title) and display full list (table) of members with two additional buttons to Save and to Close.
So far so good!?
My main problem right now, hrm, how do I word this, checkboxes. I want checkboxes to get checked for those users in Card.members dataset when I call self.editMembers. Just to clarify Card.members will contain a subset of Board.members array (which isn't defined yet).
If you take a look at fiddler you will notice at the moment I binded a list of Card.members on table row, and that because I am not sure how to achieve what I am looking to get done.
I am also not sure how to retrieve a list of selected members (which I would then need to save in the database) on Save action.
Another thing I am unsure of is how to bind edit link/button on card to be visible to members that are assigned to specific card (Card.members). Any advice in this depart would come in handy but not a show stopper. I haven't quite pinned down what way I am going to determine which user is viewing the page. But it is very like to be users id. In other words I probably end up comparing page viewers' user id to Card.members.id to determine if edit link/button is to be available to them.
And just to summarise I am looking for a bit of advice with the following:
1. how to link checkboxes between two datasets
2. how to get at list of checked members at Save action
3. and a bit of advice of how to hide edit link/button from users that are not assigned to the card
Thank you for taking the time to read my post.
Added fiddler link to my example that I was referring too.
So just to recap @Haridarshan has provided some interesting suggestions below.
Last night I fetched a list of all members from database and added them as
self.members = ko.observable([]);
on BoardViewModel. That is just before I initialise lists with their card I fetched and initialised a list of members.
I also fetched individual members assigned to each card and initialised self.members = ko.observable([]);
on each card.
Effectively I was to bind all members array in BoardViewModel on the table but I ended getting an error that my BoardViewModel.members are undefined in the current context which would be true because the table that I was trying to bind too would be in the context of Card.members.
I need to doodle a bit on this with provided suggestion from @Haridarshan. So we shall see where I got from here.
Using some of the advice by @Haridarshan I managed to bind edit link/button using if: function(ref)
- Click me. Not 100% working yet but its almost there.
I've extended Module model with self.isChecked = ko.observable(false);
and now I can get at members that were selected. Which means I can send new list of assigned members to the database.
That still leaves the issue of binding all members to the table. I tried $root.members
which didn't give me result I was after. But even if it did I am still unsure how I am going to cross check that list to Card.members. I might end up modifying self.editMembers function to do that.
Upvotes: 1
Views: 862
Reputation: 1920
As far as I understood self.members observable contains the Members model. So, you can map your data to self.members through mapping. Assuming self.members is an observable array and data is the response data of Member Details from database.
self.members(jQuery.map(data, function (item) {
return new Member(item);
}));
In html, using foreach binding, you display all member list with checkbox. So, you need to add checkbox observable in Member model.
var Member = function(item){
var self = this;
self.id = item.id;
self.avatar = item.avatar;
self.name = item.name;
self.isChecked = ko.observable(false);
self.isVisible = ko.observable(<conditional statement whether to hide or show>);
}
and assuming you're showing the data like this
<!--ko foreach: members-->
<input type="checkbox" data-bind="visible: isVisible, checked: isChecked" />
<div data-bind="text: id"></div>
<div data-bind="text: avatar"></div>
<div data-bind="text: name"></div>
<!-- /ko -->
Now, you want to have editing functionality for each member, so the edit method should be bind to Members model
var Member = function(item){
var self = this;
self.id = item.id;
self.avatar = item.avatar;
self.name = item.name;
self.isChecked = ko.observable(false);
self.isVisible = ko.observable(<conditional statement whether to hide or show>);
self.editMember = function(data){
// here you will do the edit functionality
}
}
further, for hiding edit button/link from users that are not assigned to the card, you can add visible observable to the Member model and in checkbox binding you add the visible binding.
For Save action, since you need the list of entire member who are checked that method should be added to Item Model.
var Card = function (item) {
var self = this;
...
...
self.Save = function(data){
//using ko.utils.arrayForEach, loop through all members and check for isChecked observable
// and do whatever you want to do.
}
}
Upvotes: 1