29.7.08

Firefox y los rangos de texto (textRange)

Estoy preparando un objeto para poder controlar las entradas de texto en los InputBox (de hecho ya lo tenía en una antigua librería javascript) mediante Expresiones Regulares, de modo de achicar un tanto el tamaño de la anterior, pero, además, para que me sirva de base para un futuro control de usuario web para ASP.NET, con el que estoy comenzando a trabajar.

El objeto en cuestión debe controlar distintos tipos de entradas: texto, caracteres especiales, fechas, números, etc. Todo esto para no tener que validar esto en el servidor y evitar los molestos retornos por errores del usuario a la hora de llenar un formulario.

Cuando lo tenga listo, lo subiré a este blog, para que ustedes lo "destrocen" a gusto. Pero no tengan muchas esperanzas, porque como dijera más arriba, este objeto se basa en una librería anterior que tengo, que tiene unos cuantos años de uso, lo que siempre garantiza que se le han pulido bien los errores. Pero siempre los hay.

El tema en cuestión de este artículo es que se me presentó un inconveniente en el momento de que mi evento keypress retornaba falso porque se había detectado que, por ejemplo, el caracter que estaba ingresando estaba fuera de lo permitido. Entonces "pinte" el texto e intenté reemplazar de un plumazo todo lo seleccionado.

Grande fue mi sorpresa al ver que el caracter que intentaba reemplazar lo seleccionado no era tomado, puesto que el evento keypress seguía rechazándolo.

Investigando un poco, pues di con la solución IE: antes de controlar el nuevo caracter ingresado, debía averiguar si el texto anterior estaba seleccionado total o parcialmente y borrar el rango que el usurio había pintado. Como se hace esto en IE:

if(Browser.IE) {
if (document.selection.type == "Text") {
var tr = document.selection.createRange();
tr.text = "";
}
}

Browser.IE es un objeto que me devuelve true si el navegador en Internet Explorer. document.selection es el objeto que contiene la selección que hemos hecho, cuya propiedad type tiene como valor None si no se ha seleccionado nada, o Text si se ha seleccionado texto, que es lo que nos ocupa.

Pues bien, creamos un objeto textRange mediante el método createRange del objeto selection (en el ejemplo caso tr) y podemos manipularlo a gusto.

Pero mis penas empezaron al tratar de emular este comportamiento en Firefox, no porque fuera difícil, sino por la carencia de documentación al respecto. Y, tal como vengo haciendo en este blog, acá les dejo el "cómo se hace", por si alguno de ustedes tiene este inconveniente:


if(obj.selectionStart < obj.selectionEnd) {
   if(String(noChar).search('37|39') == -1) {
     window.getSelection().collapseToStart()
   }
}

obj es el objeto que estoy validando (input). selectionStart contiene la posición inicial del "pintado" que, cuando no se está pintando el texto, tiene el mismo valor que selectionEnd. Por último, para borrar el texto seleccionada, basta con ejecutar el método collapseToStart.

0 Comentarios: