ฉันต้องการรวมตัวเลขเมื่อทำเครื่องหมายในช่องด้วยจาวาสคริปต์

ฉันต้องการรวมตัวเลขและพิมพ์ออกมาในช่วง ฉันลองใช้ innerHTML แต่เนื่องจากเป็นสตริงฉันทำไม่ได้ ฉันจึงลอง parseInt, parseFloat, Number และไม่มีอะไรเลย สำหรับช่องทำเครื่องหมายทั้งหมดที่ทำเครื่องหมายไว้ ฉันต้องการผลรวมของค่าในช่วงและผู้ที่ไม่ได้ทำเครื่องหมาย ฉันไม่ต้องการให้พวกเขาได้รับผลรวมในช่วง

(ผมลดตารางและจำนวนลงเยอะมากเพราะว่ายาวมากในการใส่ตรงนี้ ลองนึกภาพว่าผมอยากบวกจำนวนทั้งหมดเยอะๆ)

const offersCheckbox = document.querySelectorAll("#checkbox-offers");
const recalculateText = document.querySelector(".recalculate-text");
const checkboxTotal = document.querySelectorAll("#checkbox-total");
let total = 0;

for (let i = 0; i < offersCheckbox.length; i++) {
  offersCheckbox[i].addEventListener("click", (e) => {
    if (offersCheckbox[i].checked === true) {
      recalculateText.innerHTML = "recalculate invoice total";
    } else {
      recalculateText.innerHTML = "";
    }
  });
}
<table>
  <tr>
    <tr>
      <td>
        <input type="checkbox" name="checkbox" id="checkbox-offers" value="2,434.38" />
        <td>
          <div class="price-container text-bold" id="checkbox-total">
            <b>$</b>2,434.38
          </div>
        </td>
    </tr>

    <tr>
      <td>
        <input type="checkbox" name="checkbox" id="checkbox-offers" value="76.69" />
      </td>
      <td>
        <div class="price-container text-bold" id="checkbox-total">
          <b>$</b>76.69
        </div>
      </td>
    </tr>
</table>

<span class="recalculate-text text-right text-underline"></span>


person Simon    schedule 03.03.2021    source แหล่งที่มา
comment
คุณลองทำอะไร? SO ไม่ใช่การเขียนโค้ดหรือประเมินบริการฟรี แบ่งปันความสำเร็จของคุณแล้วเราจะแก้ไข นอกจากนี้ ให้ตัวอย่างที่ทำซ้ำได้น้อยที่สุด ด้วยการกดปุ่ม ‹› ในตัวแก้ไขและสร้างตัวอย่างข้อมูล ซึ่งจะเพิ่มโอกาสของคุณอย่างมาก ได้รับคำตอบ เพื่อชี้ให้เห็นว่า ทั้งหมดที่คุณต้องรู้เกี่ยวกับวิธีการทำเช่นนี้ มีคำตอบแล้วที่นี่หรือบน Google ดังนั้นให้พยายามถามคำถามและพยายามแก้ไขปัญหานี้ ยินดีต้อนรับสู่ SO,   -  person ikiK    schedule 03.03.2021
comment
รหัสองค์ประกอบ HTML จะต้องไม่ซ้ำกัน คุณต้องเปลี่ยนแอตทริบิวต์ id ของแต่ละช่องป้อนข้อมูล   -  person AGE    schedule 04.03.2021
comment
ฉันเปลี่ยนรหัสชั้นเรียนแล้ว แต่นั่นไม่ได้แก้ไขปัญหาของฉัน มีวิธีแก้ไขไหม?   -  person Simon    schedule 04.03.2021
comment
นั่นเป็นเพราะตัวเลือก jquery ของคุณไม่ถูกต้อง มีคำตอบสองสามข้อที่คุณสามารถพิจารณาได้   -  person AGE    schedule 04.03.2021


คำตอบ (4)


ฉันไม่ได้เปลี่ยนแปลงมากเกินไปจากรหัสเดิมของคุณ ดูความคิดเห็นเพื่อทำความเข้าใจการเปลี่ยนแปลงที่ฉันทำ และอย่าลังเลที่จะแสดงความคิดเห็นหากคุณมีคำถามเพิ่มเติม

const recalculateText = document.querySelector(".recalculate-text");
const checkboxContainer = document.querySelector("#checkbox-container");
let total = 0;

// Create a number formatter to print out on the UI - this is a better approach than regex IMO.
const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

