如何将包含自然值和货币的字段相乘?
Posted
技术标签:
【中文标题】如何将包含自然值和货币的字段相乘?【英文标题】:How can I multiply fields containing both natural values and currency? 【发布时间】:2020-06-07 15:15:37 【问题描述】:我正在尝试将计算器从我的 Excel 电子表格复制到网页。 第一个字段是自然数的输入(不带逗号),第二个是一些货币值(带逗号、点等),第三个是总数,但它有一个定义的值(例如,0,38 美分)。两个字段必须相乘并在第三个字段中给出结果。
我尝试使用遮罩插件创建遮罩,但出现了几个错误。也尝试使用 toLocaleStrings。
我对掩码和结果有疑问。 这是预期的结果:
<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
输入字段。也许这就是你想要的?以上是关于如何将包含自然值和货币的字段相乘?的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB:如何将仅出现在 $project 中的字段相乘?
SQL Select,如何将数字显示为货币并将反向数字显示为正数