Search code examples
knockout.jsknockout-validation

Checkbox validation on select


I have the following:

                    <tbody data-bind="foreach: { data: MenuItems, as: 'tableitem' }">
                    <tr>
                        <td data-bind="html: tableitem.label"></td>
                        <td>
                            <select class="form-control" data-bind="options: $root.GroupedScorecardTypes,
                        optionsText: 'Name', optionsValue: 'Id', value: tableitem.clean"></select>
                        </td>
                        <td>
                            <select class="form-control" data-bind="options: $root.GroupedScorecardTypes,
                        optionsText: 'Name', optionsValue: 'Id', value: tableitem.copy"></select>
                        </td>
                    </tr>
                </tbody>

Which displays the following: FrontEnd Table There are three options on the drop downs for each of them. They are : All data,Target Data and Ignore . Now when a user clicks on either All data or Target Data on the populate target column, the Clean target column for that row should change to Target Data. I tried the following but it didnt seem to work:

        self.MenuItems().forEach(function(data){
            
            if (data.copy == 2 || data.copy == 1){
                data.clean == 2
            }
            console.table(data);
        });

I need it to change instantly, any idea how i can do this? My data looks like this:

            var data = unique.map(function (item) {
            return {
                'label': item,
                'clean': DefaultItem,
                'copy': DefaultItem
            };
        });
            if (self.isSaved !== 1) {
            self.MenuItems(data);  

        }

Solution

  • I think you can take advantage of subscribing to an observable. something like the following.

    var serverData = [{
      label: 'test1',
      clean: null,
      copy: null
    },{
      label: 'test2',
      clean: null,
      copy: null
    },{
      label: 'test3',
      clean: null,
      copy: null
    }];
    
    
    function MenuItem(data) {
      var self = this;
      self.label = ko.observable(data.label || '');
      self.clean = ko.observable(data.clean || null);
      self.copy = ko.observable(data.copy || null);
    
      var subscription = self.copy.subscribe(function(newValue) {
        self.clean(newValue);
      });
      
      self.disposeSubscription = function dispose(){
        subscription.dispose();
      }
    }
    
    function ViewModel() {
      var self = this;
      self.MenuItems = ko.observableArray();
    
      self.GroupedScorecardTypes = ko.observableArray([{
          Id: 1,
          Name: 'Ignore'
        },
        {
          Id: 2,
          Name: 'Target Data'
        },
        {
          Id: 3,
          Name: 'All Data'
        },
      ]);
      
      var mappedData = serverData.map(x => new MenuItem(x));
      self.MenuItems(mappedData);
      
    }
    
    ko.applyBindings(new ViewModel());
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.3/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    <table class="table table-striped ">
      <thead class="thead-dark">
        <tr>
          <th></th>
          <th>Clean Target</th>
          <th>Populate Target</th>
        </tr>
      </thead>
      <tbody data-bind="foreach: { data: MenuItems, as: 'tableitem' }">
        <tr>
          <td data-bind="html: tableitem.label"></td>
          <td>
            <select class="form-control" data-bind="options: $root.GroupedScorecardTypes,
                            optionsText: 'Name', optionsValue: 'Id', value: tableitem.clean"></select>
          </td>
          <td>
            <select class="form-control" data-bind="options: $root.GroupedScorecardTypes,
                            optionsText: 'Name', optionsValue: 'Id', value: tableitem.copy"></select>
          </td>
        </tr>
      </tbody>
    </table>