Mujahid
Mujahid

Reputation: 1237

Knockout click event visible state

I'm new to Knockout js and I found an issue in button click event. I have a list where each list item has a button for comment. When I click the button, the invisible comment box should be visible. Following is my HTML code:

<ul class="unstyled list" data-bind="foreach: filteredItems">
    <li>
        <input type="checkbox" value="true"  data-bind =" attr: { id: id }"  name="checkbox" class="checkbox">
        <label class="checkbox-label" data-bind="text: title, attr: { for: id }"></label>
        <button class="pull-right icon" data-bind="click: loadComment, attr: { id: 'btn_' + id }"><img src="../../../../../Content/images/pencil.png" /></button>
        <div class="description" data-bind="visible: commentVisible, attr: { id : 'item_' + id}">
            <textarea data-bind="value: comment" class="input-block-level" rows="1" placeholder="Comment" name="comment"></textarea>
            <div class="action">
                <button class="accept" data-bind="click: addComment">
                    <img src="../../../../../Content/images/accept.png" /></button>
                <button class="cancel" data-bind="click: cancel">
                    <img src="../../../../../Content/images/cancel.png" /></button>
            </div>
        </div>
    </li>
</ul>

In my view model, I have mentioned when click the loadComment the comment should be visible

var filteredItems = ko.observableArray([]),
    filter = ko.observable(),
    items = ko.observableArray([]),
    self = this;

self.commentVisible = ko.observable(false);
self.comment = ko.observable();
self.addComment = ko.observable(true);
self.cancel = ko.observable();

self.loadComment = function (item) {
    self.commentVisible(true);
}

The problem is when I click the loadComment button, all the comment boxes in each list items getting visible. I want to make only the clicked button's comment box should be appear.

Need some help.

Thanks

Upvotes: 0

Views: 1399

Answers (1)

Gary.S
Gary.S

Reputation: 7121

You declaration doesnt make much sense to me. commentVisible is not a property of filteredItems so when doing a foreach, it will not be accessible unless you use the $parent binding. FilteredItems itself is a private variable and will not be exposed to the viewmodel and that should cause the binding to fail. I would look at the error console to see if that gives any clues.

Here is what I did to make a somewhat working example (note that this uses parent binding and is probably not what you are going for):

var VM = (function() {
    var self = this;

    self.filteredItems = ko.observableArray([{id: 1, title: 'Test'}]);
    self.filter = ko.observable();
    self.items = ko.observableArray([]);
    self.commentVisible = ko.observable(false);
    self.comment = ko.observable();
    self.addComment = ko.observable(true);
    self.cancel = function(){
        self.commentVisible(false);
    };

    self.loadComment = function (item) {
        self.commentVisible(true);
    }
    return self;
})();

ko.applyBindings(VM);

http://jsfiddle.net/infiniteloops/z93rN/

Knockout binding contexts: http://knockoutjs.com/documentation/binding-context.html

What you probably want to do it to create a filtered item object with those properties that are referenced within the foreach and populate the filteredItems obeservable array with them.

That might look something like this:

var FilteredItem = function(id,title){
    var self = this;    
    self.id = id;
    self.title = title;
    self.commentVisible = ko.observable(false);
    self.comment = ko.observable();
    self.addComment = ko.observable(true);
    self.cancel = function(){
        self.commentVisible(false);
    };    
    self.loadComment = function (item) {
        self.commentVisible(true);
    }
}

var VM = (function() {
    var self = this;
    var item = new FilteredItem(1, 'Test');
    self.filteredItems = ko.observableArray([item]);
    self.filter = ko.observable();
    self.items = ko.observableArray([]);

    return self;
})();

ko.applyBindings(VM);

http://jsfiddle.net/infiniteloops/z93rN/2/

Upvotes: 1

Related Questions