Find the appropriate DOM element

2019-07-24 02:30发布

问题:

Here follows my model:

<!-- ko foreach: teamMembers -->
    <tr>
      <!-- ko foreach: days -->   
      <td>
        <!-- ko foreach: shifts -->
          <input type="text" data-bind="value: startTime">
          <input type="text" data-bind="value: endTime">          
       <!-- /ko -->
      </td>
      <!-- /ko -->       
    </tr>
<!-- /ko -->

and my viewmodel:

function TimeCardViewModel() {
    var self = this;
    self.teamMembers=ko.observableArray();
  }

function TeamMemberViewModel(data){
    var self=this;
    self.days=ko.observableArray();
    for (var i=0; i<7; i++)  {
      self.days.push(new DayViewModel(...);
    }
  }

function DayViewModel(shifts){
    var self=this;
    self.shifts=ko.observableArray();
    for (var i=0; i<shifts.length; i++)  {
       self.shifts.push(new ShiftElementsViewModel(...);
    } 
  }

function ShiftElementsViewModel(a,b,c,d) {
    var self=this;
    self.startTime=ko.observable(a);
    self.endTime=ko.observable(b);
  }

var timeCardViewModel=new TimeCardViewModel();
ko.applyBindings(timeCardViewModel);

For each member, we have (for each day of the seven days of the week) a number of shifts. For each shift, we have pairs of startTime-endTime inputs. As far as the visual result is concerned, there are rows which include all the weekly shifts of a member and it might be the case of multiple shifts per day per member. If we look at the columns, these include all the shifts for all the members for a certain day.
My great problem is that I want, whenever there is a blur event on the DOM element of endTime, to focus on the DOM element of startTime vertically. For example, if we are on Monday and the first member has two shifts I want to focus on the startTime of the second shift of the first member when blur is occurring to the endTime of the first shift and then on the startTime of the first shift on Monday of the second member when blur is occurring to the endTime of the second shift of the first member. The same for Tuesday etc. How may I achieve that? For the time being, the cursor is travelling horizontally.

回答1:

This should work for you...

jQuery(function($) {
  $('body').on("blur", "input[data-bind*='value: endTime']", function() {
    var
      $t = $(this), // Current input
      $td = $t.closest('td'), // Current input's parent td
      i = $td.find('input[data-bind*="value: endTime"]').index($t), // Index of current input = current shift index
      $target = $td.find('input[data-bind*="value: startTime"]').eq(i + 1); // Target is current shift + 1

    if ($target.length) {
      $target.focus();
    }
  });
});

The idea is to bind an event handler to blur event of every input that contains value: endTime in data-bind attribute.
If this handler, we find out the index of endTime input in day, add 1 to it and focus the startTime input with that index in the same td (day)