thesowismine
thesowismine

Reputation: 930

Is it possible/feasible to replace certain characters with <span>[character]</span> as they are typed?

I'd like to have it so that whenever a user types a '#' into the search form, the '#' is styled a specific color.

I assume that the only way to do this would be to replace every instance of that character with a <span class="colorHash"></span> and to then apply the color to the class with css.

Is this possible? Can anyone point me in the right direction?

Upvotes: 0

Views: 58

Answers (1)

Quelklef
Quelklef

Reputation: 2147

One solution would be to have an element that mimics a text input by looking as much like one as possible be placed over the actual input. This mimic would be updated every time the input changes, and include the color-changed hashes. It would have no pointer events, so clicking on it would allow the user to interact with the underlying real input.

Here is a reference implementation. It is by no means perfect, and I do not recommend copying code from it.

Good things:

  • Input data is stored unchanged in an <input> element, so works fine with forms.

Bad things:

  • What is shown is not an actual <input> element, but a mimic. This causes there to be no cursor (bad), and may cause other issues. It means all styling on input[type=text] should be on the mimic, too.
  • Slight input lag.

A slightly different way of doing this would be to have the mimic be invisible, except for the red hashes.

Here is a reference implementation. It is by no means perfect, and I do not recommend copying code from it.

Good things:

  • Removes lag on input
  • Cursor is visible
  • User sees the real input element (good in my book)

Bad things:

  • Red color lags (mostly visible when using the jQuery version of the code)
  • Likely much harder to maintain. The mimic must be positioned to pixel-perfection on top of the real input.

Since this seems to be closer to what you're looking for, I'll include the code for this version here...

This code is by no means perfect, and I do not recommend copying code from it.

<div id="wrapper">
    <input type="text" id="data-input">
    <pre class="text-input-mimic" id="shown-data"></pre>
</div>
#wrapper { position: relative; }
#shown-data {
    /* Stacked in top-left corner */
    position: absolute;
    top: 0;
    left: 0;
    /* Clicking and typing goes through to real input */
    pointer-events: none;
}
.text-input-mimic, input[type=text] {
    border: 1px solid grey;
    width: 250px;
    height: 20px;
    padding: 5px;
    display: inline-block;
    margin: 0;
    font-family: Calibri !important;
    font-size: 16px !important;
}
.text-input-mimic {
    /* Make invisible except for hashes */
    background: none !important;
    border: none !important;
    color: rgba(0, 0, 0, 0);
    /* Pixel-perfect adjustments */
    padding-top: 7px;
    padding-left: 6px;
}
.colored { color: red !important; }

JS (jQ):

$('#data-input').on("change keyup paste", function() {
    let inp = $('#data-input').val();
    let modified = inp.replace(/#/g, '<span class="colored">#</span>');
    $('#shown-data').html(modified);
});

Alternatively, JS (plain):

real  = document.getElementById('data-input');
mimic = document.getElementById('shown-data');

real.addEventListener('input', function() {
    let inputVal = real.value;
    let modified = inputVal.replace(/#/g, '<span class="colored">#</span>');
    mimic.innerHTML = modified;
});

Upvotes: 2

Related Questions