Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connect knockout and jQueryUI autocomplete

I have a jQueryUI autocomplete that pulls from a list of customers and is attached based on the selector [input data-role="customer-search"]. Once a customer is selected, I make a AJAX call to get the full customer detail. This part I have working fine. The issue is that I am having trouble figuring out a way to incorporate knockout into this. My ideal situation is a custom binding like "onSelect: customerSelected", which would take in the selected Customer JSON and integrate it into the overall model, which would then cause updates to a bunch of fields on the page with bingings such as model.Customer.Address, model.Customer.Type.

The place I am butting my head against is that connection point after I've gotten the Customer JSON back from the AJAX call, how to send it to the "customerSelected" method on the viewmodel tied to the same input I attached the jQuery autocomplete.

like image 424
Rich Avatar asked Mar 29 '13 00:03

Rich


1 Answers

Here is a simplified version of a bindinghandler my team wrote for handling autocomplete. When an item is selected, the item is inserted into an observable array in the view model. It is bound in the following manner:

<input type="text" data-bind="autoComplete:myObservableArray, source:'myUrl'" />

You can customize what happens when an item is selected in the 'select:' area.

ko.bindingHandlers.autoComplete = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var postUrl = allBindingsAccessor().source; // url to post to is read here
        var selectedObservableArrayInViewModel = valueAccessor();

        $(element).autocomplete({
            minLength: 2,
            autoFocus: true,
            source: function (request, response) {
                 $.ajax({
                    url: postUrl,
                    data: { term: request.term },
                    dataType: "json",
                    type: "POST",
                    success: function (data) {
                        response(data);
                    }
                });
            },
            select: function (event, ui) {
                var selectedItem = ui.item;

                if (!_.any(selectedObservableArrayInViewModel(), function (item) { return item.id == selectedItem.id; })) { //ensure items with the same id cannot be added twice.
                    selectedObservableArrayInViewModel.push(selectedItem);
                }
            }
        });
    }
};

Hopefully, it's something like this that you're looking for. If you need something clarified, let me know.

Note Besides jquery and knockout, this example uses underscore.js ( the _.any() function)

like image 133
Rune Vejen Petersen Avatar answered Nov 18 '22 10:11

Rune Vejen Petersen