Every time I type a character in an input field, I parse the expression so that I get:
- An array of tokens, i.e., tokenArray=[2, *, COS, (, 4, )]
- A corresponding array of token types, i.e., tokenType=[NUMBER, OPERATOR, FUNCTION, (, NUMBER, )]
I need to style each token (for instance assigning a different color to each token) based on its respective token type.
I have been able to easily style a dynamic copy of the input text in a different <div>
(not the input text itself, which is what I am asking for help) as follows:
JavaScript:
function processExpression() {
var userInput = document.getElementById('inputText').value;
var resultOutput = parse(userInput); //this generates the two arrays described above
for (i in tokenArray)
newHTML += "<span style='color: " + colorMap[ tokenType[i] ] + " '>" + tokenArray[i] + "</span>";
document.getElementById('styledExpression').innerHTML = newHTML;
}
HTML:
<input type="text" id="inputText" value="" placeholder="Type expression" size="40"
onKeyDown="processExpression();"
onKeyUp="processExpression();"/>
<div id="styledExpression" value=""></div>
How can I style the input text directly in the input field where I type? Any JavaScript solution?
UPDATE
Tim's answer to the question replace innerHTML in contenteditable div provides some good help.
How would you modify http://jsfiddle.net/2rTA5/2/ to solve for when at every keydown, one reparses the entire editable? For example, imagine you type "=if(AND(3=2,A1:A4,OR(0,1)),5,6)" and, at every keydown the editable gets programmatically re-written (see token description above) and I lose the cursor.
How can this solution ignore the type of token or character or node and simply save and restore the absolute cursor (from the beginning of the ) position that was before the keydown?
as Matt said,
<input>
s don't support styling content. However, one possible solution could be to use a second<span>
that will contain the input's value, and show the styled content here. If that's not acceptable, then usecontenteditable
as Matt suggested.You can sort of hack styling behind it if it's just for unimportant aesthetics.
<input>
transparent<span>
behind it<span>
(with appropriate styling) when the<input>
's contents changeHere's a quick demo.
Text inputs do not support styled content. End of story.
A common solution is to use
contenteditable
instead.