//Notice the use of event delegation here - meaning I only added 1 single event handler to a single DOM element
//Read this blog for more on event delegation and why it's useful: https://davidwalsh.name/event-delegate
checkboxContainer.addEventListener('change', e => {
  //Also notice that I am listening for the change event, instead of the click event.
  //See here: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event
  if (e.target.tagName == "INPUT") {
    const floatValue = parseFloat(e.target.value);
    if (e.target.checked) {
      total += floatValue;
    } else {
      total -= floatValue;
    }
  }

  recalculateText.innerHTML = formatter.format(total);
});
<!-- Notice I added a parent div to enable use to use event delegation technique -->
<!-- Also notice I removed element id attributes where they were not needed. Also be sure
to always use unique id values for every element - duplicate ids are not allowed, it will 
lead to bugs. If elements need to be considered part of the same "group" then you should use
the class attribute. -->
<div id="checkbox-container">
  <table>
    <tr>
      <tr>
        <td>
          <!-- Notice I removed the comma from the value attribute -->
          <input type="checkbox" name="checkbox" value="2434.38" />
          <td>
            <div class="price-container text-bold">
              <b>$</b>2,434.38
            </div>
          </td>
      </tr>

      <tr>
        <td>
          <input type="checkbox" name="checkbox" value="76.69" />
        </td>
        <td>
          <div class="price-container text-bold">
            <b>$</b>76.69
          </div>
        </td>
      </tr>
  </table>
</div>
<span class="recalculate-text text-right text-underline"></span>

person Tom O.    schedule 03.03.2021
comment
ฉันไม่ได้เปลี่ยนแปลงมากเกินไปจากรหัสเดิมของคุณ คุณควรระบุถ้าไม่มีรหัสเดียวกันซ้ำกัน... มี document.querySelectorAll("#checkbox-offers"); ใน id ซึ่งซ้ำกัน... และ querySelectorAll จะแม่นยำยิ่งขึ้น ดังนั้นรหัสที่มันไม่ถูกต้องและจำเป็นต้องแก้ไข - person ikiK; 04.03.2021
comment
สิ่งนี้ได้ผลสำหรับฉัน แทนที่จะใช้ฟอร์แมตเตอร์นั้น ฉันใช้ split(,).join() และทำฟังเหตุการณ์กับอินพุตที่ไม่ได้อยู่ในคอนเทนเนอร์ div ขอบคุณทุกคน - person Simon; 04.03.2021

ตามการแก้ไขรหัสที่คุณมีอยู่แล้ว:

  1. id นั้นไม่ซ้ำกัน ดังนั้นให้ใช้ checkbox-offers เป็นคลาสและ querySelectorAll เนื่องจากคุณมีลูปอยู่แล้ว
  2. ตัวเลข Js ไม่มี , อยู่ในนั้น ดังนั้นคุณต้องล้างมันเพื่อให้ได้ตัวเลขที่สามารถใช้งานฟังก์ชันทางคณิตศาสตร์ได้
  3. ในลูปของคุณ คุณมี (e) แม่มดบ่งชี้เหตุการณ์ ดังนั้นใช้ e.target เพื่อกำหนดเป้าหมาย event แล้วยื่นและรับ value
  4. กับ offersCheckbox[i] คุณแค่ addEventListener และต่อจากนั้นคุณก็ใช้ e.target
  5. คุณต้องแปลงค่าเป็นตัวเลขด้วย parseFloat(num)
  6. เมื่อใส่ค่า คุณต้องคำนึงถึงมูลค่าที่เพิ่มเข้าไปแล้ว หากมี หากไม่แยกวิเคราะห์เป็น 0 หากมีบางส่วนแยกวิเคราะห์เป็นตัวเลขและเพิ่มส่วนเพิ่มเติมเข้าไป:
  7. หากคุณต้องการเพิ่ม back เป็นตัวคั่นที่พันเพื่อให้ได้ผลลัพธ์ซึ่งมีคำตอบมากมายที่นี่ใน SO เพียงค้นหาพวกเขา

คำนวณใหม่ Text.innerHTML = (parseFloat (คำนวณใหม่ Text.innerHTML || 0) + num2)

const offersCheckbox = document.querySelectorAll(".checkbox-offers");
const recalculateText = document.querySelector(".recalculate-text");

let total = 0;

for (let i = 0; i < offersCheckbox.length; i++) {
  offersCheckbox[i].addEventListener("click", (e) => {
   
    let num = e.target.value.split(",").join("")
    let num2 = parseFloat(num)

    if (e.target.checked === true) {
      recalculateText.innerHTML = (parseFloat(recalculateText.innerHTML || 0) + num2)
    } else {
      recalculateText.innerHTML = "";
    }
  });
}
<table>
  <tr>
    <tr>
      <td>
        <input type="checkbox" class="checkbox-offers" name="checkbox" value="2,434.38" />
        <td>
          <div class="price-container text-bold" id="checkbox-total">
            <b>$</b>2,434.38
          </div>
        </td>
    </tr>

    <tr>
      <td>
        <input type="checkbox" class="checkbox-offers" name="checkbox" value="76.69" />
      </td>
      <td>
        <div class="price-container text-bold" id="checkbox-total">
          <b>$</b>76.69
        </div>
      </td>
    </tr>
</table>

<span class="recalculate-text text-right text-underline"></span>

