12

In my html page, I need to make my text input accept a specific set of letters. I do that by catching the keypressed event and checking that the entered character is valid.

Those allowed characters are both taken from english that is written from left to right, and from a few other languages that are written from right to left. Each word of the input can be a mix of both english and arabic, hebrew letters.

I need to make the text box display the text written from right to left (same behavior for hebrew or arab to apply to english) - for example if I write down -

A

B

א

ב

C

D

Y

I want it to be presented exactly in this order from right to left.

Setting the "style:dir=rtl" doesn't solve it, it just present the text to be written from right to left, but doesn't actually change the order of the English characters to be presented as I need.

rtl result is this:

B

A

א

ב

Y

D

C

What is the best way to do so?

Edit:

It seems like this addresses my problem : Right to left Text HTML input although the solution is not explained to details as I'd hope to get.

Community
  • 1
  • 1
  • 3
    Possible duplicate of [Right to left Text HTML input](http://stackoverflow.com/questions/7524855/right-to-left-text-html-input) – ElChupacabra Sep 25 '16 at 19:26
  • Where is your code, Peter? – Ricky Sep 25 '16 at 20:05
  • There isn't really a detailed answer there, already saw that question. @Ricardo I have not implemented such thing yet. Trying to figure out a way –  Sep 25 '16 at 21:01

5 Answers5

10

Set your textbox style to this:

style="direction:rtl; unicode-bidi:bidi-override;"

Why?

When you're just setting directionality (using direction: rtl), you still have separate "directional runs" within that long text, each with its own rendering behavior. The "AB" part is a left-to-right run and that's why you see it rendered as an English word with the B to the right of the A.

Adding unicode-bidi: bidi-override tells the browser to forget about those separate runs and simply render all characters one after the other from right to left.

[Added to address potential client applications using the data]

For client applications that use this data, you can provide the string itself in a way that will force them to display it correctly even if those client apps are out of your control.

Assuming the client apps access the data using an API or service of some sort (meaning you don't let them access your database directly) then you can add a Unicode control character called Right-to-Left Override (RLO) to the beginning of the string, before sending it to the client.

The RLO character code is \u202E so following your example above, the resulting string you would return to your client would be:

\u202E

A

B

א

ב

C

D

Y

Most web browsers and operating systems respect BiDi control characters and apply the correct BiDi rendering logic. So when a client app outputs that string to the UI, the underlying rendering engine should display the string as you intended.

Note: Adding a unicode character by its hex code to a string may vary depending on your platform and programming language.

Atzmon
  • 1,258
  • 1
  • 7
  • 15
  • That worked really good on the view, but is it possible to save the text as it is displayed in the backend as well (and in our database), and not just make it displayed correctly? –  Sep 28 '16 at 18:44
  • 1
    The text is always saved as a string of characters in the database. How it is rendered depends on the client displaying it. The database just stores the bytes: A then B then א then ב etc. There is no "display" in the database itself. Your database management UI has some rendering logic of its own, a web browser has its own and so does any other client you may find or build yourself. The database itself only has data. – Atzmon Sep 28 '16 at 19:01
  • I understand what you're saying, but that data will be sent to different systems, which my team is not responsible for developing, and that text needs to be displayed like this on their system as well. Is it better to force them all to set the view to support this kind of display, or instead save the text in a way that different systems developers won't have to treat that text in a special manner? –  Sep 28 '16 at 20:18
  • 1
    I would keep the raw data in my database as pure as possible and handle display logic at the UI layer or as close as possible to it. If your clients only need to display this string (not edit and send it back to you) you can either ask them to apply the same style or you can inject a Right-to-Left Override (LRO) control character at the beginning of the string. I will update my answer to include this. – Atzmon Sep 28 '16 at 22:10
  • By adding that unicode symbol before the strings, the text that is sent to different system is presented as question mark. Does it mean the other systems encoding is different? If so, how do you suggest I handle this? –  Oct 10 '16 at 14:42
  • Is there a RLO character that supports windows 1255 encoding as well? –  Oct 10 '16 at 15:51
  • RLO is a Unicode control character. Windows-1255 is a codepage from the days before Unicode (when you only had 255 characters all together). If the systems consuming your data are web based, follow my first suggestion and have them apply the bidi css styles to the control displaying the text. Otherwise they will need to switch to UTF-8 encoding, which is usually not too hard to do and has other benefits. Yes, both options will require a little effort from those consuming systems. – Atzmon Oct 10 '16 at 20:11
3

You can do this with js

<div id="id_of_content"></div>

<script type="text/javascript">
        // if updating the div in realtime then try using keypress listener to call this function
        function(id_of_content) {
            var text = $('#'+id_of_content).text();
            var words = text.split(' ');
            var result = '';
            for(var j=0;j<words.length;j++) {
                if(/[^a-zA-Z]/.test(words[j])) {
                    var temp = words[j];
                    var rev_word = '';
                    for(var i=0;i<temp.length;i++) {
                        rev_word += temp[temp.length-i-1]
                    }
                result += rev_word;
                }
                else {
                    result += words[j];
                }
            }
        $('#'+id_of_content).text(result);
       }
</script>

hope this helps

Patrik
  • 2,591
  • 1
  • 18
  • 33
Sri Kanth
  • 151
  • 8
  • Isn't that code reversing the entire text? Only the left to right characters need to be reversed in order for me to achieve my goal. Meaning, english letters combinations need to be reversed, when hebrew or arab chars should stay the same –  Sep 25 '16 at 21:30
  • So i am assuming the sentence that may have entered have both english words or hebrew or arab chars. i have updated the code to reverse words containing alphabets only. – Sri Kanth Sep 25 '16 at 21:42
  • It is even more complicated than that.. Each word can contain both Arab/Hebrew and English characters all mixed up. I guess I need to find substrings of English characters in each word and reverse only that part of the word. Difficult stuff –  Sep 25 '16 at 21:50
2

Well, I was going through some blogs and sample related to RTL and came up with below working sample.

In this code switching option is there you can try both LTR and RTL on clicking of this button- enter image description here

JSfiddle: http://jsfiddle.net/vikash2402/ammajhy3/3/

Below is the working code for it.

// Jquery, BS3 & Awesome
$('#rtl-button').click(

function () {
    var src = 'http://cdnjs.cloudflare.com/ajax/libs/bootstrap-rtl/3.2.0-rc2/css/bootstrap-rtl.min.css';
    if ($(this).attr('data-direction') == 'ltr') {
        $('head').append('<link href=' + src + ' rel="stylesheet" id="bootstrap-rtl" />');
        $(this).attr('data-direction', 'rtl');
    } else { // by default we load bootstrap-rtl 
        $('head link[href="' + src + '"]').remove();
        $(this).attr('data-direction', 'ltr');
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link href="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-rtl/3.2.0-rc2/css/bootstrap-rtl.min.css" rel="stylesheet"/>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"/>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>


<div class="container">
    <h3>Testing bootstrap RTL css overwrite</h3>
<nav class="navbar navbar-default" role="navigation">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span>
 <span class="icon-bar"></span>
 <span class="icon-bar"></span>
 <span class="icon-bar"></span>

            </button> <a class="navbar-brand" href="#"><span class="glyphicon glyphicon-home"></span> Home</a>

        </div>
        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li><a href="#">Welcome</a></li>
                <li><a href="#"><span class="glyphicon glyphicon-phone-alt"></span> Contact us</a></li>
                <li><a href="#">Career</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li>
                    <form class="navbar-form" role="search">
                        <div class="form-group">
                            <input type="text" class="form-control" placeholder="Search" />
                        </div>
                        <button type="submit" class="btn btn-default">Submit</button>
                    </form>
                </li>
            </ul>
        </div>
        <!-- /.navbar-collapse -->
    </div>
    <!-- /.container-fluid -->
</nav>
</div>
<a href="#" class="btn btn-default" title="" id="rtl-button" data-direction="ltr"><span class="glyphicon glyphicon-indent-right"></span> RTL</a>

Hoping this will help you :)

Vikash Pandey
  • 5,073
  • 6
  • 36
  • 41
2

you can use this function

function reverseLTR(text) {
    var ltrChars = 'A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF' + '\u2C00-\uFB1C\uFDFE-\uFE6F\uFEFD-\uFFFF';
    var r = new RegExp("[" + ltrChars + "]?", 'g');
    var ltrMatches = text.match(r);
    var arr = [];
    var insertPlace=0;
    for (var i = 0; i < text.length; i++) {
        if (!ltrMatches[i].length) {//its rtl character
            arr.splice(i, 0, text[i]);
            insertPlace=i+1;
        }
        else arr.splice(insertPlace, 0, text[i]);
    }
    return arr.join("");
}
var text="ABאבCDY";
document.body.innerHTML=text+" converted to : "+reverseLTR(text);
fingerpich
  • 5,890
  • 2
  • 20
  • 28
1

Try the <bdo> tag

<p>left-to-right.</p>

Result: left-to-right.

<p><bdo dir="rtl">right-to-left.</bdo></p>

Result: .tfel-ot-thgir

Herbs
  • 127
  • 2
  • 8