DEV Community

Akshay Joshi
Akshay Joshi

Posted on

💰 Real-Time Indian Rupee Formatting in HTML Forms — With Clean Backend Submissions

Ever typed 1000000 in a payment form and wished it magically became 10,00,000?
Now imagine you get the visual formatting, but the backend receives a clean, unformatted number.

That’s exactly what this post covers — real-time Indian currency formatting in vanilla JavaScript, with masked display and raw input submission.


🎯 What We’re Building

A form field that:

  • Shows Indian-style commas (1,00,000) while typing
  • Saves a clean numeric value (100000) to the backend
  • Requires no external libraries
  • Is simple and production-safe

đź’ˇ Why Not Just Use <input type="number">?

Because:

  • HTML5 number inputs don’t support comma formatting
  • Indian numbering system (12,34,567) isn’t natively supported
  • Input masks like Cleave.js don’t store raw values unless explicitly managed

So we go native — and clean.


đź”§ Live Demo Structure

<form id="paymentForm"> <label for="formattedAmount">Amount (₹):</label> <input type="text" id="formattedAmount" placeholder="Enter amount" inputmode="numeric"> <input type="hidden" name="amount" id="rawAmount"> <button type="submit">Submit</button> </form> 
Enter fullscreen mode Exit fullscreen mode

We use:

  • #formattedAmount: visible input with commas
  • #rawAmount: hidden input storing plain numeric value

đź§  JavaScript Logic

const formattedInput = document.getElementById('formattedAmount'); const rawInput = document.getElementById('rawAmount'); function formatIndianNumber(x) { const parts = x.split('.'); let integerPart = parts[0]; const decimalPart = parts.length > 1 ? '.' + parts[1] : ''; integerPart = integerPart.replace(/^0+/, '') || '0'; const lastThree = integerPart.slice(-3); const rest = integerPart.slice(0, -3); const formatted = rest.replace(/\B(?=(\d{2})+(?!\d))/g, ",") + (rest ? ',' : '') + lastThree; return formatted + decimalPart; } formattedInput.addEventListener('input', () => { const raw = formattedInput.value.replace(/,/g, '').replace(/[^\d.]/g, ''); formattedInput.value = formatIndianNumber(raw); rawInput.value = raw; }); document.getElementById('paymentForm').addEventListener('submit', () => { rawInput.value = formattedInput.value.replace(/,/g, ''); console.log("Submitted value:", rawInput.value); }); 
Enter fullscreen mode Exit fullscreen mode

âś… Features

Feature Included
Live Indian formatting âś…
Works with decimals âś… (basic)
Form-safe hidden input âś…
No external dependency âś…
Easy integration âś…

📦 Backend Ready

At submission:

<input type="hidden" name="amount" value="100000"> 
Enter fullscreen mode Exit fullscreen mode

Your backend receives:

{ "amount": "100000" } 
Enter fullscreen mode Exit fullscreen mode

No commas, no parsing required. Just clean data.


🛡️ Bonus Tips

  • Don't use type="number" on the formatted input — it conflicts with commas.
  • Add pattern="\d+(,\d{2})?" or maxlength="15" for validation.
  • Support for decimals? Adjust regex and formatting as needed.

🚀 Final Thoughts

This pattern is a small but powerful UX booster:

  • Keeps forms user-friendly
  • Simplifies backend parsing
  • Gives you full control with native JavaScript

Sometimes, the cleanest solutions don’t need packages — just precise logic.


Happy coding 🇮🇳💻

Top comments (0)