Recently I have been working on a solution in Dynamics CRM 2011, which required me to store and display the characters remaining in a text field, as the user is typing into the field. This ‘Characters Remaining’ field needed to be live updating every time someone enters a character into the text field, so using the standard methods of ‘onChange’ would not quite work, as it would only update once you click out of the field.
There were a few ‘Gotchas’ that I encountered while attempting this seemingly simple task. But before I got to any of those, I first got the JScript working on the fields onchange, so that when someone clicks out of the text box after entering data, then Characters Remaining field will be set to 100 – the field values length. This was easily achieved using the following JScript, with the ‘keyPress’ function being called onchange on the text field.
function keyPress() {
var charRemaining = Xrm.Page.getAttribute("mag_charactersremaining");
var message = Xrm.Page.getAttribute("description");
var messageVal = message.getValue();
var maxLength = 100;
if (messageVal != null) {
var msgLength = messageVal.length;
var remaining = maxLength - msgLength;
charRemaining.setValue(remaining);
}
else {
charRemaining.setValue(maxLength);
}
}
In this example, the ‘charRemaining’ variable sets the ‘Characters Remaining’ field, and the ‘message’ variable sets the name of the text field we’re entering data into. Also the ‘maxLength’ variable sets the starting value of the Characters Remaining field (this will be what it counts down from, in this case 100).
So using this alone works well, however it doesn’t work each time we type a character, which is what we want to happen. So to do this we need to call the function above when a character is typed within our text field. I eventually found the following line of code which will fire the ‘keyPress’ function when a key is pressed inside the text field.
document.getElementById("description").onkeypress = keyPress;
However this was where the first ‘gotcha’ happened. Although adding the above line of code to the onload event would fire the ‘keyPress’ function when a key was pressed, it would not include certain characters such as backspace, enter, or delete. Other options were using ‘onkeydown’ instead of ‘onkeypress’, although this didn’t quite work as expected either, as it was only called when the next key was pressed, where as we wanted to fire when the current key was pressed. So instead we used ‘onkeyup’ which did the job, although using this method didn’t fire the event until the key was released, so if you held down a key it wouldn’t change the Characters Remaining until you released that key. After a bit of testing, I found that adding 2 separate lines for ‘onkeyup’ and ‘onkeydown’ worked exactly how we wanted. The full function to call in the onload looks like this:
function onLoad() {
document.getElementById("description").onkeyup = keyPress;
document.getElementById("description").onkeydown = keyPress;
}
While this was now firing the keyPress event correctly, the Characters Remaining wasn’t changing until you clicked out of the text field. I discovered this was because the ‘message length’ isn't saved until you click out of the field. However I managed to find a work around for this. Instead of using ‘Xrm.Page.getAttribute’ to get the message field, I used ‘document.getElementById’. Which when used with message length got the current length of the field at the time.
This was now working exactly as I wanted, the last step was to add the keyPress function to the onload, so that when the form loads, the Characters Remaining will be set to the correct amount. I’ve added the full JScript file below:
function keyPress() {
var charRemaining = Xrm.Page.getAttribute("mag_charactersremaining");
var message = document.getElementById("description");
var messageVal = message.value;
var maxLength = 100;
if (messageVal != null) {
var msgLength = messageVal.length;
var remaining = maxLength - msgLength;
charRemaining.setValue(remaining);
}
else {
charRemaining.setValue(maxLength);
}
}
function onLoad() {
document.getElementById("description").onkeyup = keyPress;
document.getElementById("description").onkeydown = keyPress;
}