Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout Manual Subscription Not Firing on Dropdown change

Another Knockout question that I can't seem to find help on.

I am basically trying to implement a cascading dropdown. I requested help the other day on how to parse my complicated JSON (which is coming from a cakePHP controller. The help I received the other day was excellent but I have run into another small issue.

The problem I am having is I am updating the viewModel after I make a call to JSON to get a list of countries. Once I populate the dropdown I want the list of counties to be displayed and eventually a list of cities but I am not there yet. Unfortunatly when I change I select a country from the list my observable doesn't fire. I suspect it is because I have created this.selectedCountry = ko.observable() and updating using the mapping but I do not know what a valid option for this should be. Of course I could also be way of the mark :/

I have the following code

HTML:

<select id="countries" 
            data-bind='
                options: countries, 
                optionsValue : "Id", 
                optionsText: "country", 
                optionsCaption: "[Please select a country]", 
                value: selectedCountry'>
</select>

<select id="counties" 
                data-bind='
                    options: selectedCountry() ? counties : null, 
                    optionsValue : "Id", 
                    optionsText: "County", 
                    optionsCaption: "[Please select a county]", 
                    value: selectedCounty,
                    visible: (counties() && counties().length > 0)'>
        </select>

​Javascript

var countryData= {"countries":[{"Country":{"id":"1","country":"England"}},{"Country":{"id":"2","country":"Wales\/Cymru"}},{"Country":{"id":"3","country":"Scotland"}},{"Country":{"id":"4","country":"Republic of Ireland"}},{"Country":{"id":"5","country":"Northern Ireland"}}]};

var countyData= {"country":[{"County":{"id":"1","county":"Essex"}}]};

var countryMappingOptions = {
    'countries': {
        'update': function (options) {
            return ko.mapping.fromJS(options.data.Country);
        },
        'ignore': ["selectedCountry"]
    }
};

 var countyMappingOptions = {
    'counties': {
        'update': function (options) {
            return ko.mapping.fromJS(options.data.County);
        }
    }
};
        var vm= function () {
            this.selectedCountry = ko.observable(); 
            this.selectedCounty =  ko.observable();
            this.countries = ko.mapping.fromJS([]); 
            this.counties =  ko.mapping.fromJS([]);
            // Whenever the continent changes, reset the country selection
            this.selectedCountry.subscribe(function (countryId) {
                alert(countryId);   
                this.selectedCounty(undefined);
                this.counties(undefined);
                if (countryId != null) {
                   ko.mapping.fromJS(countyData, countyMappingOptions,this.viewModel );
              }
            });
            this.selectedCounty.subscribe(function (countryId) {
                alert(countryId);    
            } .bind(this));
        };

        var viewModel = new vm();
        ko.applyBindings(viewModel );
        console.log(viewModel .countries());
        ko.mapping.fromJS(countryData, countryMappingOptions ,viewModel );
        console.log(viewModel .selectedCountry() );

I have also created a JSFiddle to demo the problem here http://jsfiddle.net/jbrr5/21/

Again any help with this issue will be appreciated and once I get the hang of knockout it will be so much easier.

Thanks ​

like image 532
user1771329 Avatar asked Oct 26 '12 14:10

user1771329


1 Answers

Some issues:

  • you forgot to do .bind(this) on the first subscribe
  • this.viewModel instead of just this
  • you had optionsValue: "Id" instead of optionsValue: "id"
  • you had optionsText: "County" instead of optionsText: "county"
  • your countyData's array is called country instead of counties

Updated fiddle: http://jsfiddle.net/antishok/jbrr5/23/

like image 67
antishok Avatar answered Oct 04 '22 08:10

antishok