41

I want to convert strings to lower or upper case in JavaScript in the locale I wanted. I think standard functions like toUpperCase() and toLocaleUpperCase() do not satisfy this need. toLocale functions do not behave as they should.

For example, in Safari 4, Chrome 4 Beta, Firefox 3.5.x on my system it converts strings with Turkish characters incorrectly. The browsers respond to navigator.language as "en-US", "tr", "en-US" respectively. But there is no way to get user's Accept-Lang setting in the browser as far as I could found. Only Chrome gives me "tr" although I have configured every browser Turkish locale preferred. I think these settings only affect HTTP header, but we can't access to these settings via JavaScript.

In the Mozilla documentation it says

The characters within a string are converted to ... while respecting the current locale. For most languages, this will return the same as ...

I think it's valid for Turkish, it doesn't differ it's configured as en or tr. In Turkish it should convert "DİNÇ" to "dinç" and "DINÇ" to "dınç" or vice-versa.

Is there any JavaScript library that satisfies this need? I think it should not only converting correctly in user's locale, but also it should support conversion via a locale parameter. Because developers cannot access to user's configured preferred language.

doğukan
  • 23,073
  • 13
  • 57
  • 69
sanilunlu
  • 725
  • 1
  • 6
  • 8
  • You might be interested in following the proposals for potential new SE sites including [Turkish Language & Usage](http://area51.stackexchange.com/proposals/30873/turkish-language-usage?referrer=wKPqNxBBY-xKcrw-ScJbLA2) and [StackOverflow in Turkish](http://area51.stackexchange.com/proposals/34945/stack-overflow-in-turkish?referrer=6DTBHmak2NY7uyvjVsZajA2). – Caleb Dec 27 '11 at 11:44

5 Answers5

104

Coming back to this years later to provide more up to date solution.

There is no need for the hack below,

just use String.toLocaleUpperCase() and String.toLocaleLowerCase()

"dinç".toLocaleUpperCase('tr-TR') // "DİNÇ"

All modern browsers support this now.


[ OLD, DO NOT USE THIS ]

Try these functions

String.prototype.turkishToUpper = function(){
    var string = this;
    var letters = { "i": "İ", "ş": "Ş", "ğ": "Ğ", "ü": "Ü", "ö": "Ö", "ç": "Ç", "ı": "I" };
    string = string.replace(/(([iışğüçö]))+/g, function(letter){ return letters[letter]; })
    return string.toUpperCase();
}

String.prototype.turkishToLower = function(){
    var string = this;
    var letters = { "İ": "i", "I": "ı", "Ş": "ş", "Ğ": "ğ", "Ü": "ü", "Ö": "ö", "Ç": "ç" };
    string = string.replace(/(([İIŞĞÜÇÖ]))+/g, function(letter){ return letters[letter]; })
    return string.toLowerCase();
}

// Example
"DİNÇ".turkishToLower(); // => dinç
"DINÇ".turkishToLower(); // => dınç

I hope they will work for you.

Rúnar Berg
  • 4,229
  • 1
  • 22
  • 38
Serkan Yersen
  • 1,233
  • 2
  • 10
  • 19
  • +1 it works pretty well, i've tested with my firebug, interesting issue, nice approach. – Sinan Dec 05 '09 at 11:21
  • 1
    I have used something like this in my projects: turkishToUpper = function(str) { return str.replace('i','İ').replace('ı','I').toUpperCase(); } Because only the 'i' and 'I' characters are the problem. But I don't know other problems in other languages, you may want to do the case conversion in a specific language. So there should be a library which accepts a locale parameter, but I could not have found one. Thanks for the answer, it also solves the problem for Turkish. – sanilunlu Dec 05 '09 at 18:57
  • 3
    second answer is better I think > http://stackoverflow.com/a/5991351/11374 . because this cannot lower if two or more of the chars are next to each other – spinodal Jan 16 '14 at 13:34
  • 2
    toTurkishUpper and toTurkishLower are more understandable. – hakan Jul 29 '14 at 07:17
  • why double parentheses in regex? – lockedscope May 14 '15 at 12:24
  • use ...replace(/i|ı|ş|ğ|ü|ç|ö/gi,...) instead. the given regex is problematic. if the word has consecutive turkish characters like the word **'girişim'** then it tries to find the **'işi**' from the array which returns UNDEFINED string. – eluleci Apr 26 '17 at 11:19
  • Problem is when the user changes the language settings in the browser than tolocaleupper and lower no longer work. – cerhart May 11 '17 at 13:58
  • Still doesn't work though ! console.log(["Şişli", "Şile", "Silivri"].sort(function(a, b) { return a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase()); })); it simply converts 'ş' to 's', so the output in Chrome and FF is Şile, Silivri, Şişli – Wolf359 Jul 06 '17 at 20:25
  • try adding `tr-TR` to `toLocaleLowerCase` method. all of these work for me btw. "ŞÇĞIİOÖUÜ".toLocaleLowerCase('tr-TR') === "şçğıioöuü" and "şçğıioöuü".toLocaleUpperCase('tr-TR'); === "ŞÇĞIİOÖUÜ" – Serkan Yersen Jul 07 '17 at 00:01
  • there is a bug on `toLocaleUpperCase` and `toLocaleLowerCase` for Turkish 'İ' char. https://bugs.chromium.org/p/v8/issues/detail?id=2196 – t13n Mar 25 '18 at 23:36
27

Thanks for the function. I really liked it. Consecutive Turkish char input results 'undefined' as 'ÇÇ'. Try replacing '/+g' with '/g'. The functions would be:

String.prototype.turkishToUpper = function(){
var string = this;
var letters = { "i": "İ", "ş": "Ş", "ğ": "Ğ", "ü": "Ü", "ö": "Ö", "ç": "Ç", "ı": "I" };
string = string.replace(/(([iışğüçö]))/g, function(letter){ return letters[letter]; })
return string.toUpperCase();
}

String.prototype.turkishToLower = function(){
var string = this;
var letters = { "İ": "i", "I": "ı", "Ş": "ş", "Ğ": "ğ", "Ü": "ü", "Ö": "ö", "Ç": "ç" };
string = string.replace(/(([İIŞĞÜÇÖ]))/g, function(letter){ return letters[letter]; })
return string.toLowerCase();
}
Senol Kulbay
  • 295
  • 3
  • 2
3
String.prototype.tUpper = function(){
   return this.replace(/i/g,"İ").toLocaleUpperCase();
}

String.prototype.tLower = function(){
    return this.replace(/I/g,"ı").toLocaleLowerCase();
}
Ean V
  • 5,091
  • 5
  • 31
  • 39
cihan
  • 31
  • 3
1
    var  a="lişliş lğüğpğp İŞİŞİŞ lşi ĞĞHFGH ÜGFHFHG ühüüüğ üğüğş ş ş Ş  İ i  ılk Ilk";

var s=a.split(' ');

var netice="";

s.forEach(function(g) {
  if (g.length>1)
    netice+=g[0].toLocaleUpperCase('tr')+
      g.slice(1).toLocaleLowerCase('tr')+" "; 
  else
    netice+=g.toLocaleUpperCase('tr')+" ";
});

alert(netice); 
Fatih Topcu
  • 132
  • 2
  • 3
-1

Please look into this small piece of code that can convert to upppercase and lowercase

var manualLowercase = function(s) {
  return isString(s)
      ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
      : s;
};

var manualUppercase = function(s) {
  return isString(s)
      ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
      : s;
};
Juvenik
  • 900
  • 1
  • 8
  • 26
  • 2
    This answer is wrong for the question as stated, as it does not deal with `iışğüçö`, which is specifically what the question is about. You should delete this answer. – toolforger Jul 08 '19 at 06:30