jQuery $(this)无法识别tr中的复选框元素

时间:2018-11-12 19:52:26

标签: javascript jquery html google-apps-script this

我正在尝试使用JQuery在未选中该行中的复选框时突出显示表中动态创建的行,以及更新显示显示已检查多少行的计数器元素。我正在使用Google Apps脚本,特别是该项目是HTML模板输出(html,js和css文件)。除了取消选中该框并更新选中行计数器(> _ <)以外的所有行,其他所有方法都有效。我到处都在寻找解决方案,但到目前为止还是空着。我唯一能想到的是,我的jquery脚本文件中的$(this)变量没有设置为复选框,但是我不能使用Chrome开发工具来监视“ this”(除非有人知道一种方法)在GAS内执行此操作...?)。

这是我的代码。gs...

function openLateAccountsNoticesWindow() {
  var htmlTemp = HtmlService.createTemplateFromFile('send_notices/HTML').evaluate();
  var html = HtmlService.createHtmlOutput(htmlTemp);
  SpreadsheetApp.getUi().showModalDialog(html, 'Send Notices');
};

// INCLUDE creates an import so files can be added inside the main index.
function include(filename){
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
};

// The getAccountsWithOpenBal function creates an array of accounts with
// an outstanding balance > $0.

function getAccountsWithOpenBal() {
  // Code to get the array of accounts from my spreadsheet goes here, 
  // but I'll provide a stand-in array below for debugging purposes.
  var accounts = [
    {Unit: "123 Abc Street", Name: "John Doe", Balance: 500.10},
    {Unit: "456 Maple Street", Name: "Mary Jane", Balance: 250.05},
    {Unit: "765 Stone Road", Name: "Mark Isaguy", Balance: 1300.45},
    {Unit: "999 Nine Avenue", Name: "Lauren Lady", Balance: 45.23}]; 

  var lateAccountsArray = [];
  for (var i=0; i < accounts.length; i++) {    
    if (parseFloat(accounts[i]['Balance']) > 0) {
      var balToNum = parseFloat(accounts[i]['Balance']);
      var bal2Decimals = balToNum.toFixed(2);      
      var balWithCommas = bal2Decimals.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
      accounts[i]['Balance'] = balWithCommas;
      lateAccountsArray.push(accounts[i]);
    }
  }
  return lateAccountsArray;
};

我的html ...

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">       
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
    </script>
    <?!= include('send_notices/CSS') ?>           
  </head>
  <body>       
    <h4 id="header">Accounts with Current Balance Owed:</h4>
    <div id="table_goes_here">
    </div>
    <br>
    <h4>Number of Notices to Submit: <span id="noticeCount"></span></h4>
    <br>
    <button class="action" id="submitButton" onclick="form_data()">Submit</button> <button class="cancel" onclick="google.script.host.close()">Cancel</button>
    <br>
  </body>
  <?!= include('send_notices/JS') ?>
</html>

这是我的js文件中的脚本,用于生成表格...

<script>
window.onload = function() {
  google.script.run.withSuccessHandler(addAccountsData).getAccountsWithOpenBal();
}

function addAccountsData(lateAccountsArray) {

  var div = document.getElementById("table_goes_here");
  var table = document.createElement("TABLE");
  table.setAttribute("id", "debtorList");
  var tableBody = document.createElement('TBODY');
  table.appendChild(tableBody);

  // TABLE HEADERS 
  // Create header row, and append to table body
  var headerRow = document.createElement('TR');
  tableBody.appendChild(headerRow);

  // Next, create each header cell
  // Unit Column Header ("unit" = "address")
  var unitTH = document.createElement('TH');
  unitTH.setAttribute("style", "width: 25%");
  unitTH.appendChild(document.createTextNode("Address"));

  // Name Column Header (name of account holder)
  var nameTH = document.createElement('TH');
  nameTH.setAttribute("style", "width: 22%");
  nameTH.appendChild(document.createTextNode("Name"));

  // Currency Column Header
  var currencyTH = document.createElement('TH');
  currencyTH.setAttribute("style", "width: 5%");
  currencyTH.appendChild(document.createTextNode(""));

  // Balance Column Header
  var balanceTH = document.createElement('TH');
  balanceTH.setAttribute("style", "width: 5%; text-align: right");
  balanceTH.appendChild(document.createTextNode("Balance"));

  // Checkbox Column Header
  var includeTH = document.createElement('TH');
  includeTH.setAttribute("style", "width: 10%; text-align: center");
  includeTH.appendChild(document.createTextNode("Include"));

  // Append all headers to header row
  headerRow.appendChild(unitTH);
  headerRow.appendChild(nameTH);
  headerRow.appendChild(currencyTH);
  headerRow.appendChild(balanceTH);
  headerRow.appendChild(includeTH);

  // I use getRowCount when filling in the table
  // rows in order to attach a unique id attr to
  // each row and checkbox.
  var rowCount = 0;
  function getRowCount() {
    rowCount += 1;
    return rowCount;
  }

  // Loop through each account, creating a row for each one.

  for (var i=0; i < lateAccountsArray.length; i++) {
    var tr = document.createElement("TR");
    rowCount = getRowCount();
    tr.classList.add("account_data");
    tr.setAttribute("id", "row" + rowCount);

    // td cell for unit/address
    var unitTD = document.createElement("TD");
    unitTD.classList.add("account_unit");
    unitTD.setAttribute("value", lateAccountsArray[i]["Unit"]);
    unitTD.appendChild(document.createTextNode(lateAccountsArray[i]["Address"]));

    // td cell for account-holder name
    var nameTD = document.createElement("TD");
    nameTD.classList.add("name");
    nameTD.setAttribute("value", lateAccountsArray[i]["Name"]);
    nameTD.appendChild(document.createTextNode(lateAccountsArray[i]["Name"]));

    // td cell for $ (to keep them aligned, regardless of the
    // number of digits in their balance.
    var currencyTD = document.createElement("TD");
    currencyTD.classList.add("currency");
    currencyTD.appendChild(document.createTextNode("$"));

    // td cell for balance amount
    var balanceTD = document.createElement("TD");
    balanceTD.classList.add("balance");
    balanceTD.setAttribute("value", lateAccountsArray[i]["Balance"]);
    balanceTD.appendChild(document.createTextNode(lateAccountsArray[i]["Balance"]));

    // td cell for checkbox
    var checkboxTD = document.createElement("TD");
    checkboxTD.classList.add("checkboxTD");
    var checkbox = document.createElement("INPUT");
    checkbox.classList.add("checkbox");
    checkbox.setAttribute("id", "checkbox" + rowCount);
    checkbox.setAttribute("type", "checkbox");
    checkbox.setAttribute("checked", true);
    checkboxTD.appendChild(checkbox);

    // Attach all td cells to tr
    tr.appendChild(unitTD);
    tr.appendChild(nameTD);
    tr.appendChild(currencyTD);
    tr.appendChild(balanceTD);
    tr.appendChild(checkboxTD);

    // Attach tr to tableBody
    tableBody.appendChild(tr);

    // Set the initial count for the number of notices.
    if (i == lateAccountsArray.length - 1) {
      var noticeCount = document.getElementById("noticeCount");
      noticeCount.innerHTML = i;
    }
  }
  div.appendChild(table)
};
</script>

这是我js文件中的脚本,用于突出显示最接近的tr并在选中:checkbox时更新#noticeCount ...

<script>
$(document).ready(function() {
  $(":checkbox").change(function() {
    var noticeCountEle = document.getElementById("noticeCount");
    var noticeCount = parseFloat(noticeCountEle.text());
    if ($(this).is(":checked")) {
      noticeCount += 1;
      $(this).closest("tr").css("background-color", "rgba(255, 255, 255, 1)");
    } else {
      noticeCount -= 1;
      $(this).closest("tr").css("background-color", "rgba(64, 64, 64, 0.7)");
    }
    noticeCountEle.innerHTML = noticeCount;
  })
});
</script>

我尝试了.closest(“ tr”)、. closest(“。account_data”),并且尝试获取该行的ID并传递该ID,但它们似乎都不起作用。我的直觉是(this)关键字不正确,但是我不确定如何解决/解决它。


已解决

问题出在我的jQuery上,但这不是“ this”关键字的问题-这是我如何设置选择器的问题。

jQuery的本机浏览器事件处理程序(.change()、. click()、. focus()和.blur())将仅附加到jQuery函数运行时存在的元素上,而不附加到在初始渲染之后添加(至少不与我设置选择器的方式有关)。由于表格,行,单元格和复选框都是通过我的JS文件动态创建的,因此我需要将.on()方法附加到动态添加了我的表格的静态div(#table_goes_here)上,然后通过“ “事件处理程序和”:checkbox“选择器作为方法参数。所以我通过将jQuery脚本文件更改为下面的代码来解决了这个问题。如果您想进一步了解jQuery事件处理,this jQuery documentation page正是您所需要的。

<script>
$(document).ready(function() {
  $("#table_goes_here").on("change", ":checkbox", function() {
    var noticeCountHTML = document.getElementById("noticeCount");
    var noticeCount = $("#table_goes_here").find("tr").length;
    noticeCountHTML.innerHTML = noticeCount;
    if ($(this).is(":checked")) {
      noticeCount -= 1;
      $(this).closest(".account_data").css("background-color", "rgba(64, 64, 64, 0.7)");
    } else {
      noticeCount += 1;
      $(this).closest(".account_data").css("background-color", "rgba(255, 255, 255, 1)");
    }
    noticeCountHTML.innerHTML = noticeCount;
  })
});
</script>

1 个答案:

答案 0 :(得分:0)

已解决

问题出在我的jQuery上,但这不是“ this”关键字的问题-这是我如何设置选择器的问题。

jQuery的本机浏览器事件处理程序(.change()、. click()、. focus()和.blur())将仅附加到jQuery函数运行时存在的元素上,而不附加到在初始渲染之后添加(至少不与我设置选择器的方式有关)。由于表格,行,单元格和复选框都是通过我的JS文件动态创建的,因此我需要将.on()方法附加到动态添加了我的表格的静态div(#table_goes_here)上,然后通过“ “事件处理程序和”:checkbox“选择器作为方法参数。所以我通过将jQuery脚本文件更改为下面的代码来解决了这个问题。如果您想了解有关jQuery事件处理的更多信息,那么此jQuery文档页面正是您所需要的。

<script>
$(document).ready(function() {
  $("#table_goes_here").on("change", ":checkbox", function() {
    var noticeCountHTML = document.getElementById("noticeCount");
    var noticeCount = $("#table_goes_here").find("tr").length;
    noticeCountHTML.innerHTML = noticeCount;
    if ($(this).is(":checked")) {
      noticeCount -= 1;
      $(this).closest(".account_data").css("background-color", "rgba(64, 64, 64, 0.7)");
    } else {
      noticeCount += 1;
      $(this).closest(".account_data").css("background-color", "rgba(255, 255, 255, 1)");
    }
    noticeCountHTML.innerHTML = noticeCount;
  })
});
</script>