5

I want to replace Vertical Bar (|) with Devanagari Danda (।) as soon as it is typed in textarea using JavaScript.

First I tried the solution given on How to change characters typed in Firefox. But it adds the character to the end only.

So, I followed the solution given on http://www.jsfiddle.net/EXH2k/6/ which was suggested by Tim Down on Changing the keypress and also on show different keyboard character from the typed one in google chrome, but it doesn't work for me (neither in Firefox nor in IE 10).

Code:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link type="text/css" rel="stylesheet" href="stylesheet.css" />
    <script type="text/javascript">
        function transformTypedChar(charStr) {
            return charStr == "|" ? "।" : charStr;
        }

        function getInputSelection(el) {
            var start = 0, end = 0, normalizedValue, range,
            textInputRange, len, endRange;

            if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
                start = el.selectionStart;
                end = el.selectionEnd;
            } else {
                range = document.selection.createRange();

                if (range && range.parentElement() == el) {
                    len = el.value.length;
                    normalizedValue = el.value.replace(/\r\n/g, "\n");

                    // Create a working TextRange that lives only in the input
                    textInputRange = el.createTextRange();
                    textInputRange.moveToBookmark(range.getBookmark());

                    // Check if the start and end of the selection are at the very end
                    // of the input, since moveStart/moveEnd doesn't return what we want
                    // in those cases
                    endRange = el.createTextRange();
                    endRange.collapse(false);

                    if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
                        start = end = len;
                    } else {
                        start = -textInputRange.moveStart("character", -len);
                        start += normalizedValue.slice(0, start).split("\n").length - 1;

                        if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
                            end = len;
                        } else {
                            end = -textInputRange.moveEnd("character", -len);
                            end += normalizedValue.slice(0, end).split("\n").length - 1;
                        }
                    }
                }
            }

            return {
                start: start,
                end: end
            };
        }

        function offsetToRangeCharacterMove(el, offset) {
            return offset - (el.value.slice(0, offset).split("\r\n").length - 1);
        }

        function setInputSelection(el, startOffset, endOffset) {
            el.focus();
            if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
                el.selectionStart = startOffset;
                el.selectionEnd = endOffset;
            } else {
                var range = el.createTextRange();
                var startCharMove = offsetToRangeCharacterMove(el, startOffset);
                range.collapse(true);
                if (startOffset == endOffset) {
                    range.move("character", startCharMove);
                } else {
                    range.moveEnd("character", offsetToRangeCharacterMove(el, endOffset));
                    range.moveStart("character", startCharMove);
                }
                range.select();
            }
        }

        $("#inputTextArea").keypress(function (evt) {
            if (evt.which) {
                var charStr = String.fromCharCode(evt.which);
                var transformedChar = transformTypedChar(charStr);
                if (transformedChar != charStr) {
                    var sel = getInputSelection(this), val = this.value;
                    this.value = val.slice(0, sel.start) + transformedChar + val.slice(sel.end);

                    // Move the caret
                    setInputSelection(this, sel.start + 1, sel.start + 1);
                    return false;
                }
            }
        });
    </script>
</head>
<body>
    <textarea name="input" id="inputTextArea" rows="10"></textarea>
</body>
</html>
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
jyotesh
  • 330
  • 5
  • 17

2 Answers2

5

That's pretty easy. Throw away your code with the newlines handling etc. and just do that:

$(document).ready(function() {
    $('#my-input').on('input', function() {
        var $input = $(this),
            curVal = $input.val();
        var cursorPos = curVal.slice(0, this.selectionStart).length;

        $input.val(curVal.replace(/[|]/g, '।'));
        this.setSelectionRange(cursorPos, cursorPos);
    });
});

Working example: JSFiddle

schlingel
  • 8,560
  • 7
  • 34
  • 62
1

I want to replace Vertical Bar (|) with Devanagari Danda (।) as soon as it is typed in textarea using javascript.

Since you want to replace a character as soon as it is typed, this may the simplest option:

$('#inputTextArea').on("keyup", function(e) {
    $(this).val($(this).val().replace(/[|]/g, "।"));
});

I noticed that although you haven't tagged jQuery, you are using jQuery in your code. Hence a jQuery based solution.

A quick fiddle: http://jsfiddle.net/THEre/

Abhitalks
  • 27,721
  • 5
  • 58
  • 81
  • +1 because I took the /[|]/g pattern from you. But your code doesn't handles the cursor pos. – schlingel Oct 03 '13 at 08:42
  • 1
    @schlingel yes of course, I dashed out a quick and dirty solution for him to at least give him a direction. Yours is a more complete solution and I had already +1 to you. :) – Abhitalks Oct 03 '13 at 08:44