如何将包含自然值和货币的字段相乘?

Posted

技术标签:

【中文标题】如何将包含自然值和货币的字段相乘?【英文标题】:How can I multiply fields containing both natural values and currency? 【发布时间】:2020-06-07 15:15:37 【问题描述】:

我正在尝试将计算器从我的 Excel 电子表格复制到网页。 第一个字段是自然数的输入(不带逗号),第二个是一些货币值(带逗号、点等),第三个是总数,但它有一个定义的值(例如,0,38 美分)。两个字段必须相乘并在第三个字段中给出结果。

我尝试使用遮罩插件创建遮罩,但出现了几个错误。也尝试使用 toLocaleStrings。

我对掩码和结果有疑问。 这是预期的结果:

html

<form>
<!-- simple number to start the calculation -->
<label>Natural Number</label>
<input type="text" id="base" />
<br>
<!-- currency including the cents -->
<label>Currency value</label>
<input type="text" id="ticket" />
<br>
<!-- If the first field is "1" and the second is "1,00", this field has a value of 0.38 cents. -->
<label>Currency total</label>
<input type="text" id="cost" readonly /></form>

JQUERY

$(document).ready(function()
$('#cost').mask('000.000.000.000.000,00', reverse: true);

$('#base').keyup(calculate);
$('#ticket').keyup(calculate)

function calculate(e) 
$('#cost').val($('#base').val() * $('#ticket').val() * 0.38).trigger('input')

);

【问题讨论】:

你能告诉我们预期的货币价值格式吗?您是否尝试过使用 Maskmoney github.com/plentz/jquery-maskmoney... 请在您的问题中添加预期的格式 我在帖子中添加了一个结果示例。我尝试了一个 maskMoney,实际上是一个更有效的面具。但有时总货币不显示小数。 【参考方案1】:

尝试使用正则表达式来解析所有非数字和十进制符号。 下面的 toDigits 函数正好完成了这一点,并允许您在此之后使用常规数学。

$(document).ready(function()
  //add maskMoney listener
  $('#base').keyup(calculate);
  $('#ticket').keyup(calculate);
);

function calculate(e) 
  const percent = 0.38,
    baseValToDigits = toDigits($('#base').val() || 0),
    ticketValToDigits = toDigits($('#ticket').val() || 0),
    costVal = baseValToDigits * ticketValToDigits,
    percentageOfCostVal = costVal * percent;
  //format percentageOfCostVal as currency
  $('#cost').val(percentageOfCostVal).trigger('input')

function toDigits(val) 
    const isNeg = /(\(.*\))|^[-]/.test(val),
        digits = parseFloat(val.toString().replace(/[^0-9\.]+/g,""));
    return isNeg ? digits * -1 : +digits;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
  <!-- simple number to start the calculation -->
  <label>Natural Number</label>
  <input type="text" id="base" />
  <br>
  <!-- currency including the cents -->
  <label>Currency value</label>
  <input type="text" id="ticket" />
  <br>
  <!-- If the first field is "1" and the second is "1,00", this field has a value of 0.38 cents. -->
  <label>Currency total</label>
  <input type="text" id="cost" readonly />
</form>

【讨论】:

它对计算有效,我使用 maskMoney 到小数点,但总不显示掩码,除非我用光标单击。 我已经修改了上面的代码。您可以添加回您的 maskMoney 侦听器,也可以在设置成本字段的值之前正确格式化该值。两个选项见上述代码中的 cmets 谢谢。一切正常。但我认为 maskMoney 有一些限制,因为我总是必须点击结果才能看到小数点。 如果这是 jquery 的掩码货币,我确实找到了一个简介:重要提示:如果您尝试将 maskMoney 绑定到只读字段,则不会发生任何事情,因为我们完全忽略了只读字段。因此,如果您有一个只读字段,请尝试将 maskMoney 绑定到它,它将不起作用。即使您更改了删除只读属性的字段,您也需要重新绑定 maskMoney 才能使其工作。 我不知道我是否理解得很好。我已经从输入中删除了“只读”。但这没关系,因为当我选择它时,该字段只显示货币格式。【参考方案2】:

无需任何插件即可使用。您可以自定义以适合您的实际项目。希望下一个 HTML 标准最终将内联本地化引入输入字段。


[更新] 使用延迟较少的 Onchange 而不是 keyup 事件处理程序,可以更轻松地键入并变得更加用户友好。并允许使用逗号输入,该逗号将被替换为默认的预期点,以便 parseFloat 函数将其视为有效数字。 所以我们可以使用正则表达式模式来格式化货币值。

