Skip to content
Advertisement

How to use straight and smart quotes in auto-replace script for textarea?

I’m really stuck again on how to properly combine these lines to auto-replace straight quotes into smart ones in the text area.

It was working earlier, however after I added a line to fix the cursor going at the end after replacing a character.

Here’s what is currently looks like:

    var area = document.getElementById("textarea1");

    var getCount = function (str, search) {
        return str.split(search).length - 1;
    };

    var replaceText = function (search, replaceWith) {
        if (area.value.indexOf(search) >= 0) {
            var start = area.selectionStart;
            var end = area.selectionEnd;
            var textBefore = area.value.substr(0, end);
            var lengthDiff = (replaceWith.length - search.length) * getCount(textBefore, search);
            area.value = area.value.replace(search, replaceWith);
            area.selectionStart = start + lengthDiff;
            area.selectionEnd = end + lengthDiff;
        }
    };

    area.addEventListener("keypress", function (e) {
        setTimeout(function () {
            replaceText(" ,", ",")
            replaceText(" ;", ";")
            replaceText(" .", ".")
            replaceText("  ", " ")
            replaceText("--", "—")
            replaceText(/(^|[-u2014s(["])'/g, "$1u2018")
            replaceText(/'/g, "u2019")
            replaceText(/(^|[-u2014/[(u2018s])"/g, "$1u201c")
            replaceText(/"/g, "u201d");
        }, 0)
    });
<textarea id="textarea1" cols="40" rows="8"></textarea>

Commas, semicolon, period, em dash, and double spaces is working already.But it’s not for the quote marks. What can I do to correct these regex lines?

Here’s exactly where I’m stuck:

replaceText(/(^|[-u2014s(["])'/g, "$1u2018")
replaceText(/'/g, "u2019")
replaceText(/(^|[-u2014/[(u2018s])"/g, "$1u201c")
replaceText(/"/g, "u201d");

Thanks in advance

Advertisement

Answer

In your replaceText you need to distinguish when you pass a regex or a string. .indexOf() does not accept a regex.

Moreover, I would suggest to change the keypress event with the input one.

The snippet:

window.addEventListener('DOMContentLoaded', function(e) {
  var area = document.getElementById("textarea1");

  var getCount = function (str, search) {
      return str.split(search).length - 1;
  };

  var replaceText = function (search, replaceWith) {
      if (typeof(search) == "object") {
          area.value = area.value.replace(search, replaceWith);
          return;
      }
      if (area.value.indexOf(search) >= 0) {
          var start = area.selectionStart;
          var end = area.selectionEnd;
          var textBefore = area.value.substr(0, end);
          var lengthDiff = (replaceWith.length - search.length) * getCount(textBefore, search);
          area.value = area.value.replace(search, replaceWith);
          area.selectionStart = start + lengthDiff;
          area.selectionEnd = end + lengthDiff;
      }
  };

  area.addEventListener("input", function (e) {
      replaceText(" ,", ",");
      replaceText(" ;", ";");
      replaceText(" .", ".");
      replaceText("  ", " ");
      replaceText("--", "—");
      replaceText(/(^|[-u2014s(["])'/g, "$1u2018");
      replaceText(/'/g, "u2019");
      replaceText(/(^|[-u2014/[(u2018s])"/g, "$1u201c");
      replaceText(/"/g, "u201d");
  });
});
<textarea id="textarea1" cols="40" rows="8"></textarea>
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement