更改影响其他单元格的一个表格单元格

时间:2017-11-05 05:16:46

标签: jquery html-table this

如何将一种饮料换成另一种饮料,以便成本反映下一个细胞的变化?

例如:我选择了饮料,点击“下订单”按钮,点击“编辑”按钮。在“饮料类型”细胞中,我从茶变为可乐:饮料成本单元格应该从2.25美元变为2.50美元,但它保持不变。

据我所知,我的代码中的所有内容都是正确的,我无法弄清楚它为什么不起作用。

https://jsfiddle.net/9d7ee9fr/7/

我将不胜感激任何建议:

HTML:

<form>
    <fieldset>
        <legend>
        Customer's Information
        </legend>
<br><br> 

Drink Order:    
<!--asks for coffee type-->
<select name="drinkType" id="drinkType">
    <option value="#">Select Drink</option>
    <option value="0">Tea  $2.25</option>
    <option value="1">Coke  $2.50</option>
    <option value="2">Coffee  $2.75</option>
</select>
<br><br>
<label>&nbsp;</label>
<input type="button" id="placeOrderBtn" value="Place Order">    
<br><br>

</fieldset>
</form>
<br>   
<table id = "receiptOrders">  
    <thead>
        <tr>
            <th>Item Number</th>
            <th>Drink Type</th>
            <th>Drink Cost</th>
            <th>Edit/Save</th>
        </tr>
    </thead>
    <tbody></tbody>
</table>
</main>
</div><!-- end .container -->
</body>
</html>

JS:

"use strict";

// Global Variables
var amt = 0; 
var itemNumber; // for receipt purposes

// arrays
var drinkCosts = [2.25, 2.50, 2.75]; // costs of each drink type
var drinkTypeHolder =[]; // holds each customer's name
var drinkCostHolder = []; // holds each customer's subtotal
var drink;

// ready event: short way
$(function() {    
    // calculates total cost
    $("#placeOrderBtn").click(function() {
        if ($("#drinkType").val() == "#") {
            alert ("Please select a drink type");
        } else {
        drink = parseInt($("#drinkType").val()); // gets id: drinkType value from HTML page

        //calls the function 
        var drinkCost = drinkAmt(drink);
        drinkCost = parseFloat(drinkCost);
        $("#drinkCost").val(drinkCost.toFixed(2)); 

        var drinkName = drinkType(drink);
        var totalList = 0; 

        drinkTypeHolder.push(drinkName); // adds drink type name

        drinkCostHolder.push(drinkCost); // adds subtotal cost

        // i retrieves each element from the array
       for (var i = 0; i < drinkTypeHolder.length; i++) { 
           totalList = "<tr><td></td><td class='editableText'>" + drinkTypeHolder[i] + "</td><td>" + drinkCostHolder[i] + "</td><td><input type='button' value='Edit' class='editBtn'><input type='button' value='Save' class='saveBtn'></td></tr>";    
        }

    $("#receiptOrders > tbody").append(totalList); // table: tbody: children
    }

// edits information
$(".editBtn").click(function() { 
    $(this).hide(); // hides edit button
    $(this).next(".saveBtn").show(); // displays save button

    // finding cells in the row of the selected edit button, but ignoring item number, and last item
    $(this).closest("tr").find("td:not(:last-child)").each(function() {
        $("td:first-child").prop("contenteditable", false); // makes item number not editable
        $(".editBt, .saveBtn").prop("contenteditable", false); // makes item number not editable
        $("tr").not(this).prop("contenteditable", false); 
        $(this).prop("contenteditable", true);

        $("td:first-child, .editBt, .saveBtn").css({"backgroundColor": "#fff"});
        $(this).css({"backgroundColor": "#c4c7c6"}); 
});
});

// There is no change event on contenteditable element.
// Input event fires on a contenteditable editor when its contents are changed 
    $("td:nth-child(2)").on("input",function(){
        if ($(this).text() == "Tea" || $(this).text() == "tea") {
            $(this).next("td").html("2.25");
            $(this).css({"backgroundColor": "red"}); // for test purposes
        } else if ($(this).text() == "Coke" || $(this).text() == "coke") {
            $(this).next("td").html("2.50"); 
            $(this).css({"backgroundColor": "blue"}); // for test purposes
        } else if ($(this).text() == "Coffee" || $(this).text() == "coffee") {
            $(this).next("td").html("2.75"); 
            $(this).css({"backgroundColor": "pink"}); // for test purposes
    }
 });

// saves information
$(".saveBtn").click(function() {
    $(this).hide(); // hides save button
    $(this).prev(".editBtn").show(); // displays edit button
    $(this).prop("contenteditable", false);
    $("td").not(this).prop("contenteditable", false); 

    $(this).closest("tr").find("td:not(:last-child)").each(function() {
        $(this).css({"backgroundColor": "#fff"});
    });

    });
    }); // end places order click

}); // end of ready event handler

// matches each drink type to each price
// gets amount
var drinkAmt = function(inDrink) {
    var amt = 0;
    switch(inDrink) {
    case 0:
      amt = drinkCosts[0]; // Tea
      break;
    case 1:
      amt = drinkCosts[1]; // Coke  
      break;
    case 2:
      amt = drinkCosts[2]; // Coffee
      break;
}
    return amt;
};

var drinkType = function(inDrink) {
    switch(inDrink) {
    case 0:
            return "Tea"; // Tea
            break;
    case 1:
           return "Coke"; // Coke  
           break;
    case 2:
           return "Coffee"; // Coffee
           break;
}
};

2 个答案:

答案 0 :(得分:1)

好的...首先,你做错了......

change元素上没有contenteditable个事件。您可以将其更改为keydown或使用.on('input',function()) ...就像这样:

$("td:nth-child(2)").keydown(function(){ ...

$("td:nth-child(2)").on('input',function(){ ...

请注意,如果您使用鼠标右键单击菜单将文本粘贴到其中,则第一个解决方案将无效。

第二件事是,如果您在每次点击Edit按钮时添加新事件,它会堆叠......所以点击EditSaveEdit后, SaveEditSave ...将绑定3个事件(相同事件)。并将被触发3次。这是内存泄漏。单击Save按钮...

时,您需要删除该事件

在第一种情况下,它将是:

$("td:nth-child(2)").unbind('keypress');

在第二种情况下,它将是:

$("td:nth-child(2)").off('input');

另一件事是,您需要了解jQuery选择器的工作方式以及.eq()的工作原理。从你的例子来看,你似乎并不理解......

请阅读this document

基本上它从元素集中选择一个元素。但在你的情况下,$("td:nth-child(2)")不是一个集合,而是单个元素。所以在它上面调用.eq(2)完全没有意义,因为该集合中没有第二个元素。

在您的代码中:

     $("td:nth-child(2)").change(function(){ 
        if ($(this).eq(2) == "Tea" || "tea") {
            $(this).eq(3).html(2.25);
        } 
     ...

$("td:nth-child(2)")是包含产品名称的元素,因此引用它应该只是$(this),而不是$(this).eq(2)。另外一点是你无法将元素与字符串进行比较,就像你在$(this).eq(2) == "Tea"中所做的那样......你需要使用$(this).text()来获取该元素的文本。所以它应该是:

if ($(this).text() == "Tea" || "tea") { ...

确定。但是如何选择价格领域呢?我已经提到$(this).eq(3).html(2.25);完全没有意义 - 因为$(this)是一个元素,而不是元素集。要选择下一个td元素,您应该使用.next('td')

     $("td:nth-child(2)").change(function(){ 
        if ($(this).text() == "Tea" || "tea") {
            $(this).next('td').html("2.25"); // <-- this supposed to be a string, not float, so we are using double or single quotas.
        } 
     ...

嗯......就是这样。该死的,我应该当老师。玩得开心!

答案 1 :(得分:0)

尝试运行代码段。 使用的逻辑:

  1. 我为drinkOptions 使用了对象数组(键值) 初始化select标签并将其放在一个函数中。
  2. 每次点击下订单时,我附加一个包含数据键属性的表格行     (data-key = Tea,data-key = Coffee)到tbody元素。想想      data-key作为饮品的唯一ID

  3. 每次点击保存,我 遍历tbody中的所有.receiptItem 元素并检查是否 它匹配数据密钥。 如果匹配数据键,则替换其值 用我编辑的饮料或价格。

  4. &#13;
    &#13;
    // if errors JavaScript will stop running
    "use strict";
    
    // Global Variables
    var amt = 0;
    var itemNumber; // for receipt purposes
    
    // declare drinkOptions as key value array
    var drinkOptions = {
      "Tea": "2.25",
      "Coke": "2.5",
      "Coffee": "2.75"
    };
    
    var drink; //holds the drink
    var price; //holds the price
    
    function findNReplaceItem(key, nDrink, nPrice) {
      var found = false;
      alert("key:" + key);
      for (var i in drinkOptions) {
        if (i == nDrink) {
          //replace the value of drink in key value array with new price
          drinkOptions[i] = nPrice;
          found = true;
          break;
        }
      }
    
      // replace all drink cost
      $(".receiptItem").each(function() {
        if ($(this).attr("data-key") == key) {
          $(this).find("td").eq(1).html(nDrink);
          $(this).find("td").eq(2).html(nPrice)
        }
      });
    
      //replace the values from select drink type
      initializeSelect();
      return found;
    }
    
    function initializeSelect() {
      $("#drinkType").html("");
      $("#drinkType").append("<option value='#'>Select Drink</option>");
      $.each(drinkOptions, function(key, value) {
        $("#drinkType").append("<option value='" + key + "'>" + key + " $" + value + "</option>");
      });
    }
    
    //initialize select with drinkOptions
    $(document).ready(function() {
      initializeSelect();
    });
    
    // ready event: short way
    // long way: $(document).ready(function()){
    $(function() {
      // calculates total cost
      $("#placeOrderBtn").click(function() {
        if ($("#drinkType").val() == "#") {
          alert("Please select a drink type");
        } else {
          drink = $("#drinkType").val(); // get the key, in this case Coffee or Tea or Coke
    
          //loop on drinkOptions and find key match
          $.each(drinkOptions, function(key, value) {
            if (drink == key) {
              price = value;
    
              $("tbody").append("<tr class='receiptItem' data-key='" + key + "'><td></td><td>" + key + "</td><td>" + value + "</td><td><input type='button' value='Edit' class='editBtn'><input type='button' value='Save' class='saveBtn'></td></tr>");
            }
          });
        }
    
        // edits information
        $(".editBtn").click(function() {
          $(this).hide(); // hides edit button
          $(this).parent().find(".saveBtn").show(); // displays save button
    
          // finding cells in the row of the selected edit button, but ignores last item
          $(this).closest("tr").find("td:not(:last-child)").each(function() {
            $("td:first-child").prop("contenteditable", false);
            $("tr").not(this).prop("contenteditable", false);
            $(this).prop("contenteditable", true);
    
            $("td:first-child, .editBt, saveBtn").css({
              "backgroundColor": "#fff"
            });
            $(this).css({
              "backgroundColor": "#c4c7c6"
            });
    
          });
        });
        // saves information
        $(".saveBtn").click(function() {
    
          //call function and pass arguments; data-key, drink type, drink price
          var row = $(this).parent().parent();
          if (findNReplaceItem(row.attr("data-key"), row.find("td:nth-child(2)").html(), row.find("td:nth-child(3)").html())) {
    
          } else {
            alert("Didn't find in drinkOptions!");
            $(this).eq(2).val("");
            $(this).eq(3).val("");
          }
    
          $(this).hide(); // hides save button
          $(this).parent().find(".editBtn").show(); // displays edit button
          $(this).prop("contenteditable", false);
          $("td").not(this).prop("contenteditable", false);
    
          $(this).closest("tr").find("td:not(:last-child)").each(function() {
            $(this).css({
              "backgroundColor": "#fff"
            });
          });
    
        });
      }); // end places order click
    
    }); // end of ready event handler
    &#13;
    /* Removes all default margin and padding */
    
    * {
      margin: 0px;
      padding: 0px;
    }
    
    .container {
      background-color: #fff;
      margin: 0px auto;
      width: 80%;
    }
    
    fieldset {
      border-top: 2px solid #ddd;
      border-right: 1px solid #fff;
      border-bottom: 1px solid #fff;
      border-left: 1px solid #fff;
      font-size: 1.2rem;
      margin-left: -10px;
      margin-top: 10px;
      padding-left: .5em;
      width: 400px;
    }
    
    
    /* Centering Customer's Info text */
    
    legend,
    label {
      font-size: 1.2rem;
      text-align: center;
      padding: 0 .25em;
    }
    
    #placeOrderBtn {
      margin-left: -15px;
    }
    
    .hideReceiptBtn {
      display: none;
    }
    
    #receiptOrders tbody {
      counter-reset: rowNumber;
    }
    
    
    /* lists item number */
    
    #receiptOrders tr {
      counter-increment: rowNumber;
    }
    
    
    /* displays item number */
    
    #receiptOrders tbody tr td:first-child:before {
      content: counter(rowNumber);
    }
    
    .saveBtn {
      display: none;
    }
    
    table,
    th,
    td {
      font-size: 1.0rem;
      border-collapse: collapse;
      text-align: center;
    }
    
    th {
      background-color: #dcedec;
      border: 1px solid #aaa;
      padding: .2em;
    }
    
    td {
      border: 1px solid #aaa;
      padding: .3em;
    }
    &#13;
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <header>
      <h1>Sample</h1>
    </header>
    
    <div class="container">
    
      <main>
    
        <br>
    
        <form>
          <fieldset>
            <legend>
              Customer's Information
            </legend>
            <br><br> Drink Order:
            <!--asks for coffee type-->
            <select name="drinkType" id="drinkType">
            <option value="#">Select Drink</option>
        </select>
            <br><br>
            <label>&nbsp;</label>
            <input type="button" id="placeOrderBtn" value="Place Order">
            <br><br>
    
          </fieldset>
        </form>
        <br>
        <h3 class="hiddenReceipt">Receipt</h3>
        <br>
        <table id="receiptOrders">
          <thead>
            <tr>
              <th>Item Number</th>
              <th>Drink Type</th>
              <th>Drink Cost</th>
              <th>Edit/Save</th>
            </tr>
          </thead>
          <tbody></tbody>
        </table>
    
      </main>
    
    </div>
    <!-- end .container -->
    </body>
    
    </html>
    &#13;
    &#13;
    &#13;