6

I know this question has been replied many times here, but I still haven't got an exact answer.. I need to convert English letters to Persian/Arabic letters by some javascript, but not for the entire page, but only for a div or more. like only for a specific class.

I have come across these codes, but don't know which one are the best to use.

function convert($string) {
    $persian = array('۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹');
    $num = range(0, 9);
    return str_replace($persian, $num, $string);
}

I need exact that source to implement only on one div-class.

For example:

<div class="demo">12345</div> 

should change to

<div class="demo">۱۲۳۴۵</div>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Peter
  • 287
  • 2
  • 5
  • 13

10 Answers10

12

I don't believe either of the code samples you provided are JavaScript, the first is close syntactically, but is missing the range() method and new on the array() definition. The second is Java.

To achieve what you require you could convert the text of each of the HTML elements you want to translate to an array and step through them, checking each character via Regex to see if a number was found. If it was, you can do a simple replacement before joining the array back together. Something like this:

var arabicNumbers = ['۰', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
$('.translate').text(function(i, v) {
  var chars = v.split('');
  for (var i = 0; i < chars.length; i++) {
    if (/\d/.test(chars[i])) {
      chars[i] = arabicNumbers[chars[i]];
    }
  }
  return chars.join('');
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="translate">Dummy text with some 123 numbers in 390981 it.</div>
<div class="translate">Dummy text with some 67898 numbers in 109209734.09 it.</div>

Update - 2020-03

Here's a shorter version of the above logic using ES6 syntax. Note that this will work in all modern browsers. The only place it won't work is in any version of IE.

var arabicNumbers = ['۰', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
$('.translate').text((i, v) => v.split('').map(c => parseInt(c) ? arabicNumbers[parseInt(c)] : c).join(''));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="translate">Dummy text with some 123 numbers in 390981 it.</div>
<div class="translate">Dummy text with some 67898 numbers in 109209734.09 it.</div>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • 2
    Thank you very much, it works like a charm. i should maybe mention that the numbers i gave in my first post isn't arabic, but Persian, but i will edit your post, hopefully its okay. :) – Peter Jan 17 '16 at 17:29
  • 4
    No problem, glad to help. The edit is fine - I guessed the language from your title :) – Rory McCrossan Jan 17 '16 at 17:30
  • mate i figured out a problem about the code. when i load the page it first shows the english numbers, then switch it over to arabic. it goes really fast, but its annoying because its moving from left to right and as a developer I notice it and its really annoying. are there anything to do? – Peter Jan 18 '16 at 00:44
  • Unfortunately not, as the JS code only runs when the HTML is loaded. To stop the original number appearing at all, you would need to make the translation on the server, but that would depend on what language you're using, and how you're storing the data. – Rory McCrossan Jan 18 '16 at 07:48
  • What you could do is hide the content of the div altogether: set the visibility to "hidden" in the css and make it visible from the javascript code only after the transformation is done, so you will not get the nasty effect anymore. – Octav Zlatior Jan 18 '16 at 12:51
  • Hello Rory. thanks for your reply again. I will make it the "reply" but i just removed it as a reply for now just because so other people can se its "unsolved" and hopefully se this. Yes i was thinking exactly like what @OctavZlatior said. Rory is it possible somehow to give me an example to how i add CSS style from my Javascript to the .translate tag? unfortunately my Javascript experience is zero. – Peter Jan 19 '16 at 00:09
  • You can edit it either in a stylesheet (recommended), inline (not recommended) or directly in a style tag (not necessarily bad, but not how people do it usually). You can read about it here: http://www.w3schools.com/html/html_css.asp – Octav Zlatior Jan 19 '16 at 10:42
  • 1
    Or you can accept the man's answer and make another question out of this issue so somebody can answer :) – Octav Zlatior Jan 19 '16 at 10:43
10

for use in React , use this Component

import React, {Component} from "react";


class PersianNumber extends Component {


   render() {
       let en_number = this.props.number.toString();
       let persianDigits = "۰۱۲۳۴۵۶۷۸۹";
       let persianMap = persianDigits.split("");
       let persian_number = en_number.replace(/\d/g, function (m) {
         return persianMap[parseInt(m)];
       });

    return (
        <span>{persian_number}</span>
    )


  }

}


export default PersianNumber

save the file name as : PersianNumber.jsx and use like this :

<PersianNumber number={12365}/>
Ali Zemani
  • 141
  • 1
  • 5
6

You can use convertToPersianNumber function that I have copied from this link and use it as the following code in jQuery

$('.translate').text(function(i, v) {
   return convertToPersianNumber(v)
})

convertToPersianNumber code

var persianDigits = "۰۱۲۳۴۵۶۷۸۹";
var persianMap = persianDigits.split("");

function convertToEnglishNumber(input){
    return input.replace(/[\u06F0-\u06F90]/g, function(m){
        return persianDigits.indexOf(m);
    });
}
function convertToPersianNumber(input){
    return input.replace(/\d/g,function(m){
        return persianMap[parseInt(m)];
    });
}

// tests
console.log(convertToEnglishNumber("۴۳۵"));
console.log(convertToEnglishNumber("۶۲۷۰۱"));
console.log(convertToEnglishNumber("۳۵۴۳"));
console.log(convertToPersianNumber("216541"));
console.log(convertToPersianNumber("16549"));
console.log(convertToPersianNumber("84621"));
fingerpich
  • 8,500
  • 2
  • 22
  • 32
3

To convert numeric characters, you just need to add/subtract the difference between two sets of Unicode characters to the original numbers. Here is an example:

// English to Persian/Arabic
console.log(
'Persian now:',
'12345'.replace(/[0-9]/g, c => String.fromCharCode(c.charCodeAt(0) + 1728))
);

// Persian/Arabic to English
console.log(
'English now:',
'۵۶۷۸۹'.replace(/[۰-۹]/g, c => String.fromCharCode(c.charCodeAt(0) - 1728))
);
user1079877
  • 9,008
  • 4
  • 43
  • 54
1

I think this could help:

    const arabicNumbers = ['۰', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
    const ThirtyNine = 39;
    const convertToArabic = (number) => {
      return String(number).split('').map(char => arabicNumbers[Number(char)]).join('');
    }
    const inArabic = convertToArabic(ThirtyNine);
0

Try to use angularJS version, which has a lot of features,

GitHub - mohebifar/angular-persian: Persian tools for angular.js

<div >{{vm.value | pNumber}}</div>

Notice: this solution is very easy to use, but is based on angularJS.

Ebrahim
  • 1,740
  • 2
  • 25
  • 31
0

in React Native : I created a function that converts number both ways according to the language direction:

import React from 'react';
import {I18nManager} from 'react-native';
const isRTL = I18nManager.isRTL; //check app direction

export function NumberConverter(number){    
    if(!isRTL){  
        //english language
        const digit = (number.toString()).replace('.', ',')
        const id= '0123456789';
        return (digit.replace(/[۰-۹]/g, function(w){
            return id[w]}))
    } else{
        //Arabic Language
        const digit = (number.toString()).replace('.', ',')
        var id = '٠١٢٣٤٥٦٧٨٩';
        return (digit.replace(/[0-9]/g, function (w) {
            return id[w]}))
    
    }
}

Then use it like this:

        import {NumberConverter} from './NumberConverter';
        NumberConverter(10)
         
0

You can try some function like below:

translateFunction: function(number){
      var looper = ['۰','۱','۲','۳','۴','۵','۶','۷','۸','۹'];
      var englishDigits = Array.from(String(number), Number);
      var farsiDigits = [];
      englishDigits.forEach(digit => {
        farsiDigits.push(looper[digit]);
      });
      console.log(farsiDigits.join(""));
    }

And the steps we have are:

  1. We define an array called looper to use its items to replace our English digits.

  2. We convert our string argument (like '123') to an array. As far as I know, we cannot use forEach on numbers nor strings, so we should convert it to an array.

  3. We define an empty array for getting our final result.

  4. The most important part, we iterate through our array and push every number from it into the farsiDigits, according to how it can be the index of looper items.

I know that this code can be written a lot better, but it was something that came to my mind now and I hope it's gonna help!

NavidMnzh
  • 169
  • 3
  • 17
0

In VUE with the Custom Filter incase any one needed.

    Vue.filter('NumToPer', function (input) {
        return input.replace(/[0-9]/g, c => String.fromCharCode(c.charCodeAt(0) + 1728));
        
**OR USE THIS ONE**
        // var persianDigits = "۰۱۲۳۴۵۶۷۸۹";
        // var persianMap = persianDigits.split("");
    
        // return input.replace(/\d/g, function(m) {
        //     return persianMap[parseInt(m)];
        // });
    })
Nasser Ali Karimi
  • 4,462
  • 6
  • 34
  • 77
0

It's for your Font. You can change your font to a persian font for example 'BYekan' for your div.

MoHaMMaD
  • 19
  • 3