简体   繁体   中英

How can I multiply fields containing both natural values and currency?

I'm trying to replicate a calculator from my Excel spreadsheet to a webpage. The first field is an input to natural numbers (without commas), the second is to some currency values (with commas, points, etc) and the third is the total, but it has a defined value (for example, 0,38 cents). Both of the fields must multiply and give a result in the third field.

I tried to create a mask using a mask plugin, but had several errors. Tried to use toLocaleStrings too.

I'm having problems with the masks and the results. That's the expected result : 捕获

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')
}

});

Try using a regex to parse out all the non digit and decimal symbols. The toDigits function below accomplishes just that and allows you to use regular math after that.

 $(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>

It's functional here without any plugins. Something you could customize to fit to your actual project. Hopefully the next HTML standards would finally bring inline localization to input fields.


[UPDATE] Using a less delayed Onchange instead of keyup event handlers, would allow easier typing and become more user-friendly. And allowed typing using comma that would be replaced to the default expected dot so that parseFloat function would treat it as a valid number. So we could use a regex pattern to format the currency value.

 $(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)(?=(\\d{3})+(?!\\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>

You can use Number.toLocaleString('en-us',{minimumFractionDigits:2,maximumFractionDigits:2})+'€' to get your desired currency format.

 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>

Although I am still a big fan of jQuery, I have written the above in Vanilla JS. It is simple enough ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM