【问题标题】:Javascript Form CalculationJavascript表单计算
【发布时间】:2017-04-13 14:16:24
【问题描述】:

我正在尝试用 javascript 制作一个计算抵押贷款的表格,然后将结果呈现到页面上。 这是我的表格:

<form name="calc" id="lidd_mc_form" class="lidd_mc_form" method="post">
<div class="lidd_mc_input mortgage lidd_mc_input_light lidd_mc_input_responsive"><label for="lidd_mc_total_amount">Mortgage Required <note style="color: grey;">(omit commas)</note></label><input type="text" name="lidd_mc_total_amount" id="lidd_mc_total_amount" placeholder="£"><span id="lidd_mc_total_amount-error"></span></div><div class="lidd_mc_input down_payment lidd_mc_input_light lidd_mc_input_responsive"><div style="visibility: hidden; position: absolute;"><label for="lidd_mc_down_payment">Down Payment</label><input type="text" name="lidd_mc_down_payment" id="lidd_mc_down_payment" placeholder="£"><span id="lidd_mc_down_payment-error"></span></div></div><div class="lidd_mc_input interest_rate lidd_mc_input_light lidd_mc_input_responsive"><label for="lidd_mc_interest_rate">Interest Rate <note style="color: grey;">(enter 10% as 10)</note></label><input type="text" name="lidd_mc_interest_rate" id="lidd_mc_interest_rate" placeholder="%"><span id="lidd_mc_interest_rate-error"></span></div><div class="lidd_mc_input amortization_period lidd_mc_input_light lidd_mc_input_responsive"><label for="lidd_mc_amortization_period">Repayment Period <note style="color: grey;">(omit commas)</note></label><input type="text" name="lidd_mc_amortization_period" id="lidd_mc_amortization_period" placeholder="years"><span id="lidd_mc_amortization_period-error"></span></div>
<input type="hidden" name="lidd_mc_payment_period" id="lidd_mc_payment_period" value="12"><div class="lidd_mc_input">

<input type="button" onclick="calc()" name="lidd_mc_submit" id="lidd_mc_submit" value="Calculate"></div></form>

<div id="lidd_mc_details" class="lidd_mc_details" style="display: none;"><div id="lidd_mc_results" class="lidd_mc_results"></div>
                <div id="lidd_mc_summary" class="lidd_mc_summary lidd_mc_summary_light" style="display: block;"></div>
            </div>

这是我正在使用的 Javascript:

            <script>
    function calc() {   /**  * Created by Connor on 13/04/2017.  */


        var mortgageRequired = document.forms["calc"]["lidd_mc_total_amount"].value;
        var interestRate = document.forms["calc"]["lidd_mc_interest_rate"].value;
        var repaymentPeriod = document.forms["calc"]["lidd_mc_amortization_period"].value;


//Calculation

//calculate repayment period in months
        var repaymentMonthly = repaymentPeriod * 12;

//Capital Payment
        var capitalPayment = mortgageRequired * (((interestRate / 12) * (1 + interestRate / 12) ^ repaymentMonthly) /
            ((1 + (interestRate / 12)) ^ repaymentMonthly - 1));

//Interest Only
        var noInterest = mortgageRequired / repaymentMonthly;
        var interestOnly = capitalPayment - noInterest;

//Display
        document.getElementById('lidd_mc_details').innerHTML +=
            interestOnly & capitalPayment;


 } </script>

问题是页面刷新,而且根本不起作用,因为它不会向页面呈现任何内容,即使输入是按钮而不是提交

我也在尝试使代码不会刷新用户页面并且是异步的,这是正确的做法吗?

我对 JavaScript 非常陌生,如果有任何反馈,我将不胜感激!

【问题讨论】:

  • 除了页面刷新问题,你还有什么问题?
  • "is this the right way of doing so?" - 它做你想做的事吗?
  • 确保为函数命名,以便实际调用它们。
  • Scott- 为清楚起见编辑了问题;大卫 - 目前没有,我的意思是良好的实践和标准,以便我可以改进; Jesse - 这个函数不是叫做 calc 吗?;

标签: javascript ajax forms calculator


【解决方案1】:

页面正在刷新,因为您正在使用配置了method 属性的form 元素。表单用于将数据传输到服务器资源,这不是您在此处尝试做的。在这种情况下,您需要禁用表单的提交功能,您可以通过删除 method 属性来做到这一点。

接下来,没有名为 note 的 HTML 元素。这些应该是span 元素。

接下来,您将在末尾使用&amp; 进行连接。这应该是+

此外,不要使用内联 HTML 事件处理程序(onclick、onmouseover 等),因为它们会创建意大利面条式代码,这会导致创建更改 this 绑定的隐式全局包装函数,并且不遵循 W3C 事件标准.改用 addEventListener 在 JavaScript 中绑定事件处理程序。

最后,您的结果区域使用 CSS 样式设置为 display:none,因此单击按钮后您看不到任何内容。单击按钮后,您需要对其进行修改。

这是一个重新设计的版本(参见 cmets):

// These should not be in the function. You only need to scan the DOM for them once.

// Don't set your variables to the values of the input fields. Instead set them to the
// input fields themselves. That way, you can go back and get any other property of the
// field without having to scan the DOM for the element again.  Also, get the reference
// to the element using the more modern approach (i.e. document.getElementById()).
var mortgage = document.getElementById("lidd_mc_total_amount");
var interest = document.getElementById("lidd_mc_interest_rate");
var repayment = document.getElementById("lidd_mc_amortization_period");
var button = document.getElementById("lidd_mc_submit");
var output = document.getElementById('lidd_mc_details');

// Set up event handler for button
button.addEventListener("click", calc);

// The name of the function should not be in parenthesis.
function calc(){ 
  
  // Now, set up variables for the values and remember that all input element values are strings
  // by default and need conversion to numbers before math is done with them.
  var mortgageRequired = parseFloat(mortgage.value);
  var interestRate = parseFloat(interest.value) / 1200;    // Convert to decimal and get periodic rate
  var repaymentPeriod = parseFloat(repayment.value) * 12;  // Get period in months

  //Calculation

  //Capital Payment
  var capitalPayment = mortgageRequired * interestRate * 
                      (Math.pow(1 + interestRate, repaymentPeriod)) / 
                      (Math.pow(1 + interestRate, repaymentPeriod) - 1);

  //Display
  // Use textContent instead of innerHTML when the output doesn't contain HTML
  // and don't use & to concatenate in JavaScript as & means logical "AND", not concatenate
  output.style.display = "block";
  output.textContent = capitalPayment.toFixed(2);
 }
<form name="calc" id="lidd_mc_form" class="lidd_mc_form">
  <div class="lidd_mc_input mortgage lidd_mc_input_light lidd_mc_input_responsive">
    <label for="lidd_mc_total_amount">
      Mortgage Required <span style="color: grey;">(omit commas)</span>
    </label>
    <input type="text" name="lidd_mc_total_amount" id="lidd_mc_total_amount" placeholder="£">
    <span id="lidd_mc_total_amount-error"></span>
  </div>
  <div class="lidd_mc_input down_payment lidd_mc_input_light lidd_mc_input_responsive">
    <div style="visibility: hidden; position: absolute;">
      <label for="lidd_mc_down_payment">Down Payment</label>
      <input type="text" name="lidd_mc_down_payment" id="lidd_mc_down_payment" placeholder="£">
      <span id="lidd_mc_down_payment-error"></span>
    </div>
  </div>
  <div class="lidd_mc_input interest_rate lidd_mc_input_light lidd_mc_input_responsive">
    <label for="lidd_mc_interest_rate">
      Interest Rate <span style="color: grey;">(enter 10% as 10)</span>
    </label>
    <input type="text" name="lidd_mc_interest_rate" id="lidd_mc_interest_rate" placeholder="%">
    <span id="lidd_mc_interest_rate-error"></span>
  </div>
  <div class="lidd_mc_input amortization_period lidd_mc_input_light lidd_mc_input_responsive">
    <label for="lidd_mc_amortization_period">
      Repayment Period <span style="color: grey;">(omit commas)</span>
    </label>
    <input type="text" name="lidd_mc_amortization_period" id="lidd_mc_amortization_period" placeholder="years">
    <span id="lidd_mc_amortization_period-error"></span>
  </div>
  <input type="hidden" name="lidd_mc_payment_period" id="lidd_mc_payment_period" value="12">
  <div class="lidd_mc_input">
    <input type="button" name="lidd_mc_submit" id="lidd_mc_submit" value="Calculate">  </div>
