0

This is a follow-up to question 16885880. I did not see a good mechanism for asking this question within the context of that question. I don't have a 50 Reputation so I can't comment (and this would probably be inappropriate as a comment, anyway), and this is not an answer to that question.

My question:

I'm trying to use the answer to jQuery: How to know when a table row loses focus?, but it does not seem to work the way I've coded it. Can anyone help me understand what I'm doing wrong?

Using Firefox Debugger, I've verified that the handler code is hit when the JS file is loaded, but breakpoints at the delayedFn = setTimeout(function() { and if (blurredInput === event.delegateTarget) { lines are never hit when the inputs in my row are entered, updated or exited; and my console.log lines are never hit.

HTML Snippet:

<!-- Table after DataTables gets through with it -->
<table role="grid" id="assetDetails" class="dataTable no-footer">
  <thead>
    <tr role="row">
      <th colspan="1" rowspan="1"
          class="icon sorting_disabled"></th>
      <th colspan="1" rowspan="1"
          class="seqNum sorting_disabled"></th>
      <th colspan="1" rowspan="1"
          class="vendorName sorting_disabled">Vendor Name</th>
      <th colspan="1" rowspan="1"
          class="vendorItemId sorting_disabled">Item ID</th>
      <th colspan="1" rowspan="1"
          class="itemDesc sorting_disabled">Materials Provided</th>
      <th colspan="1" rowspan="1"
          class="itemCost sorting_disabled dollarAmount">$ Amount</th></tr>
  </thead>
  <tbody>
    <tr role="row" class="editable odd" id="detail_1">
      <td class="icon">
        <a href="#"
           onclick="updateDetailsTable('detail_1', UPDATE_TYPE_DELETE)">
          <img class="icon"
               src="/public/images/delete.png" title="Delete Row">
        </a>
      </td>
      <td class="seqNum">1</td>
      <td>
        <input class="vendorName" value="" type="text">
      </td>
      <td>
        <input class="vendorItemId" value="" type="text">
      </td>
      <td>
        <input class="itemDesc" value="" type="text">
      </td>
      <td class="dollarAmount">
        <input pattern="\d{1,9}(\.\d{2})?"
               class="itemCost" value="0" type="text">
      </td>
    </tr>
  </tbody>
</table>

My jQuery Event Handler:

var delayedFn, blurredInput;
$("tr.editable").on("blur", ":input", function(event) {
  blurredInput = event.delegateTarget;
  delayedFn = setTimeout(function() {
    var tableId = $(blurredInput).closest("table").attr("id");
    var rowId = $(blurredInput).closest("tr").attr("id");
    /*
     * Get the name of the function we want to call. The functions are:
     *   + updateDetailsTable
     *   + updateDisposalsTable
     */
    // Skip the leading "asset" portion of the table ID.
    var tableName = tableId.substr(5);
    var functionName = "update" + tableName + "Table";
    console.log("tr.editable.onblur: tableId      = " + tableId);
    console.log("tr.editable.onblur: rowId        = " + rowId);
    console.log("tr.editable.onblur: tableName    = " + tableName);
    console.log("tr.editable.onblur: functionName = " + functionName);
    window[functionName](rowId, UPDATE_TYPE_CHANGE);
    /*
     * Timeout value is set to 500 for FireFox.
     * See: https://stackoverflow.com/questions/20747591/
     */
  }, 500);
});
$('tr.editable').on('focus', ':input', function(event) {
  if (blurredInput === event.delegateTarget) {
      clearTimeout(delayedFn);
  }
});
Community
  • 1
  • 1
Mike M
  • 43
  • 1
  • 6

1 Answers1

0

I've figured it out. A detail I left out of my problem statement is that I use jQuery DataTables to add a new row when then the user clicks an "add row" link, or when the table supplied from the server is empty.

In the above HTML, the initial row was added by DataTables, AFTER the JS file containing the handler was loaded, because the server table was empty. To get the handler to work I had to modify it like this:

var delayedFn, blurredRow;  //<-- Changed
$('table').on('blur', 'tr.editable :input', function(event) {  //<-- Changed
  blurredRow= $(event.target).closest("tr").attr("id");  //<-- Changed
  delayedFn = setTimeout(function() {
    var tableId = $(event.target).closest("table").attr("id");  //<-- Changed
    /*
     * Get the name of the function we want to call. The functions are:
     *   + updateDetailsTable
     *   + updateDisposalsTable
     */
    // Skip the leading "asset" portion of the table ID.
    var tableName = tableId.substr(5);
    var functionName = "update" + tableName + "Table";
    console.log("tr.editable.onblur: tableId      = " + tableId);
    console.log("tr.editable.onblur: blurredRow   = " + blurredRow);  //<-- Changed
    console.log("tr.editable.onblur: tableName    = " + tableName);
    console.log("tr.editable.onblur: functionName = " + functionName);
    window[functionName](blurredRow, UPDATE_TYPE_CHANGE);  //<-- Changed
    /*
     * Timeout value is set to 500 for FireFox.
     * See: http://stackoverflow.com/questions/20747591/
     */
  }, 500);
});
$('table').on('focus', 'tr.editable :input', function(event) {  //<-- Changed
  focusedRow = $(event.target).closest('tr').attr('id');  //<-- Changed
  if (focusedRow === blurredRow) {  //<-- Changed
      clearTimeout(delayedFn);
  }
});
Mike M
  • 43
  • 1
  • 6