Retrieve boolean value from selected array object

2019-08-05 09:39发布

问题:

Objective

I'm trying to create a form that will display different dropdown(select) lists based on a single first choice of "Plan Type" e.g.("Basic", "Standard", "Deluxe").

If a user selects "Basic", then the user can choose from a new dropdown list called "Option A". If they select "Standard" or "Deluxe" then they receive "Option B".

Edit to Objective

I guess I just really need to have the isOptionA or isOptionB available for consumption in my view.

Requirement

The user can only see the options that they have selected, I do not want to show disabled fields of any kind (reason: its a bad experience for basic users, IMO).

Also, the options in all dropdowns are not to be changed by the user at any point in time.

Past Research

I've crawled all sorts of sites, including SO. None of them can help me put it all together.

HTML

<div>
    <select id="planType" data-bind="options: planTypes, value: selectedPlanType, optionsText : 'name', optionsValue : 'id', optionsCaption : 'Select your Plan'"></select>
</div>
<div data-bind="if: isOptionA">
    Option A Available!
</div>

Knockout JS

var viewModel = function(){
    var self = this;
    self.planTypes = [
        { id: 0, name: 'Basic', optionA: false, optionB: true },
        { id: 1, name: 'Standard', optionA: true, optionB: false },
        { id: 2, name: 'Deluxe', optionA: true, optionB: false }
    ];

    self.selectedPlanType = ko.observable();
    self.isOptionA = ko.computed(function(){
        //pass the currently selected plan type's boolean for optionA to
        //'isOptionA'
    });
    self.isOptionB = ko.computed(function(){
        //pass the currently selected plan type's boolean for optionB to
        //'isOptionB'
    });

};

ko.applyBindings(viewModel);

Please view my js fiddle here and lend help if you can.

http://jsfiddle.net/winsconsinfan/9jqgazfx/9/

回答1:

It would be easier to not set the optionsValue in your binding. By setting the optionsValue, the value gets projected to the property of the selected option. In this case, selectedPlanType will be the id if the corresponding selected option. It would make everything easier to just use the option itself so you don't have to figure out which was selected again.

<select id="planType" data-bind="options: planTypes,
                                 value: selectedPlanType,
                                 optionsText: 'name',
                                 optionsCaption: 'Select your Plan'">
</select>

Given now that the selectedPlanType will now hold the actual planType object that was selected, it's just a matter of checking the selected plan type's option value.

self.selectedPlanType = ko.observable(); // now a planType object, not id
self.isOptionA = ko.computed(function(){
    var selectedPlanType = self.selectedPlanType();
    return selectedPlanType && !!selectedPlanType.optionA;
});
self.isOptionB = ko.computed(function(){
    var selectedPlanType = self.selectedPlanType();
    return selectedPlanType && !!selectedPlanType.optionB;
});

http://jsfiddle.net/9jqgazfx/10/


Otherwise, if you need that select to actually use the id, you'll need to make some adjustments to you figure out which planType object is selected from the id. A computed observable will help here.

<select id="planType" data-bind="options: planTypes,
                                 value: selectedPlanTypeId,
                                 optionsText: 'name',
                                 optionsValue: 'id',
                                 optionsCaption: 'Select your Plan'">
</select>
self.selectedPlanTypeId = ko.observable();
self.selectedPlanType = ko.computed(function () {
    var selectedPlanTypeId = self.selectedPlanTypeId();
    return ko.utils.arrayFirst(self.planTypes, function (planType) {
        return planType.id == selectedPlanTypeId;
    });
});

http://jsfiddle.net/9jqgazfx/14/



回答2:

var viewModel = function(){
var self = this;
self.planTypes = [
    { id: 0, name: 'Basic'},
    { id: 1, name: 'Standard'},
    { id: 2, name: 'Deluxe'}
];

self.selectedPlanType = ko.observable();
self.isOptionA = ko.computed(function(){
    return (self.selectedPlanType() != null)? self.selectedPlanType() != 0 ? true :false :false;
});

self.isOptionB = ko.computed(function(){
    return (self.selectedPlanType() != null)?self.selectedPlanType() == 0 ? true :false :false;
});
};
ko.applyBindings(viewModel);

The above code should help you out. All we are doing is looking if the selected option has a value and is equal to something you want . ie standard, basic etc.

http://jsfiddle.net/9jqgazfx/13/