Reputation: 4923
I am trying to have the functionality of the jQuery selectable list when using KnockoutJS, but can't get it to work.
Using Custom Bindings I was successful in transforming ul
element in a selectable one and creating events handlers for the selected and unselected events. But what do I pass to my ViewModel functions which maintain the selected elements?
Here is my code so far: http://jsfiddle.net/QCmJt/
I am new to all this, so maybe I am approaching this the wrong way...
Upvotes: 1
Views: 2296
Reputation: 4923
Ok, I figured a way to pass the data bound to the selected item:
$(ui.selected).tmplItem().data
when selecting and
$(ui.selected).tmplItem().data
when unselecting.
Here the updated fiddle: http://jsfiddle.net/8RnxC/
Custom binding looks like:
ko.bindingHandlers.selectable = {
init: function(element, valueAccessor) {
$(element).attr("id", "selectable").selectable({
selected: function(event, ui) {
vm.selectRequest($(ui.selected).tmplItem().data);
},
unselected: function(event, ui) {
vm.unselectRequest($(ui.unselected).tmplItem().data);
}
});
}
};
And my view model:
function viewModel() {
// Data
this.requests = ko.observableArray([]);
this.selectedRequests = ko.observableArray([]);
// Behaviours
this.selectRequest = function(request) {
this.name = "othername";
// Add to array if not already there.
if ($.inArray(request, this.selectedRequests()) === -1) {
this.selectedRequests().push(request);
}
var self = this;
};
this.unselectRequest = function(request) {
// Remove from the array.
this.selectedRequests().splice($.inArray(request, this.selectedRequests()), 1);
};
};
Upvotes: 0
Reputation: 7584
Here is a little bit of a modified one from yours, got it working as well. It uses a selected property on each item in the array that's an observable to do two way communication. If you want a property that's just a list of the selected items, you could always create a dependent observable, or just a method to filter.
Created a custom binding:
ko.bindingHandlers.selectableItem = {
init: function(element, valueAccessor, allBindingsAccessor) {
var selectable = $(element).parent();
selectable.bind('selectableselected', function(event, ui) {
if(ui.selected === element) {
var value = valueAccessor();
value(true);
}
});
selectable.bind('selectableunselected', function(event, ui) {
if(ui.unselected === element) {
var value = valueAccessor();
value(false);
}
});
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var el = $(element);
if(valueAccessor()()) {
el.addClass('ui-selected');
} else {
el.removeClass('ui-selected');
}
}
};
It's not hardened for more than very simple two way bindings, but should be easy enough to build on.
Upvotes: 1