Search code examples
javascriptjqueryknockout.jsknockout-2.0knockout-mvc

Knockoutjs foreach n rows check if dropdown has value


I have this html markup:

<!-- ko foreach: Orders -->
  <div class="row">
    <div>
      <select class="form-control"  data-bind="attr: { id: 'prefix_' + $index() }, options: TeacherNames, optionsValue: 'TeacherId', optionsText: 'TeacherName', optionsCaption: 'Choose Teacher', event: { change: $root.teacherChanged }">
      </select>
    </div>
    <div>
      <a href='#' data-bind="click: $root.RequestImage" class="green-btn blue pull-right">
        <span class="glyphicon glyphicon-cloud-download"></span> Download 
      </a>
    </div>
  </div>
<!-- /ko -->

There will be n number of items in the foreach loop, that will not be known in the moment of development.

What I want to do is when the $root.RequestImage is clicked, the code needs to check if there is selection made in the respected dropdown for that row, if the selection is made then proceed further, otherwise display alert box with 'error' message.

So in the RequestImage that action should happen, this is the RequestImage function currently:

self.RequestImage = function () {

};

How can I achieve this?

Update

OrdersVM:

var self = this;
self.Orders = ko.observableArray([]);

$.ajax({
  type: "POST", url: "/webservices/InfoWS.asmx/GetOrders",
  contentType: "application/json; charset=utf-8",
  dataType: "json",
  success: function (data) {
    if (data.d != null) {
      var orderIds = [];
      ko.utils.arrayForEach(data.d, function (item) {

        item._teacherOrders = ko.observable();

        $.ajax({
          type: "POST",
          url: "/webservices/InfoWS.asmx/GetTeachersForMyAccount",
          contentType: "application/json; charset=utf-8",
          data: "{'orderId': " + JSON.stringify(item.OrderId) + "}",
          dataType: "json",
          success: function (data) {
            if (data) {
              return item._teacherOrders(data.d);
            }
          },
          error: function (n) {
            alert('Error retrieving teachers for orders, please try again.');
          }
        });

        item.TeacherNames = ko.computed(function () {
          return item._teacherOrders();
        });

        self.Orders.push(item);
        orderIds.push(item.OrderId);

      });
    }
  },
  error: function (data) {
    var response = JSON.parse(data.responseText);
    console.log("error retrieving orders:" + response.Message);
  }
});

Solution

  • I would do it this way:

    1. add an observable selectedTeacher to every order object
    2. add value: selectedTeacher to your selects:

      <select class="form-control" data-bind="attr: { id: 'prefix_' + $index() }, options: TeacherNames, optionsValue: 'TeacherId', ..., value: selectedTeacher"></select>

    3. check that observable in your RequestImage event

      if ( !data.selectedTeacher() ) {
              alert('Error: select teacher')
      } else {
              alert('Success')
      }
      

    A working demo - Fiddle