2
votes

I've got a select menu with multiple selections enabled.

<select id="regions" data-placeholder="Choose a Region..." multiple style="height: 35px;" data-bind="options: availableRegions,selectedOptions: selectedRegions,optionsText: 'name',optionsValue: 'value',event: { change: filterResellersByRegion }"></select>

I've bound the select to a json array. While setting up the data-bind on the select, I wired up an observableArray to the selectedOptions property. Here's my viewmodel:

function ResellersViewModel() {
var self = this;

self.availableRegions = ko.observableArray([{
    'name': 'United States',
        'value': 'united-states'
}, {
    'name': 'Canada',
        'value': 'canada'
}, {
    'name': 'Latin America &amp; the Caribbean',
        'value': 'latin-america-caribbean'
}, {
    'name': 'Europe, Middle East &amp; Africa',
        'value': 'europe-middle-east-africa'
}, {
    'name': 'Asia-Pacific &amp; Japan',
        'value': 'asia-pacific-japan'
}, {
    'name': 'China &amp; North Asia',
        'value': 'china-north-asia'
}]);

self.resellers = [{
    'name': '2S',
        'url': 'http://www.2s.com.br/',
        'urlText': 'www.2s.com.br',
        'status': 'gold',
        'city': '',
        'regions': ['latin-america-caribbean']
}, {
    'name': 'Abacus Solutions LLC',
        'url': 'http://www.abacusllc.com/',
        'urlText': 'www.abacusllc.com',
        'status': 'gold',
        'city': '',
        'regions': ['united-states']
}, {
    'name': 'Accunet Solutions, Inc.',
        'url': 'http://www.accunetsolutions.com/',
        'urlText': 'www.accunetsolutions.com',
        'status': 'platinum',
        'city': '',
        'regions': ['united-states']
}, {
    'name': 'Accuvant',
        'url': 'http://www.accuvant.com/',
        'urlText': 'www.accuvant.com',
        'status': 'gold',
        'city': '',
        'regions': ['united-states']
}, {
    'name': 'Activar Soulciones, S.A. de C.V.',
        'url': 'http://www.activar.com.mx/',
        'urlText': 'www.activar.com.mx',
        'status': 'gold',
        'city': '',
        'regions': ['latin-america-caribbean']
}, {
    'name': 'Adcap Network Solutions',
        'url': 'http://www.adcapnet.com/',
        'urlText': 'www.adcapnet.com',
        'status': 'gold',
        'city': '',
        'regions': ['united-states']
}, {
    'name': 'Advanced Infraestructure & Security Solutions, SA',
        'url': 'http://www.aiss.com.mx/',
        'urlText': 'www.aiss.com.mx',
        'status': 'gold',
        'city': '',
        'regions': ['latin-america-caribbean']
}, {
    'name': 'Advanced Systems Group',
        'url': 'http://www.virtual.com/',
        'urlText': 'www.virtual.com',
        'status': 'gold',
        'city': '',
        'regions': ['united-states']
}, {
    'name': 'AE Business Solutions',
        'url': 'http://www.aebs.com/',
        'urlText': 'www.aebs.com',
        'status': 'platinum',
        'city': '',
        'regions': ['united-states']
}, {
    'name': 'Alexander Open Systems',
        'url': 'http://www.aos5.com/',
        'urlText': 'www.aos5.com',
        'status': 'gold',
        'city': '',
        'regions': ['united-states']
}];

self.selectedRegions = ko.observableArray();

self.selectedResellers = ko.observableArray(self.resellers.slice(0));

self.filterResellersByRegion = function () {
    alert(self.selectedRegions.length);
};
}

ko.applyBindings(new ResellersViewModel());

As I read the documentation, that array is supposed to be updated as the selections are changed. I'm using the change event as well. I'm trying to use the change event to trigger a filter on another json array. However, the observable I have wired up to selectedOptions never gets data inserted into it. This can be seen with my alert on the change event which checks the length of the array. What am I doing wrong? I have setup a jsfiddle for this issue, feel free to check it out. Thanks for your help with this.

1
As a note you need to use multiple="multiple" to properly work in all browsers - PW Kad

1 Answers

1
votes

You have to call the observableArray with the () to get its length value. I'm not sure why (haven't looked into it) but the .length property on an observableArray doesn't update and is always 0. This is an issue with getting the underlying array's length value with just a property (source)

alert(self.selectedRegions().length);

That will get you a result.

Unless there's another need to have that event bound to this element, I'd remove it and deal with subscriptions/computeds to do your filtering on an array. Here's a fiddle with some notes.