-1

I am using the Knockout subscribe function. I have 3 combo boxes. Every combo has no data until I select a record from the previous combo (except for the first combo box).

When I select it works well. In the subscribe callback, it correctly gives me the selected value from the combo box.

But when I click the row and want to fire the same callback, it doesn't work.

https://codepen.io/anon/pen/dmpbpe

    function UNVViewModel() {
      var self = this;
      var UNVViewModel = vm;

      self.Continent = ko.observableArray([]);
      self.Countries = ko.observableArray([]);
      self.States = ko.observableArray([]);
      self.AllData = ko.observableArray([]);

      self.concod = ko.observable();
      self.cntrycod = ko.observable();
      self.statcod = ko.observable();

      self.Load = function() {

 $.getJSON('../ProjectAPI/api/Project/Continent', function (data) { self.Continent(JSON.parse(data)); })

 $.getJSON('../ProjectAPI/api/Project/Countries ', function (data) { self.Countries (JSON.parse(data));})
$.getJSON('../ProjectAPI/api/Project/States ', function (data) { self.States (JSON.parse(data));})
      };
        self.AllData = [
          {
            StateName: "Cairo",
            StateCode: 111,
            CountryCode: 11,
            ContinentCode: 1,
            ContinentName: "Africa",
            CountryName: "Egypt"
          },
          {
            StateName: "Oran",
            StateCode: 112,
            CountryCode: 12,
            ContinentCode: 1,
            ContinentName: "Africa",
            CountryName: "Algeria"
          },
          {
            StateName: "Rome",
            StateCode: 121,
            CountryCode: 21,
            ContinentCode: 2,
            ContinentName: "Europe",
            CountryName: "Italy"
          }
        ];


      self.concod.subscribe(function(con) {
        if (con == undefined) {
          return false;
        } else {
          $.getJSON(
            "../ProjectAPI/API/Project/Countries?ContinentCode=" + con, function(data) { self.Countries(JSON.parse(data));}
          ).complete(function() {
            if (self.Clickedconcod() !== undefined) {
              self.concod(self.Clickedconcod());
            }
          });
        }
      });

      self.cntrycod.subscribe(function(cnty) {
        if (cnty == undefined) {
          return false;
        } else {
          $.getJSON(
            "../ProjectAPI/API/Project/States?CountryCode=" +self.cntrycod() +"&ContinentCode=" +self.concod,function(data) {self.States(JSON.parse(data));}
          ).complete(function() {
            if (self.Clickedcntrycod() !== undefined) {
              self.cntrycod(self.Clickedcntrycod());
            }
          });
        }
      });
    }

    var vm;
    $(document).ready(function() {
      vm = new UNVViewModel();
      vm.Load();
      ko.applyBindings(vm);
    });
 
<div>
    <select class="styled-select" data-bind="options:Continents,optionsText:'ContinentName', optionsValue:'ContinentCode',optionsCaption:'Select  ', value:concod "></select>

    <select class="styled-select" data-bind="options:Countries,optionsText:'CountryName', optionsValue:'CountryCode',optionsCaption:'Select ', value:cntrycod "></select>

    <select class="styled-select" data-bind="options:States,optionsText:'StateName', optionsValue:'StateCode',optionsCaption:'Select ', value:statcod "></select>

</div>



<table id="myTable">
    <thead>

        <tr>
            <th> Continent Name</th>
            <th> Country Name</th>
            <th> State Name</th>
        </tr>
    </thead>

    <tbody data-bind="foreach:AllData">
        <tr data-bind="click:$parent.CountryClick">

            <td data-bind="text:ContinentName"></td>
            <td data-bind="text:CountryName"></td>
            <td data-bind="text:StateName"></td>

        </tr>
    </tbody>

</table>
Tamer
  • 19
  • 6
  • You're using `Clickedcntrycod` but have never defined it. You have bound `CountryClick`, but have never defined it. – Roy J Mar 16 '18 at 21:22
  • 1
    It would be better if you removed a lot of your example code to just the minimum needed to show what your problem is – politus Mar 17 '18 at 12:15

1 Answers1

0

The subscribe callback fires when an observable changes. You are changing those observable values when you select something in the drop downs, but you are not changing the observable values in the row clicks.

If you want to call the same code from a drop down select/Knockout subscribe callback and the row click, extract the common code you want to run into a separate function and call it from both places.

I've changed the code below to add an alert showing the future XHR call when the drop down is selected or the row is clicked, commented out the XHR calls, and extracted the common code in to a function.

For example, self.refreshConcod is the new common code function. It is called by self.concod.subscribe when the drop down changes and by self.CountryClick when the row is clicked.

