2

I want to block the entry of accented letters (any language) in input, preferably I would like this block to be done with regex through the attribute pattern

I tried something but I did not succeed...

<form>
  <label for="username">Name <i>(only letters without accent)</i></label>
  <br>
  <input name="username" id="username" type="text" pattern="[A-Za-z]+" oninvalid="this.setCustomValidity('Only letters without accent')">
</form>

Accepts: Joao Silva, Pedro, Fabio Duarte...

Rejects: João Silva, Pedro Camões, Fábio Duarte ...

Ωmega
  • 42,614
  • 34
  • 134
  • 203
Mathiasfc
  • 1,627
  • 1
  • 16
  • 24
  • maybe a duplicate of this? https://stackoverflow.com/questions/30225552/regex-for-diacritics – dmgig May 22 '18 at 14:30
  • Doesn't it reject / accept correctly if that's the current behavior? – revo May 22 '18 at 14:33
  • @revo Yes, but only in the first time... If I miss the pattern and then adjust, continue firing the validation error. – Mathiasfc May 22 '18 at 14:35
  • Probably you want something like `pattern="[A-Z][A-Za-z]* [A-Z][A-Za-z]*"`, though it is rather restrictive (no `'` and `-` are allowed). – Wiktor Stribiżew May 22 '18 at 14:36
  • 1
    Your problem is with `oninvalid` attribute. See https://stackoverflow.com/questions/16867407/html5-why-does-my-oninvalid-attribute-let-the-pattern-fail – revo May 22 '18 at 14:40
  • Also if you need spaces you should allow them in character class. – revo May 22 '18 at 14:41
  • I am very curious about _**why**_ you want to prevent people from properly entering their name? My thought is that you may be trying to work around some _other_ problem that could be fixed (for example, if the database is not storing accented characters correctly the DB needs to be configured to allow it) – Stephen P May 22 '18 at 17:35
  • 1
    @StephenP Hey Stephen thanks for the advice, I remembered [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)... I'm actually doing this to avoid future problems, but if I use this, I'll use it for usernames, I used people's names only in the scope of the question. – Mathiasfc May 22 '18 at 17:46

2 Answers2

1
<input name="username" id="username" type="text" 
    pattern="[A-Za-z ]*" title="Latin letters and space characters only"> />

Test this code here.


Alternatively, you can control what characters are allowed during typing.

<input name="username" id="username" type="text" onCopy="return false" 
    onDrag="return false" onDrop="return false" onPaste="return false" 
    autocomplete=off />

jQuery:

$(document).ready(function() {
    $("#username").keypress(function(event) {
        var inputValue = event.which;
        if(!((inputValue >= 65 && inputValue <=  90) ||  // A-Z
             (inputValue >= 97 && inputValue <= 122) ||  // a-z
             (inputValue == 32))) {                      // space
            event.preventDefault(); 
        }
    });
});

Test this code here.

Ωmega
  • 42,614
  • 34
  • 134
  • 203
0

Original Answer

As specified in the question, it sounds like you want to block anything other than basic Latin alphabet letters and spaces, which is doable with a pattern attribute - the regex is ^[a-zA-Z ]+$.

Edit 2020-08-19

The question asks specifically about "accented letters", not non-Latin-alphabet characters or non-ASCII characters. As of 2020, and assuming you don't need to support Internet Explorer, this is actually fairly simple to check for in JavaScript.

Explanation

NFD normalization splits apart all diacritics from their base characters. The regex /\p{M}/u matches anything in the Unicode "Mark" category, such as all those diacritics we just split apart.

const hasDiacritics = str =>
  /\p{M}/u.test(str.normalize('NFD'))

// tests
;[
  'Joao Silva',
  'Pedro',
  'Fabio Duarte',
  'João Silva',
  'Pedro Camões',
  'Fábio Duarte',
  'Αρσένιος',
  'Αρσενιος',
  'Александра',
  '李晓华',
].forEach(str => {
  console.log(str, hasDiacritics(str))
})

You could use a similar method to strip diacritics:

const stripDiacritics = str =>
  str.normalize('NFD').replace(/\p{M}+/gu, '')


stripDiacritics('ZA̡͊͠͝LGΌ ISͮ̂҉̯͈͕̹̘̱ TO͇̹̺ͅƝ̴ȳ̳ TH̘Ë͖́̉ ͠P̯͍̭O̚​N̐Y̡ H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔̀ͅ')


// => "ZALGΟ IS TOƝy THE PO​NY HE COMES"

Caveats

As pointed out in the article @Stephen P links to in the comment below, this is probably a bad idea. It's worth thinking carefully about whether you want to risk annoying or even offending your users by forcing them to enter something that isn't their real name.

Lionel Rowe
  • 5,164
  • 1
  • 14
  • 27
  • I am _completely_ on-board with what you are saying, and I often cite [Falsehoods Programmers Believe About Names](https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/) ... but this may have been better as a _comment_ on the question. – Stephen P May 22 '18 at 17:33
  • 1
    @StephenP That's possibly true. I'm new to SO, so I'm not exactly sure what the protocol is where you have a comment that contains an answer. I've rephrased it to give more prominence to the answer part and also tailor the answer to fit the question better. – Lionel Rowe May 22 '18 at 19:01
  • I think your edit was the perfect way to handle this. – Stephen P May 22 '18 at 19:54