$(document).ready(function()

$('form').on('change','#base,#ticket',function() 
  var ticket=parseFloat($('#ticket').val().replace(',', '.'));
  calculate();
  if(!isNaN(ticket))
  $('#ticket').val(EuroFormat(ticket));
  
  );

function calculate(e) 
var ticket=parseFloat($('#ticket').val().replace(',', '.'));
var total = parseFloat($('#base').val()) * ticket * 0.38;
if(!isNaN(total))
$("#cost").val(EuroFormat(total));




function EuroFormat(num) 
  return (  num.toFixed(2).replace('.', ',').replace(/(\d)(?=(\d3)+(?!\d))/g, '$1.') + ' €'  ) 
 
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<!-- simple number to start the calculation -->
<label>Natural Number</label>
<input type="text" id="base" autocomplete="off"/>
<br>
<!-- currency including the cents -->
<label>Currency value</label>
<input type="text" id="ticket" autocomplete="off"/>
<br>
<!-- If the first field is "1" and the second is "1,00", this field has a value of 0.38 cents. -->
<label>Currency total</label>
<input type="text" id="cost" readonly"/></form>

【讨论】:

这是一个很好的选择。但我不知道用户是否可以快速打字。 obs。我也在等待 HTML 的内联解决方案。 使用点代替逗号对我来说已经是个问题了 :) 在我的国家,我们只使用逗号作为小数...是的,应该添加到当地人! 我刚刚使用 onChange 事件更新了它,这在这种情况下更加用户友好 谢谢。完全更友好。但门票价值不接受美分。 确实如此!好吧,这就是我上面提到的 javascript 的问题...您需要使用点输入 :) 我确实记得在发票表单中为客户找到了解决方法。我会看看我能做什么【参考方案3】:

您可以使用Number.toLocaleString('en-us',minimumFractionDigits:2,maximumFractionDigits:2)+'€' 获取您想要的货币格式。

const curr=v=>isNaN(+v)?'':(+v).toLocaleString('en-us',minimumFractionDigits:2,maximumFractionDigits:2)+' €';
var d=;
['base','ticket','cost'].forEach((id,i)=>
  d[id]=document.querySelector('#'+id); 
  if(i<2) d[id].addEventListener('change',ev=>
    var tv=parseFloat(d.ticket.value.replace(/,/g,''));
    d.cost.value=curr(d.base.value*tv*.38);
    d.ticket.value=curr(tv);
  );
)
<form>
  <!-- simple number to start the calculation -->
  <label>Natural Number</label>
  <input type="text" id="base" />
  <br>
  <!-- currency including the cents -->
  <label>Currency value</label>
  <input type="text" id="ticket"/>
  <br>
  <!-- If the first field is "1" and the second is "1,00", this field has a value of 0.38 cents. -->
  <label>Currency total</label>
  <input type="text" id="cost" readonly />
</form>

虽然我仍然是 jQuery 的忠实粉丝,但我已经用 Vanilla JS 编写了以上内容。这很简单......

【讨论】:

香草已经足够好了。但在这种情况下,票证不是货币格式。 有很多方法可以解决这个问题:要么在输入字段后面打印货币符号(作为标签的一部分),要么 - 正如我刚刚在回答中所做的那样- 通过将其放置在那里并在处理过程中忽略它来“允许”它在字段本身中。您当然可以在每次编辑值后将其“强制”返回,但是由于我的操作由 keyup 事件触发,这会造成严重破坏。因此,在我的示例中,我只接受带有和不带货币符号的值。 其实符号不重要,小数点很重要。我需要第二个字段中的逗号和点,使其类似于 Excel 电子表格及其格式化货币。 好的,我已经把触发事件从keyup改成了change。这使得现在可以将货币后处理curr() 应用于#ticket#cost 输入字段。也许这就是你想要的?

以上是关于如何将包含自然值和货币的字段相乘?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Access 2010 中将单个字段的所有记录相乘

MongoDB:如何将仅出现在 $project 中的字段相乘?

SQL Select,如何将数字显示为货币并将反向数字显示为正数

如何将 SqlDbtype.Money = 0 与 Sql 服务器中的货币字段进行比较

如何在报表生成器中动态格式化货币字段?

如何将 Json 数组作为统一字段传递给 WWWform