Convert English numbers to Persian/Arabic only for a specified div - javascript
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>
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>
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}/>
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"));
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))
);
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);
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.
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)
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:
We define an array called looper to use its items to replace our English digits.
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.
We define an empty array for getting our final result.
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!
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)];
// });
})
It's for your Font. You can change your font to a persian font for example 'BYekan' for your div.
Related
how to truncate output values in Nerdamer
I am using nerdamer.solve to solve roots but the roots are long and not truncated. I wanted to get truncated values upto 4 decimal places. How can I achieve this? I am using the following code to solve and display output in html: var r = nerdamer.solve(`1 - ${a} * x^(${p}) + ${b}`, 'x'); document.getElementById("polesAns").innerHTML= r.toString(); The folllowing is output: [(138655807/135201312)*i+49385501/48155102,(-138655807/135201312)*i+49385501/48155102,(58886197/57419096)*i-49385501/48155102,(-58886197/57419096)*i-49385501/48155102,-560373381/386371730,172668482/119053157,(145619303/100403024)*i-5753750945848186/10000000000000000000000000000000,(-560373381/386371730)*i-5753750945848186/10000000000000000000000000000000] There is no division performed also. I tried the solution posted here: How to use .toFixed() (or any alternative) on Nerdamer.solve solutions? But how can I do this with my code? I tried the following: var value = `1 - ${a} * x^(${p}) + ${b}`; var toFixed = function(value, n) { var img = Number(nerdamer.imagpart(value).text()).toFixed(n); var real = Number(nerdamer.realpart(value).text()).toFixed(n); // Format the number assuming i denotes imaginary in your case var formatted = ''; if(real !== '0.0000') { formatted += real; } if(img !== '0.0000') { // Put the plus sign betweent the real and imaginary if(img.charAt(0) !== '-' && formatted) { formatted += '+'; } // Assuming you're using i and not j for instance formatted += img+'i'; } return formatted; }; sol_raw = this.nerdamer.solve(value,'s'); xs = this.nerdamer(sol_raw.toString()).each(function(solution) { roundedSolutions.push(toFixed(solution, 4)); }); this.setState({ solution: roundedSolution.join(''), equation:value}) document.getElementById("polesAns").value = solution.toString(); I don't understand the this.setState() part , should i declare sol_raw and xs as var? Also the substitution of variable is used in the my above root equation from advice here javascript Solving equation with subsitution of variable value thank you
Replace accented characters with their unaccented equivalent
I have a text field that can not allow accents. I was using this code: <input type="text" onkeyup="value=value.replace(/[^0-9a-zA-Z' ']/g,'')"> But rather than blocking the characters, I need them to be replaced for example by typing Ç change to C I found a function and hes working, but when I type a dot appears the letter A Can you help me? <script>function retiraAcento(palavra,obj){ com_acento = 'áàãâäéèêëíìîïóòõôöúùûüçÁÀÃÂÄÉÈÊËÍÌÎÏÓÒÕÖÔÚÙÛÜÇ<,>´`-,*/~'; sem_acento = 'aaaaaeeeeiiiiooooouuuucAAAAAEEEEIIIIOOOOOUUUUC '; nova=''; for(i=0;i<palavra.length;i++) { if (com_acento.search(palavra.substr(i,1))>=0) { nova+=sem_acento.substr(com_acento.search(palavra.substr(i,1)),1); } else { nova+=palavra.substr(i,1); } } obj.value = nova;}</script><input type="text" onKeyUp="javascript:retiraAcento(this.value, this);">
I didn't dig into it enough to see why the . was being replaced with A, but this version doesn't have that behaviour. It doesn't work exactly the same and it operates on the whole string, but that likely isn't a problem unless it's used in a large textfield, in which case it could be optimised other ways. const com_acento = 'áàãâäéèêëíìîïóòõôöúùûüçÁÀÃÂÄÉÈÊËÍÌÎÏÓÒÕÖÔÚÙÛÜÇ<,>´`-,~'; const sem_acento = 'aaaaaeeeeiiiiooooouuuucAAAAAEEEEIIIIOOOOOUUUUC '; function retiraAcento(string) { return string .split('') .map(char => { const charIdx = com_acento.indexOf(char) if (charIdx !== -1) { return sem_acento[charIdx] } return char }) .join('') } function replaceCharOnChange(evt) { event.target.value = retiraAcento(evt.target.value) } document.querySelector('input').addEventListener('keyup', replaceCharOnChange) Apologies it's half rewritten in english! I'd also look into using another data structure than the two same-length strings. The simplest would be an object lookup table eg: {á: 'a', ç: 'c', ...} but there's other ways you could go about it too
remove all Decimals and single numbers from array / string
so my script generates a big blob of "Piano Notes" which are similar to... var songNotes = "..."; the large Piano notes content and my problem is between the piano notes which i need [also in the fiddle] there are empty ",," and decimal numbers.. so i cant figure out how to remove the empty ,, and decimals as big as "1.0416666666642413,0.625,0,g3,1498.9583333333358,,0,c3,1.0416666666642413,0.625,0,c3" and i want them removed except the the needed words which are var theRightOnes = "s2,as2,cs3,ds3,fs3,gs3,as3,gs3,cs4,ds4,fs4,cs3,as4,gs4,ds5,a2,cs4,b2,c3,a3,ds4,b3,c4,as3,gs2,e3,c3,c4,cs3,ds3,a4,fs3,gs3,as3,g3,f3,b4,c5,a3,d4,as2,e4,g4,d3,b3,b2,f4,a2,d4,e4,cs5,gs1,e2,c2,c3,cs2,ds2,a3,fs2,gs2,as2,g2,f2,b3,c4,a2,d3,as1,e3,g3,d2,b2,b1,f3,a1,d5,e5"; so can anyone give me a clue on how this can be accomplished? if anyone needs more info then i am ready oblige to do so.. Regards - Adarsh Hegde
var notesArr = songNotes.split(","); var len = notesArr.length; while(len--) { if(!notesArr[len] || !isNaN(parseInt(notesArr[len], 10))) { notesArr.splice(len, 1); } } songNotes = notesArr.join(",");
I think you want to remove all the numbers from notes. You can say like bellow var notes = songNotes.split(",").filter(function(note){ return isNaN(note); }); console.log(notes);
You can use Array.filter (see MDN) to weed out unwanted values: var wantedNotes = songNotes.split(',') .filter(function (v) { return isNaN(+v) && v.trim().length }); jsFiddle
just use regular expression,like this: var a = "1.0416666666642413,0.625,0,g3,1498.9583333333358,,0,c3,1.0416666666642413,0.625,0,c3"; console.log(a.replace(/\b(\d+(\.\d+)?),+/g,""));
Javascript (or jQuery) string replacement
So, I have strings pulled from a JSON array like this: Hg22+ CO32- Al3Cl23+ These numbers need to be superscript or subscript, with rules. It's only numbers 0-9, and if that number has a plus or minus after it, it needs to be superscript, meaning I need to change the string to <sup>3+</sup>. All other numbers, if they haven't been superscripted, need to be subscripted. Here are a few examples of what I need: C12H22O11 (s, sucrose) = <sub>1</sub><sub>2</sub>H<sub>2</sub><sub>2</sub>O<sub>1</sub><sub>1</sub> (s, sucrose) Al3Cl23+ = Al<sub>3</sub>Cl<sub>2</sub><sup>3+</sup> Hg22+ = Hg<sub>2</sub><sup>2+</sup> I can do it, but very sloppily. I am really open to a good way to change string like above. If anyone can help out I'd be really appreciative! Thanks!
Easy. var result = input.replace(/\d([+-]?)/g,function(match,plus) { var s = plus ? "sup" : "sub"; return "<"+s+">"+match+"</"+s+">"; }); Done.
Slightly modified from #Niet the Dark Absol's answer var tests = ['Hg22+', 'CO32-', 'Al3Cl23+','C12H22O11 (s, sucrose)']; function chemize(input) { return input.replace(/\d([\+\-]?)/g,function(match,plus) { var s = plus ? "sup" : "sub"; return "<"+s+">"+match+"</"+s+">"; }); } for(var z in tests) { var test = tests[z]; console.log('"' + test + '" --> ' + chemize(test) ); } Output: "Hg22+" --> Hg<sub>2</sub><sup>2+</sup> "CO32-" --> CO<sub>3</sub><sup>2-</sup> "Al3Cl23+" --> Al<sub>3</sub>Cl<sub>2</sub><sup>3+</sup> "C12H22O11 (s, sucrose)" --> C<sub>1</sub><sub>2</sub>H<sub>2</sub><sub>2</sub>O<sub>1</sub><sub>1</sub> (s, sucrose)
How to achieve String Manipulation in JavaScript
The problem statement is like this: I have a contract. On renewal on every month the contract name should append with renewal identifier. For example at beginning the name is myContract then on first renewal name should be myContract-R1, next renewal name should be myContract-R2 and so on.. On each renewal, the name should automatically change. So in Jquery how can I do this?
This is a JavaScript question, not a jQuery question. jQuery adds little to JavaScript's built-in string manipulation. It sounds like you want to take a string in the form "myContract" or "myContract-Rx" and have a function that appends "-R1" (if there's no "-Rx" already) or increments the number that's there. There's no shortcut for that, you have to do it. Here's a sketch that works, I expect it could be optimized: function incrementContract(name) { var match = /^(.*)-R([0-9]+)$/.exec(name); if (match) { // Increment previous revision number name = match[1] + "-R" + (parseInt(match[2], 10) + 1); } else { // No previous revision number name += "-R1"; } return name; } Live copy
You can use a regular expression for this: s = s.replace(/(-R\d+)?$/, function(m) { return '-R' + (m.length === 0 ? 1 : parseInt(m.substr(2), 10) + 1); }); The pattern (-R\d+)?$ will match the revision number (-R\d+) if there is one (?), and the end of the string ($). The replacement will return -R1 if there was no revision number before, otherwise it will parse the revision number and increment it.
how you get renewal number? Calculating from date, or getting from database? var renewal = 1, name = 'myContract', newname = name+'R'+renewal; or maybe like $(function(){ function renew(contract){ var num_re = /\d+/, num = contract.match(num_re); if (num==null) { return contract+'-R1'; } else { return contract.replace(num_re,++num[0]); } } var str = 'myContract'; new_contract = renew(str); // myContract-1 new_contract = renew(new_contract); // myContract-2 new_contract = renew(new_contract); // myContract-3 }); Here jQuery can't help you. It's pure JavaScript working with strings P.S. I have here simple reg exp, that's not concrete for your example (but it works). Better use reg-exp from example of T.J. Crowder