RichL
RichL

Reputation: 183

Disable entire dropdown with knockoutjs observable

I have the following code which represents a Viewmodel and associated HTML for display using Knockout.js. I would like to work out how to disable the entire dropdown control (not just a single select item) if 'IsAnnualLeave' is true.

Viewmodel:

function viewModel(){

    var self=this;

    self.TimeEntryAssignmentViewModels = ko.observableArray();

    self.TimeEntryAssignmentViewModels.push(new TimeEntryAssignmentViewModel(1, 'Test 1', false));
    self.TimeEntryAssignmentViewModels.push(new TimeEntryAssignmentViewModel(2, 'Test 2', false));
    self.TimeEntryAssignmentViewModels.push(new TimeEntryAssignmentViewModel(3, 'Test 3', true));

    function TimeEntryAssignmentViewModel(AssignmentID, CodeName, IsAnnualLeave) {
        var self = this;
        this.AssignmentID = ko.observable(AssignmentID);
        this.CodeName = ko.observable(CodeName);
        this.IsAnnualLeave = ko.observable(IsAnnualLeave);
    }
}

ko.applyBindings(new viewModel());

HTML:

<select class="form-control" data-bind="options: TimeEntryAssignmentViewModels,
            optionsValue: 'AssignmentID', optionsText: 'CodeName',
            value: 3, optionsCaption: '-- please select --',
            disable: IsAnnualLeave "></select>

How do I reference the current item in my observable array 'viewModel.TimeEntryAssignmentViewModels' in order to do this?

I have tried accessing the property directly using:

disable: IsAnnualLeave

However, that does not work. Here is a jsfiddle: http://jsfiddle.net/Lm5zyLvg/5/

Upvotes: 0

Views: 2863

Answers (1)

afrikaan
afrikaan

Reputation: 425

However, I would like to work out how to access the currently selected item in the dropdown rather than always getting the value from the third item in the array.

If you want to access selected item in the dropdown you have to define an observable that holds the selected items value.

 self.selected=ko.observable();

After that you have to tell ko to bind this with value binding.

<select data-bind="options:List,value:selected"></select>

Then you can access it from your ViewModel. In your case you have already binded a value value: AssignmentID.

I dont know if the AssignmentID is observable but if its not you have to make it observable. Then you can access it. Here is a sample for you : Sample observableArray selection

What I'm trying to accomplish is to disable the entire dropdown control when my web page loads existing data only when the currently selected item has the observable of 'IsAnnualLeave' set to 'true'.

Update 2:

The problem is how to handle selection changing and update selected elements disable property with knockout. You can use event binding for that.

event:{change:$root.evnt} 

And in the viewModel you just simply:

    self.evnt=function()
{
    //change logic here.

}

In your case you have to bind the selected item in a ko.observable and bind change event. Then you can modify your select item property. You can bind observables to visible and disable attributes of an html element.

Here is the full code: Html:

<select data-bind="options: TimeEntryAssignmentViewModels,optionsValue: 'IsAnnualLeave', optionsText: 'CodeName',disable:dis,value:selected,event:{change:$root.evnt}"></select>

javascript:

function viewModel(){

var self=this;
    self.TimeEntryAssignmentViewModels = ko.observableArray();

self.TimeEntryAssignmentViewModels.push(new TimeEntryAssignmentViewModel(1, 'Test 1', false));
self.TimeEntryAssignmentViewModels.push(new TimeEntryAssignmentViewModel(2, 'Test 2', false));
self.TimeEntryAssignmentViewModels.push(new TimeEntryAssignmentViewModel(3, 'Test 3', true));

self.selected=ko.observable();
self.dis=ko.observable(false);

self.evnt=function()
{
    if(self.selected()){
    self.dis(true);
    }
}

function TimeEntryAssignmentViewModel(AssignmentID, CodeName, IsAnnualLeave) {
    var self = this;
    this.AssignmentID = ko.observable(AssignmentID);
    this.CodeName = ko.observable(CodeName);
    this.IsAnnualLeave = ko.observable(IsAnnualLeave);
}

}

ko.applyBindings(new viewModel());

The jsfiddle file: NewJsFiddle

Update 3

Well, if you absolutely want to bind your AssignmentID to the selected value that means a bit of extra work. First you have to iterate your observableArray and then check if any of items IsAnnualLeave property is false. Then visible the select.

new Html:

<select data-bind="options: TimeEntryAssignmentViewModels,optionsValue: 'AssignmentID', optionsText: 'CodeName',disable:dis,value:selected,event:{change:$root.evnt}"></select>

change the evnt function in ViewModel:

self.evnt=function()
{
     ko.utils.arrayForEach(self.TimeEntryAssignmentViewModels(), function(item) {
    var value = item.IsAnnualLeave();
         if(value){
         self.dis(true);
         }
});

ko.utils.arrayForEach is what you need. You can find a lot of info about utils here :Utils

And the final fiddle:Final

Upvotes: 1

Related Questions