</form>

<div id="lidd_mc_details" class="lidd_mc_details" style="display: none;">
  <div id="lidd_mc_results" class="lidd_mc_results"></div>
  <div id="lidd_mc_summary" class="lidd_mc_summary lidd_mc_summary_light" style="display: block;">   
  </div>
</div>

【讨论】:

  • 我正在尝试使用此解决方案@@liddleperrett.universalwebsitedesigncompany.co.uk/…,但它似乎不起作用,知道为什么吗?
  • “似乎不起作用。”可能意味着任何事情。你的开发者控制台说什么?您是否将 JavaScript 放置在 script 标记中,而该标记恰好位于结束 body 标记之前?
  • Uncaught TypeError: Cannot read property 'replace' of undefined 由我没有编写的名为 changeSummary() 的函数引起的,该网站基于 wordpress CMS
  • 这与您的原始帖子完全不同。如果不深入了解changeSummary() 函数并对其进行调试,就无法帮助您。
  • 这是一个很好的观点,我将就此提出一个单独的问题,我将您的问题标记为正确,因为它是我使用的解决方案,并且您对我最有耐心:) 谢谢!
【解决方案2】:

您需要将一个函数绑定到表单的提交事件以阻止页面重新加载。您可以通过在表单元素上使用addEventListner('submit', function(e) { .. }); 来做到这一点。您将使用e.preventDefault() 停止表单的提交事件,然后您可以继续进行计算和输出。

var form = document.getElementById('calculator');

form.addEventListener('submit', function(e) {
  // Prevent Default will stop the event from firing
  e.preventDefault();
  // Run your calculations here etc.
});
<form method="post" id="calculator">
  <input type="text" />
  <input type="submit" value="Calculate" />
</form>

请参阅此Fiddle 以获取示例。

【讨论】:

  • 您也可以只删除method 属性。
【解决方案3】:

问题是您使用的表单使用了我认为是 php 方法的形式。默认情况下,这将刷新页面。您想在不发出任何网络请求的情况下处理所有内容,因此使用 DOM 操作应该可以完成这项工作。下面是一个工作示例。

 function calc() {   /**  * Created by Connor on 13/04/2017.  */


        var mortgageRequired = document.getElementById("lidd_mc_total_amount").value;
        var interestRate = document.getElementById("lidd_mc_interest_rate").value;
        var repaymentPeriod = document.getElementById("lidd_mc_amortization_period").value;


//Calculation

//calculate repayment period in months
        var repaymentMonthly = repaymentPeriod * 12;

//Capital Payment
        var capitalPayment = mortgageRequired * (((interestRate / 12) * (1 + interestRate / 12) ^ repaymentMonthly) /
            ((1 + (interestRate / 12)) ^ repaymentMonthly - 1));

//Interest Only
        var noInterest = mortgageRequired / repaymentMonthly;
        var interestOnly = capitalPayment - noInterest;

//Display
        document.getElementById('lidd_mc_details').innerHTML +=
            interestOnly & capitalPayment;


 } 
<html>
  <body>
  lidd_mc_total_amount
  <input type="text" id="lidd_mc_total_amount"/>
  <br>
  lidd_mc_interest_rate
  <input type="text" id="lidd_mc_interest_rate"/>
  <br>
  lidd_mc_amortization_period
  <input type="text" id="lidd_mc_amortization_period"/>
  <br>
  <button onClick="calc()">Click for answer</button>

  <div>The answer: <span id="lidd_mc_details"></span></div>
  
  </body>
</html>

【讨论】:

  • 表单元素应始终包裹在form 元素中。简单删除method 属性即可解决刷新问题。
  • 在小提琴中效果很好,但在我的网站上返回“未捕获的 ReferenceError: calc is not defined”有什么想法吗?
  • 确保函数定义在页面底部,靠近body标签的结束端,或至少在使用函数calc的HTML标记之后。 >
猜你喜欢
  • 2016-08-06
  • 2012-08-07
  • 1970-01-01
  • 2012-10-11
  • 2016-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-27
相关资源
最近更新 更多