0

I'm working on a Django project and one of the forms won't submit. I figured out that the culprit is some JavaScript that formats the currency input (when I remove the JS or remove the input type="currency", it submits)

This is my simplified form - the JS is from html5 input for money/currency

var currencyInput = document.querySelector('input[type="currency"]')
var currency = 'GBP'

// format inital value
onBlur({
  target: currencyInput
})

// bind event listeners
currencyInput.addEventListener('focus', onFocus)
currencyInput.addEventListener('blur', onBlur)


function localStringToNumber(s) {
  return Number(String(s).replace(/[^0-9.-]+/g, ""))
}

function onFocus(e) {
  var value = e.target.value;
  e.target.value = value ? localStringToNumber(value) : ''
}

function onBlur(e) {
  var value = e.target.value

  var options = {
    maximumFractionDigits: 2,
    currency: currency,
    style: "currency",
    currencyDisplay: "symbol"
  }

  e.target.value = value ?
    localStringToNumber(value).toLocaleString(undefined, options) :
    ''
}
<form action="{% url 'create_goal' %}" method="post">

  <h4 class="mb-3" id="create">Create a Savings Goal</h4>

  <input type="text" class="form-control" id="goalName" name="goalName" value="" required>

  <input type="currency" min="0" pattern="^\d*(\.\d{0,2})?$" class="form-control" id="goal" name="goal" required>

  <button type="submit" class="btn btn-secondary btn-block">Add Goal</button>

</form>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Anna
  • 359
  • 1
  • 4
  • 13
  • This does not seem to be a Django issue. I clicked edit, then `[<>]` snippet editor and replaced the template with just HTML – mplungjan Jun 17 '20 at 05:42
  • No, I know it's not a Django issue. I'm not sure what you mean - this (excluding some irrelevant tags and template inherited) is the actually rendered template. Moving the function calls around doesn't fix the issue. The only 'fix' is removing the JS or removing the ```type="currency"``` – Anna Jun 17 '20 at 05:47
  • I know, hence I made the snippet for you. But since it is not a django issue, we do not need to pollute with the django tag – mplungjan Jun 17 '20 at 05:48
  • ah the tag... alright yep thanks – Anna Jun 17 '20 at 05:49

1 Answers1

0

You have required and you have a pattern="^\d*(\.\d{0,2})?$"

Your currency code breaks the pattern and stops the submission because the HTML5 validation fails on the modified value

So

  1. allow the currency pattern OR
  2. show another field, like a span over the input OR
  3. remove the pattern like I did below

You can set the custom error in the currency code if the user fails to input a valid amount

How to create html5 custom validation?

var currencyInput = document.querySelector('input[type="currency"]')
var currency = 'GBP'

// format inital value
onBlur({
  target: currencyInput
})

// bind event listeners
currencyInput.addEventListener('focus', onFocus)
currencyInput.addEventListener('blur', onBlur)


function localStringToNumber(s) {
  return Number(String(s).replace(/[^0-9.-]+/g, ""))
}

function onFocus(e) {
  var value = e.target.value;
  e.target.value = value ? localStringToNumber(value) : ''
}

function onBlur(e) {
  const tgt = e.target;
  var value = tgt.value

  if (isNaN(value))
    tgt.setCustomValidity('Please enter a valid amount');
  else
    tgt.setCustomValidity('');

  var options = {
    maximumFractionDigits: 2,
    currency: currency,
    style: "currency",
    currencyDisplay: "symbol"
  }

  e.target.value = value ?
    localStringToNumber(value).toLocaleString(undefined, options) :
    ''
}
<form action="{% url 'create_goal' %}" method="post">

  <h4 class="mb-3" id="create">Create a Savings Goal</h4>

  <input type="text" class="form-control" id="goalName" name="goalName" value="" required>

  <input type="currency" min="0" class="form-control" id="goal" name="goal" required>

  <button type="submit" class="btn btn-secondary btn-block">Add Goal</button>

</form>
mplungjan
  • 169,008
  • 28
  • 173
  • 236