self.refreshConcod = function(con) {
    if (con == undefined) {
      return false;
    } else {
      alert("../ProjectAPI/API/Project/Countries?ContinentCode=" + con);
      //$.getJSON(
      //  "../ProjectAPI/API/Project/Countries?ContinentCode=" + con,
      //  function(data) {
      //    self.Countries(JSON.parse(data));
      //  }
      //);
    }
};
self.concod.subscribe(function(con) {
    self.refreshConcod(con);
});
self.CountryClick = function() {
    self.refreshConcod(this.ContinentCode);
};

function UNVViewModel() {
  var self = this;
  var GSTViewModel = vm;
  var UNVViewModel = vm;

  self.Continent = ko.observableArray([]);
  self.Countries = ko.observableArray([]);
  self.States = ko.observableArray([]);
  self.AllData = ko.observableArray([]);

  self.concod = ko.observable();
  self.cntrycod = ko.observable();
  self.statcod = ko.observable();

  self.Load = function() {
    self.Continents = [
      { ContinentName: "Africa", ContinentCode: 1 },
      { ContinentName: "Europe", ContinentCode: 2 },
      { ContinentName: "Asia", ContinentCode: 3 }
    ];

    self.Countries = [
      { CountryName: "Egypt", CountryCode: 11, ContinentCode: 1 },
      { CountryName: "Algeria", CountryCode: 12, ContinentCode: 1 },
      { CountryName: "Ghana", CountryCode: 13, ContinentCode: 1 },

      { CountryName: "Italy", CountryCode: 21, ContinentCode: 2 },
      { CountryName: "Denmark", CountryCode: 22, ContinentCode: 2 },
      { CountryName: "France", CountryCode: 23, ContinentCode: 2 },
      { CountryName: "Germany", CountryCode: 24, ContinentCode: 2 },

      { CountryName: "Russia", CountryCode: 31, ContinentCode: 3 },
      { CountryName: "Malaysia", CountryCode: 32, ContinentCode: 3 },
      { CountryName: "China", CountryCode: 33, ContinentCode: 3 },
      { CountryName: "Turkey", CountryCode: 34, ContinentCode: 3 }
    ];

    self.States = [
      { StateName: "Cairo", StateCode: 111, CountryCode: 11, ContinentCode: 1 },
      { StateName: "Alex", StateCode: 211, CountryCode: 11, ContinentCode: 1 },
      { StateName: "Oran", StateCode: 112, CountryCode: 12, ContinentCode: 1 },
      { StateName: "Blida", StateCode: 212, CountryCode: 12, ContinentCode: 1 },
      { StateName: "Accra", StateCode: 113, CountryCode: 13, ContinentCode: 1 },
      {
        StateName: "Kumasi",
        StateCode: 213,
        CountryCode: 13,
        ContinentCode: 1
      },
      { StateName: " Rome", StateCode: 121, CountryCode: 21, ContinentCode: 2 },
      { StateName: "Milan", StateCode: 221, CountryCode: 21, ContinentCode: 2 },
      {
        StateName: " Horsens",
        StateCode: 122,
        CountryCode: 22,
        ContinentCode: 2
      },
      {
        StateName: "Roskilde",
        StateCode: 222,
        CountryCode: 22,
        ContinentCode: 2
      },
      { StateName: " Paris", StateCode: 123, CountryCode: 23, ContinentCode: 2 },
      { StateName: "Lyon ", StateCode: 223, CountryCode: 23, ContinentCode: 2 },
      {
        StateName: "Berlin",
        StateCode: 124,
        CountryCode: 24,
        ContinentCode: 2
      },
      {
        StateName: "Moscow",
        StateCode: 131,
        CountryCode: 31,
        ContinentCode: 3
      },
      {
        StateName: "Saint Petersburg",
        StateCode: 231,
        CountryCode: 31,
        ContinentCode: 3
      },
      {
        StateName: "Novosibirsk",
        StateCode: 331,
        CountryCode: 31,
        ContinentCode: 3
      },
      {
        StateName: "Hong Kong",
        StateCode: 133,
        CountryCode: 33,
        ContinentCode: 3
      },
      {
        StateName: "Beijing",
        StateCode: 233,
        CountryCode: 33,
        ContinentCode: 3
      },
      {
        StateName: "Tianjin",
        StateCode: 333,
        CountryCode: 33,
        ContinentCode: 3
      },
      {
        StateName: "Anqing",
        StateCode: 433,
        CountryCode: 33,
        ContinentCode: 3
      },
      {
        StateName: " Istanbul",
        StateCode: 134,
        CountryCode: 34,
        ContinentCode: 3
      },
      {
        StateName: "Ankara",
        StateCode: 234,
        CountryCode: 34,
        ContinentCode: 3
      },
      { StateName: "İzmir", StateCode: 334, CountryCode: 34, ContinentCode: 3 },
      { StateName: "Bursa", StateCode: 434, CountryCode: 34, ContinentCode: 3 }
    ];
  };
  self.AllData = [
    {
      StateName: "Cairo",
      StateCode: 111,
      CountryCode: 11,
      ContinentCode: 1,
      ContinentName: "Africa",
      CountryName: "Egypt"
    },
    {
      StateName: "Oran",
      StateCode: 112,
      CountryCode: 12,
      ContinentCode: 1,
      ContinentName: "Africa",
      CountryName: "Algeria"
    },
    {
      StateName: "Rome",
      StateCode: 121,
      CountryCode: 21,
      ContinentCode: 2,
      ContinentName: "Europe",
      CountryName: "Italy"
    }
  ];

  self.refreshConcod = function(con) {
    if (con == undefined) {
      return false;
    } else {
      alert("../ProjectAPI/API/Project/Countries?ContinentCode=" + con);
      //$.getJSON(
      //  "../ProjectAPI/API/Project/Countries?ContinentCode=" + con,
      //  function(data) {
      //    self.Countries(JSON.parse(data));
      //  }
      //);
    }
  };
  self.concod.subscribe(function(con) {
    self.refreshConcod(con);
  });
  self.CountryClick = function() {
    self.refreshConcod(this.ContinentCode);
  };

  self.cntrycod.subscribe(function(cnty) {
    if (cnty == undefined) {
      return false;
    } else {
      alert("../ProjectAPI/API/Project/States?CountryCode=" + cnty + "&ContinentCode=" + self.concod());
      //$.getJSON(
      //  "../ProjectAPI/API/Project/States?CountryCode=" +
      //    cnty +
      //    "&ContinentCode=" +
      //    self.concod(),
      //  function(data) {
      //    self.States(JSON.parse(data));
      //  }
      //);
    }
  });
}

var vm;
$(document).ready(function() {
  vm = new UNVViewModel();
  vm.Load();
  ko.applyBindings(vm);
});
#myTable {
    font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
    border-collapse: collapse;
    width: 100%;
}

#myTable td, #myTable th {
    border: 1px solid #ddd;
    padding: 8px;
}

#myTable tr:nth-child(even){background-color: #f2f2f2;}

#myTable tr:hover {background-color: #ddd;}

#myTable th {
    padding-top: 12px;
    padding-bottom: 12px;
    text-align: left;
    background-color: #4CAF50;
    color: white;
}

.styled-select select {
       background: transparent;
       width: 268px;
       padding: 5px;
       font-size: 16px;

       border: 0;
       border-radius: 0;
       height: 34px;
       -webkit-appearance: none;
       -moz-appearance:none;
       appearance: none;
       }

.styled-select {
       width: 271px;
       height: 25px;
       overflow: hidden;
       background: url(img/cmbbox.png) no-repeat;
       border: 0;
       }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<div class="modal-body">
  <div class="row">
    <div class="col-xs-6">
      <div class="form-group has-error">
        <label class="title_lable">Continent Name:</label>
        <select class="styled-select" data-bind="options:Continents,optionsText:'ContinentName', optionsValue:'ContinentCode',optionsCaption:'Select  ', value:concod "></select>
      </div>
    </div>
    <div class="col-xs-6">
      <div class="form-group has-error">
        <label class="title_lable"> Country Name:</label>
        <select class="styled-select" data-bind="options:Countries,optionsText:'CountryName', optionsValue:'CountryCode',optionsCaption:'Select ', value:cntrycod "></select>
      </div>
    </div>
  </div>
  <div class="row">
    <div class="col-xs-12">
      <div class="form-group has-error">
        <label class="title_lable ">State Name:</label>
        <select class="styled-select" data-bind="options:States,optionsText:'StateName', optionsValue:'StateCode',optionsCaption:'Select ', value:statcod "></select>
      </div>
    </div>
  </div>
</div>

<table id="myTable" class="table table-bordered table-striped " style="font-size:12px;cursor:cell">
  <thead>
    <tr>
      <th> Continent Name</th>
      <th> Country Name</th>
      <th> State Name</th>
    </tr>
  </thead>
  <tbody data-bind="foreach:AllData">
    <tr data-bind="click:$parent.CountryClick">
      <td data-bind="text:ContinentName"></td>
      <td data-bind="text:CountryName"></td>
      <td data-bind="text:StateName"></td>
    </tr>
  </tbody>
</table>
Joe Wilson
  • 5,591
  • 2
  • 27
  • 38