jQuery UI autocomplete - with source change fix
Fixed issue with not detecting changes to the source array.
https://groups.google.com/d/topic/knockoutjs/ABhEeI7jLKA/discussion
HTML
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/base/jquery-ui.css">
<script src="http://rniemeyer.github.com/KnockMeOut/Scripts/jquery.tmpl.js"></script>
<script src="http://rniemeyer.github.com/KnockMeOut/Scripts/knockout-latest.debug.js"></script>
<hr/>
<input data-bind="jqAuto: { autoFocus: true }, jqAutoSource: myPeople, jqAutoValue: mySelectedPerson, jqAutoSourceLabel: 'displayName', jqAutoSourceInputValue: 'name'" />
<hr/>
Selected Person's GUID:
<div data-bind="text: mySelectedPerson() ? mySelectedPerson().guid : 'No one selected'"></div>
<hr/>
<button data-bind="click: addPerson">add person</button>
<button data-bind="click: deletePerson">delete person</button>
<hr/>
For testing setting the model value elsewhere:
<select data-bind="options: myPeople, optionsCaption: 'select a person...', optionsText: 'displayName', value: mySelectedPerson"></select>
<hr/>
<div class="desc">
<h1>Description</h1>
Demonstrates using knockout with jQuery UI Autocomplete.
See https://groups.google.com/d/topic/knockoutjs/ABhEeI7jLKA/discussion for discussion.
<h1>History</h1>
This (http://jsfiddle.net/studgeek/rwvdd/14/)<br/>
Adds support for using objects as value<br/><br/>
http://jsfiddle.net/studgeek/rwvdd/12/<br/>
Demonstrates null issue when using objects (no jqAutoSourceValue)<br/><br/>
http://jsfiddle.net/rniemeyer/YNCTY (14)<br/>
http://jsfiddle.net/studgeek/rwvdd/4/<br/>
Fixed updates to source (list of options)<br/><br/>
http://jsfiddle.net/rniemeyer/YNCTY/13/<br/>
"Original" from rpn
</div>
CSS
h1 {
font-weight: bold;
color: blue;
font-size:
}
div.desc {
font-size: smaller;
}
JavaScript
//jqAuto -- main binding (should contain additional options to pass to autocomplete)
//jqAutoSource -- the array of choices
//jqAutoValue -- where to write the selected value
//jqAutoSourceLabel -- the property that should be displayed in the possible choices
//jqAutoSourceInputValue -- the property that should be displayed in the input box
//jqAutoSourceValue -- the property to use for the value
ko.bindingHandlers.jqAuto = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var options = valueAccessor() || {},
allBindings = allBindingsAccessor(),
unwrap = ko.utils.unwrapObservable,
modelValue = allBindings.jqAutoValue,
source = allBindings.jqAutoSource,
valueProp = allBindings.jqAutoSourceValue,
inputValueProp = allBindings.jqAutoSourceInputValue || valueProp,
labelProp = allBindings.jqAutoSourceLabel || valueProp;
//function that is shared by both select and change event handlers
function writeValueToModel(valueToWrite) {
if (ko.isWriteableObservable(modelValue)) {
modelValue(valueToWrite );
} else { //write to non-observable
if (allBindings['_ko_property_writers'] && allBindings['_ko_property_writers']['jqAutoValue'])
allBindings['_ko_property_writers']['jqAutoValue'](valueToWrite );
}
}
//on a selection write the proper value to the model
options.select = function(event, ui) {
writeValueToModel(ui.item ? ui.item.actualValue : null);
};
//on a change, make sure that it is a valid value or clear out the model value
options.change = function(event, ui) {
var currentValue = $(element).val();
var matchingItem = ko.utils.arrayFirst(unwrap(source), function(item) {
return unwrap(item[inputValueProp]) === currentValue;...