1

If I have an <input type="email">, and the user enters an Internationalized Domain Name, Angular (EDIT: except it's not Angular's fault - see my answer for details) automatically converts the value to punycode, which is a nice feature, but very confusing for users if the value is displayed back to them. E.g.

abc@ábc.com

becomes

abc@xn--bc-lia.com

It also causes issues when a backend is expecting the original Unicode version of the domain, and the Angular app instead sends the punycode version.

I can use e.g. punycode.js to convert it back, but is there a way to do this in Angular without involving another library - either tell Angular not to do the encoding, or get the original value subsequently?

var myApp = angular.module('myApp',[]);

function thing($scope) {
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<p>Copy this text into the input:</p>
<p>abc@ábc.com</p>
<div ng-controller="thing">
  <input id="inp" type="email" class="form-control" ng-model="addr">
  <p>Model gets: {{addr}}</p>
</div>
</body>
Community
  • 1
  • 1
CupawnTae
  • 14,192
  • 3
  • 29
  • 60
  • I think the question (and the answer) could be easier to find on the internet if it would be: "Prevent Chrome email input forms from converting to Punycode" – rbelow May 06 '21 at 19:26
  • True, but at that point, does it become basically a dupe of the [question](https://stackoverflow.com/a/37205099/1469259) I linked in my answer? If I google `chrome email punycode`, that question comes up straight away. Your answer below is a good point though! – CupawnTae May 06 '21 at 20:02

3 Answers3

4

It turns out it's not Angular that's doing it, it's Chrome (Safari does not have the same behaviour, haven't tested other browsers). See for example Input type email value in Chrome with accented characters wrong

Here's an example of it happening without Angular - try this in Chrome:

function update() {
  document.getElementById('output').innerText = document.getElementById('inp').value
}
<p>Copy this text into the input:</p>
<p>abc@ábc.com</p>
<div ng-controller="thing">
  <input id="inp" type="email" onchange="update()">
  <p>Browser says: <span id="output"></span></p>
</div>

So the short answer is no, there's no way of stopping this via Angular - and currently there doesn't appear to be a way to tell Chrome not to do it either.

Community
  • 1
  • 1
CupawnTae
  • 14,192
  • 3
  • 29
  • 60
1

As for today: 2021-05-06 these are the browsers behaviors regarding converting input fields from type=email on keystroke to Punycode:

  • Chrome: Converts to Punycode
  • Firefox: Does not convert to Punycode
  • Safari: Does not convert to Punycode
  • Edge: Does not convert to Punycode
  • Internet Explorer: Does not convert to Punycode

If you do not want this behavior on Chrome remove type=email from your input field!

rbelow
  • 726
  • 8
  • 7
0

As soon as you use ng-model on input type email, angularjs will use its magic on the input.

Try it without ng-model

Andrew Donovan
  • 552
  • 2
  • 14
  • But I want to bind the input to my model - without `ng-model` how would I achieve this? – CupawnTae May 11 '16 at 15:22
  • 1
    You could use ng-change, to then bind to a scope variable, but read some docs. There must be a way to use ng-model while preventing angularjs to woe its magic on the input email – Andrew Donovan May 11 '16 at 15:31
  • 2
    FYI, in case you're interested, turns out it's not Angular's fault - posted an answer to that effect – CupawnTae May 13 '16 at 08:36