3

I am using toLowerCase() to convert a content editable div to lowercase. But it's also reversing the text! Can someone please tell me why this is happening?

$(document).ready(function() {
  $('#user').bind('keyup', function() {
    $(this).text($(this).text().toLowerCase());
  });
});
#user {
  background: #f1f1f1;
  padding: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="user" contenteditable="true"></div>

Fiddle: https://jsfiddle.net/professorsamoff/8zyvc202/3/

Thanks, Tim

Tim Samoff
  • 94
  • 11

4 Answers4

8

It has to do with the quirkiness of browsers... When the text is being set, the cursor moves to the beginning of the editable area.

A less quirky solution might be to convert to lowercase using CSS while the user is typing. Then, if you want to go above and beyond, do the actual conversion in JavaScript on the blur event.

$(document).ready(function() {
  $('#user').blur(function() {
    console.log('Converting from '+$(this).text()+' to '+$(this).text().toLowerCase());
    $(this).text($(this).text().toLowerCase());
  });
});
#user {
  background: #f1f1f1;
  padding: 1em;
  text-transform:lowercase;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="user" contenteditable="true"></div>
dana
  • 17,267
  • 6
  • 64
  • 88
  • In my tests, the blur() function isn't actually converting the text, though… I understand blur()'s job, but it doesn't seem to be working in this case…? – Tim Samoff Mar 23 '17 at 04:46
  • Which browser is this failing in? I did a quick test on Edge, Chrome, and Firefox. – dana Mar 23 '17 at 04:48
  • All browsers. Keep in mind that this test will always "appear" to work with the CSS in place. – Tim Samoff Mar 23 '17 at 04:51
  • Ah, hold on… I see that the text is, in fact, converted when the div loses focus. How then, do I convert the text if the div retains focus? – Tim Samoff Mar 23 '17 at 04:53
  • I am kind of curious about the use case here. If you must do the actual conversation while the user is typing, then @OmarAlEisa's answer below is probably your best bet. Personally, I think the CSS solution feels cleaner when typing (the cursor doesn't flicker). But if the ultimate goal is to lowercase the text, then using blur() does eventually achieve this. If you are posting something to the server, you could do the conversion there as well. – dana Mar 23 '17 at 14:23
  • This is for a game that gathers user input in the form of an interactive retro-style terminal. And while I know of several different ways to do what I'm doing, my current method of gathering user input is to do so in lowercase (to avoid a slew of variable designations, etc.). So what I'm trying to do is gather the text in lowercase and process it so that users can type in both upper- and lowercase (e.g., my iPhone always auto-capitalizes the first letter of any text input). So, plain styling doesn't help much in this case. – Tim Samoff Mar 23 '17 at 14:56
2

Can be achieved using css

#user {
  background: #f1f1f1;
  padding: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="user" contenteditable="true" style="text-transform: lowercase"></div>
Geethu Jose
  • 1,953
  • 2
  • 14
  • 30
-1
Please try the following:

$(document).ready(function() {
    $('#user').bind('keyup', function() {
        $(this).val($(this).val().toLowerCase());
    });
});
Koby Douek
  • 16,156
  • 19
  • 74
  • 103
-1

This is a very interesting one. toLowerCase() is not reversing the text (you can verify this be removing the function and you will see that the text is still being reversed). Whats really happening is that the cursor position moves to the beginning after placing the new text.

As mentioned in other answers, a simple way to solve this would be to do it via css. But if you need to do it by javascript only, check out this solution. We’re manually moving the cursor position to the end after placing the new text.

The implementation of the placeCaretAtEnd function was inspired by this answer.

$(document).ready(function() {
  $('#user').bind('keyup', function() {
    $(this).text($(this).text().toLowerCase());
    placeCaretAtEnd(this);
  });
});

function placeCaretAtEnd(el) {
    el.focus();
    if (typeof window.getSelection != "undefined"
            && typeof document.createRange != "undefined") {
        var range = document.createRange();
        range.selectNodeContents(el);
        range.collapse(false);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (typeof document.body.createTextRange != "undefined") {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.collapse(false);
        textRange.select();
    }
}
#user {
  background: #f1f1f1;
  padding: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="user" contenteditable="true"></div>
Community
  • 1
  • 1
Omar AlEisa
  • 174
  • 8
  • Not sure why you got voted down on this — it is, in fact, the answer for me. Thank you! – Tim Samoff Mar 23 '17 at 14:59
  • 2
    This approach doesn't let you use the left arrow to edit what you typed, and if you click in the middle and start to type, your caret gets sent to the end, not where it was before. The css solution posted by dana is the most accessible. But if you really want that transition effect, really should be checking for the keycode, and tracking the caret position. If I understand your case correctly, if it's for a game, if you need the information lowercase for something that uses the info, just send a copy of the text to the callback with lowercase() applied on it rather than directly on the input. – Ultimater Mar 23 '17 at 16:24
  • Ah, right… That is a problem. Of course, a simple conditional could take care of that, although it wouldn't handle Cmd/Ctrl+A for text selection. And, yes, I like the "sending in lowercase" option — this issue was just bugging me terribly. – Tim Samoff Mar 24 '17 at 14:54