ลิงค์ที่มีประโยชน์:

เมธอด querySelectorAll และ getElementsBy* ส่งคืนอะไร

วิธีพิมพ์ตัวเลขด้วยเครื่องหมายจุลภาคเป็น ตัวคั่นหลักพันใน JavaScript

คุณสมบัติใดบ้างที่ฉันใช้กับ event.target ได้

จะแปลงสตริงเป็นจำนวนเต็มใน JavaScript ได้อย่างไร< /ก>

person ikiK    schedule 03.03.2021

โปรดทราบว่าคุณจำเป็นต้องใช้ประโยชน์จากระบบตัวจัดการเหตุการณ์ของฟิลด์อินพุต ในกรณีนี้ onchange โดยที่แต่ละฟิลด์อินพุตจะจัดการการแก้ไขค่าที่เก็บไว้ของผลรวมของแต่ละราคา

ฉันเขียนสกุลเงินลงใน Number Normalizer ผ่าน regex แต่ฉันไม่ได้เขียนตัวเลขลงในตัวจัดรูปแบบสกุลเงิน เพื่อจัดรูปแบบผลรวมกลับเป็นสกุลเงินใหม่ คุณจะต้องจัดการกับสิ่งนั้นด้วยตัวเอง

let sum = 0;

let addPrice = (elem) => {
  let value = parseFloat(elem.value.replace(/\$|,/g, ''), 2);
  
  elem.checked ? (sum += value) : (sum -= value);

  document.getElementById('result').innerHTML = sum;
};
<table>
  <tr>
    <tr>
      <td>
        <input type="checkbox" name="price" value="2,434.38" onchange="addPrice(this)" />
        <td>
          <div class="price-container text-bold">
            <b>$</b>2,434.38
          </div>
        </td>
    </tr>

    <tr>
      <td>
        <input type="checkbox" name="price" value="76.69" onchange="addPrice(this)" />
      </td>
      <td>
        <div class="price-container text-bold">
          <b>$</b>76.69
        </div>
      </td>
    </tr>
</table>

<div class="recalculate-text text-right text-underline">Total: <span id="result">0</span></div>

person AGE    schedule 03.03.2021
comment
ทำไมคุณถึงเพิ่ม jquery ในตัวอย่างสำหรับการแทรกสุดท้ายนั้นเพื่อความรักของพระเจ้า!? และไม่ได้กล่าวถึง jquery ในคำถาม;) - person ikiK; 04.03.2021
comment
@ikiK อืมบรรทัด jQuery นั้นสามารถเปลี่ยนเป็น document.getElementById ได้อย่างง่ายดาย อัปเดตเพื่อความสอดคล้อง - person AGE; 04.03.2021
comment
แน่นอนมันทำได้ และมันควรจะเป็น :) ฉันคิดว่ามันตลกดี หลังจากทุกอย่างใน vanilla js แล้ว ให้แทรกด้วย jquery มันไม่สมเหตุสมผลเลย - person ikiK; 04.03.2021
comment
ฉันเข้าใจคุณแล้ว ข้อดีก็คือ - person AGE; 04.03.2021
comment
ขอบคุณ ฉันชอบแนวทางการใช้ regex ของคุณสำหรับสิ่งนี้ แต่คุณจะไม่พบว่าฉันใช้มันเพื่อสิ่งง่ายๆ แบบนี้ Split.join คือหนทางของฉัน ตัวอย่างที่ดีอย่างไรก็ตาม นอกจากนี้ยังมีการแทนที่ทั้งหมด เพื่อให้มันซ้ำซ้อนมากยิ่งขึ้น - person ikiK; 04.03.2021
comment
ฉันเข้าใจประเด็นของคุณ ตัวจัดรูปแบบสกุลเงินเป็นอุปสรรคในการใช้งานอีกประการหนึ่งสำหรับผู้ที่ถามคำถามเพื่อแก้ไข ฉันสามารถให้คำตอบที่ดีมากสำหรับสิ่งนั้นเนื่องจากฉันสร้างหลายอย่างด้วยตัวเอง แต่ข้อจำกัดมักจะเข้มงวดกว่ามากที่นี่ (ด้วยเหตุนี้ regex ที่ตรงไปตรงมา) ปัญหาของคำถามคือสิ่งสำคัญที่นี่ - person AGE; 04.03.2021
comment
หยาบมันเป็นแค่ 2 เซ็นต์ของฉันไชโย - person ikiK; 04.03.2021

person    schedule
comment
แม้ว่าคำตอบเช่นนี้จะสามารถแก้ปัญหาที่พวกเขาไม่ได้รับการต้อนรับใน SO ได้ แต่พวกเขาต้องการคำอธิบายเพื่อให้ความเป็นจริงของ OP เรียนรู้บางสิ่งจากพวกเขาในครั้งต่อไป - person ikiK; 04.03.2021