Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout issue displaying content based on dropdown value

I just created a jsfiddle so that u can do quick edits JSFIDDLE Link to Code

As you can see the Array selectedChoice works fine in the dropdown and displays content based on the dropdown selected value.

However, when I try to use a CountryModel with properties id and name it is trowing errors in Internet Explorer but not in Firefox. however, is odd that the default behavior is not to hide the content <p>This content appear when US is selected</p>

I suspect this code

    <section data-bind="visible: selectedChoiceWithModel().name==='US'"> 

I also tried this

<section data-bind="if: selectedChoiceWithModel().name === 'Russia', 
     hasfocus: selectedChoiceWithModel().name === 'Russia'">
    <p>This content appear when Russia is selected</p>

Two issues:

enter image description here

Typescript code

class CountryModel {
    id: number;
    name: string;

}

compiles to

var CountryModel = (function () {
    function CountryModel() {
    }
    return CountryModel;
})();

Typescript Code /// /// ///

class ViewModel {
    constructor()
    {
        //initialize the data for the model now this has two purposes. Consider separating the model from its data generation. 
        var x = new CountryModel();
        x.id = 1;
        x.name = "Russia";
        var y = new CountryModel();
        y.id = 2;
        y.name = "US";
        this.countries.push(x);
        this.countries.push(y);
    }

    availableDrugs = ['A', 'B', 'others'];
    firstName: KnockoutObservable<string>  = ko.observable();
    isVisible: KnockoutObservable<boolean> = ko.observable(true); 
    selectedChoice = ko.observable();
    selectedChoiceWithModel = ko.observable();
    countries: KnockoutObservableArray<CountryModel> = ko.observableArray([]);
    sendMe = function () {

        alert(ko.toJSON({ selectedCountryId: this.selectedChoice() }));
    };
}


$(() => {
    ko.applyBindings(new ViewModel(), document.getElementById("model"));
});

Compiles to

/// <reference path="CountryModel.ts" />
/// <reference path="../Scripts/typings/knockout/knockout.d.ts" />
/// <reference path="../Scripts/typings/jquery/jquery.d.ts" />
var ViewModel = (function () {
    function ViewModel() {
        this.availableDrugs = ['A', 'B', 'others'];
        this.firstName = ko.observable();
        this.isVisible = ko.observable(true);
        this.selectedChoice = ko.observable();
        this.selectedChoiceWithModel = ko.observable();
        this.countries = ko.observableArray([]);
        this.sendMe = function () {
            alert(ko.toJSON({ selectedCountryId: this.selectedChoice() }));
        };
        //initialize the data for the model now this has two purposes. Consider separating the model from its data generation.
        var x = new CountryModel();
        x.id = 1;
        x.name = "Russia";
        var y = new CountryModel();
        y.id = 2;
        y.name = "US";
        this.countries.push(x);
        this.countries.push(y);
    }
    return ViewModel;
})();

$(function () {
    ko.applyBindings(new ViewModel(), document.getElementById("model"));
});

Html code

<!--http://jsfiddle.net/pkysylevych/dqUAz/2/
    http://stackoverflow.com/questions/12516123/use-knockout-to-hide-display-questions-based-on-selected-value-in-drop-down
    http://jsbin.com/egacil/2/edit
    http://www.codeproject.com/Articles/342244/Knockout-that-cascading-dropdown

    -->
@section scripts
{
    <script src="~/js/RequestFormModel.js"></script>
    <script src="~/js/CountryModel.js"></script>
}
<div id="model">

<p>First name: <strong data-bind="text: firstName"></strong></p>


<p>First name: <input data-bind="value: firstName" /></p>

   <input type="checkbox" data-bind="checked: isVisible"/>
   <div data-bind="if: isVisible">Hide this content.</div>

        <!--Display content usign observable array--> 
    <select data-bind="options: availableDrugs, value: selectedChoice, optionsCaption: 'choose..'"></select> 
      <input type="text" data-bind="value: firstName, visible: selectedChoice() === 'others', hasfocus: selectedChoice() === 'others'" /> 


    <section data-bind="visible: selectedChoice() === 'A', hasfocus: selectedChoice() === 'A'">
        <p> This content appear when a is selected</p>

    </section>
    <section data-bind="visible: selectedChoice() === 'B', hasfocus: selectedChoice() === 'B'">
        <p>This content appear when B is selected</p>
    </section>




    <!---Sample number two with models instead of just an array --> 
      <select data-bind="options: countries, optionsText: 'name', value: selectedChoiceWithModel, optionsCaption: 'Choose...'"></select>



            <section data-bind="visible: selectedChoiceWithModel().name==='US'">
            <p>This content appear when US is selected</p>
    </section>


</div>
like image 559
hidden Avatar asked Mar 06 '26 18:03

hidden


1 Answers

I suspect your binding is breaking in ie and not in other better browsers because of a case error that ie can't handle.

The hasFocus binding is camelCase so try converting all your hasfocus bindings to hasFocus.

Edit

Alright, your problem was more than one -

http://jsfiddle.net/BJhQz/14/

You need to make sure that selectedChoiceWithModel is defined before you try to bind to properties on it. I added a containerless binding to your view to keep from trying to see the name of it if it was not yet selected.

Next, I made a few updates to your view model to make it easier to understand for me. I am not saying they are required, but without them your view model was suffering from my inability to read it.

StackOverflow.com wants some code so here it is -

<!-- ko if: selectedChoiceWithModel() -->
    <section data-bind="visible: $data.selectedChoiceWithModel().name() === 'Russia'">
        <p>This content appear when Russia is selected</p>
    </section>
    <h1 data-bind="text: selectedChoiceWithModel().name()"></h1>
<!-- /ko -->
like image 179
PW Kad Avatar answered Mar 09 '26 07:03

PW Kad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!