Foros del Web » Programando para Internet » Javascript »

Controlar el caret en un input

Estas en el tema de Controlar el caret en un input en el foro de Javascript en Foros del Web. Buenos dias/tardes/noches forer@s. Necesitaria vuestra ayudita para algo que espero no sea demasiado complejo (aunque a mi me esta pareciendo un mundo ) Por exigencias ...
  #1 (permalink)  
Antiguo 16/02/2006, 09:10
Avatar de Amröd  
Fecha de Ingreso: febrero-2006
Mensajes: 9
Antigüedad: 18 años, 2 meses
Puntos: 0
Controlar el caret en un input

Buenos dias/tardes/noches forer@s.

Necesitaria vuestra ayudita para algo que espero no sea demasiado complejo (aunque a mi me esta pareciendo un mundo )

Por exigencias del guion (aka "el jefe lo quiere asi") debo convertir el contenido de un input a mayusculas segun se esta escribiendo.

Es decir, aplicar el toUpperCase() a cada caracter introducido. De forma que se vea en todo momento en mayusculas y el value sea el mismo que se ve.

this.value = this.value.toUpperCase() funciona, pero no me deja retroceder si no es borrando o con el raton.

Hrasteando un poco me he dado cuenta que cada vez que sobreescribo el contenido de un input el caret se me posiciona al final... lo cual me fastidia todo el invento.

He encontrado un codigo para saber la posicion del caret, lo cual me permite introducir el caracter convertido a mayusculas en esa posicion, pero inmediatamente se me va el caret al final de nuevo

Por si a alguien le interesa:
var range = document.selection.createRange();
var bookmark = range.getBookmark();
caret_pos = bookmark.charCodeAt(2) - 2;

Aunque no entiendo muy bien que es lo que hace, el resultado es que en caret_pos tengo la posicion del cursor dentro del input.
Llamo a esta funcion tanto en onKeyUp como en onMouseUp.

Y luego introduzco el caracter por medio de:
oInput.value = subStrA + chrMays + subStrB;

chrMays es el caracter introducido por el usuario convertido a mayusculas (cancelo la entrada y lo concateno yo a capon).
subStrX son las subcadenas anteriores resultado de dividir la cadena en el punto que he detectado el caret.

El problema es q esto me pone la letra donde yo quiero, pero el caret pasa al final.

Si alguien tiene alguna idea, cualquier cosilla sera bienvenida.

PD.- yo lo haria con CSS y luego lo convertiria tranquilamente con el toUpperCase(), pero no puedo utilizar esa opcion
  #2 (permalink)  
Antiguo 17/02/2006, 02:00
Avatar de Amröd  
Fecha de Ingreso: febrero-2006
Mensajes: 9
Antigüedad: 18 años, 2 meses
Puntos: 0
Pues vaya, debe ser bastante mas complicado de lo ya me parecia a mi...

Os adjunto el codigo de una pagina de ejemplo a ver si sirve de ayuda.

Si hay algun otro modo para pasar a mayusculas "on-the-fly" q no tenga nada q ver con esto, tb me vale.

Muchas gracias.

---------------------------------------------

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Prueba</title>

<script>

function stopit(E)
{
E.preventDefault();
}

var caret_pos;
function getCaretPos ()
{
var range = document.selection.createRange();
var bookmark = range.getBookmark();
caret_pos = bookmark.charCodeAt(2) - 2;

window.document.getElementById('pos').value = caret_pos;
}

var tclAcento = 0; // para controlar si la ultima tecla pulsada fue un acento
var tclShift = false; // para controlar si se pulso el shift
function mays (oInput, E)
{
var iKeyCode_a = 65;
var iKeyCode_e = 69;
var iKeyCode_i = 73;
var iKeyCode_o = 79;
var iKeyCode_u = 85;
var iKeyCode_z = 90;
var iKeyCode_ç = 191; //231
var iKeyCode_ñ = 192; //241
if (window.event)
{
var iKeyCode_acento1 = 186; // `^ para IE
} else
{
var iKeyCode_acento1 = 59; // `^ para FF
}
var iKeyCode_acento2 = 222; // ´¨
var arrayAcentosA = [192,194,193,196]; // estan ordenados [`,^,´,¨]
var arrayAcentosE = [200,202,201,203];
var arrayAcentosI = [204,206,205,207];
var arrayAcentosO = [210,212,211,214];
var arrayAcentosU = [217,219,218,220];

if(window.event)
{
var cKeyCodeRecibido = window.event.keyCode; // Caracter recibido IE:
} else if(E.which)
{
var cKeyCodeRecibido = E.which; // Caracter recibido NS:
}

var bCancelarEntrada = false;
var chrMays;

if (cKeyCodeRecibido == iKeyCode_ñ)
{
chrMays = String.fromCharCode(209);
bCancelarEntrada = true;
}
if (cKeyCodeRecibido == iKeyCode_ç)
{
chrMays = String.fromCharCode(199);
bCancelarEntrada = true;
}

if ((iKeyCode_a<=cKeyCodeRecibido)&&(cKeyCodeRecibido <=iKeyCode_z))
{
if (tclAcento!=0)
{ // la ultima tecla fue un acento
if ((cKeyCodeRecibido!=iKeyCode_a)&&(cKeyCodeRecibido !=iKeyCode_e)&&(cKeyCodeRecibido!=iKeyCode_i)&&(cK eyCodeRecibido!=iKeyCode_o)&&(cKeyCodeRecibido!=iK eyCode_u))
{ // entra aqui si no es una vocal
chrMays = String.fromCharCode(cKeyCodeRecibido);
bCancelarEntrada = true;
} else
{ // caso de que la tecla pulsada sea una vocal y la anterior fuera un acento
var arrayAcentosX;
switch (cKeyCodeRecibido)
{ // con este switch escogemos el array donde miraremos el acento
case 65: // A
arrayAcentosX = arrayAcentosA;
break;
case 69: // E
arrayAcentosX = arrayAcentosE;
break;
case 73: // I
arrayAcentosX = arrayAcentosI;
break;
case 79: // O
arrayAcentosX = arrayAcentosO;
break;
case 85: // U
arrayAcentosX = arrayAcentosU;
break;
}
var numElem = 0;
if (tclAcento==222) {numElem+=2} // si el acento era ´ o ¨, sera el elemento 2 o 3.
if (tclShift) {numElem++} // si se pulso la tecla Shift, sera el elemento 1 o 3
chrMays = String.fromCharCode(arrayAcentosX[numElem]);
}
} else
{ // la ultima tecla pulsada no fue un acento
chrMays = String.fromCharCode(cKeyCodeRecibido);
}
bCancelarEntrada = true;
}

if (bCancelarEntrada)
{
if(window.event)
{
window.event.returnValue = false;
} else if(E.which)
{
window.addEventListener("keypress", stopit, false);
setTimeout("window.removeEventListener('keypress', stopit, false)",1); //Solo es para que se ejecute con un poco de retardo, si se ejecuta automáticamente después no hace nada el addEventListener
}
//oInput.value=oInput.value+chrMays; << esto inserta chrMays al final del string
var subStrA = oInput.value.substr(0,caret_pos);
var subStrB = oInput.value.substring(caret_pos, oInput.value.length);
oInput.value = subStrA + chrMays + subStrB;
//alert('char:'+chrMays+' '+cKeyCodeRecibido);
}

if ((cKeyCodeRecibido == iKeyCode_acento2) || (cKeyCodeRecibido == iKeyCode_acento1))
{ // comprobacion acentos
if(window.event)
{
window.event.returnValue = false;
} else if(E.which)
{
window.addEventListener("keypress", stopit, false);
setTimeout("window.removeEventListener('keypress', stopit, false)",1); //Solo es para que se ejecute con un poco de retardo, si se ejecuta automáticamente después no hace nada el addEventListener
}
tclAcento = cKeyCodeRecibido;

var evtObj = window.event? event : E;
if (evtObj.shiftKey)
{ // comprobacion tecla Shift pulsada, solo si se ha pulsado un acento
tclShift = true;
} else
{
tclShift = false;
}

} else
{ // se ha pulsado una tecla que no es un acento y ya ha sido procesada, asi que esta variable debe estar limpia. Lo mismo para el shift
tclAcento = 0;
tclShift = false;
}

// la siguiente linea es solo para el ejemplo
window.document.getElementById('code').value = cKeyCodeRecibido;
}

</script>

</head>

<body style="background-color:#CCFFCC">
<form>

<div>
Pasar a mayusculas [mays()] <input type="text" onKeyDown="mays(this,event)" onmouseup="getCaretPos(this, event)" onkeyup="getCaretPos(this, event)"/> - <input id="code" type="text" tabindex="2" size="4"> keyCode de la tecla pulsada
</div>
<div>
Posicion del cursor&nbsp;<input id="pos" size="4">
</div>

</form>
</body>
</html>
  #3 (permalink)  
Antiguo 18/02/2006, 00:22
Avatar de uamistad  
Fecha de Ingreso: diciembre-2004
Ubicación: Cd. de México
Mensajes: 1.395
Antigüedad: 19 años, 4 meses
Puntos: 1
A mí me parece que podrías facilitarte la vida haciéndolo con CSS. No hay que programar nada, CSS hace eso.
__________________
"Di no al Internet Explorer" -Proverbio Chino-
  #4 (permalink)  
Antiguo 20/02/2006, 01:57
Avatar de Amröd  
Fecha de Ingreso: febrero-2006
Mensajes: 9
Antigüedad: 18 años, 2 meses
Puntos: 0
Lamentablemente el CSS solo muestra, no convierte el value. Es decir, si almaceno en BBDD algo q por CSS esta en mayusculas con el text-transform:uppercase, lo q grabare estara como lo haya escrito el usuario, ya sea mayusculas, minusculas o una mezcla de.

El CSS esta muy bien, pero solo no basta.

La primera solucion q propuse yo pasaba por utilizar CSS para visualizacion y en onBlur hacer this.value = this.value.toUpperCase().

Esta solucion ha sido deshechada por los posibles accesos asincronos a campos, via AJAX por ejemplo.
  #5 (permalink)  
Antiguo 20/02/2006, 03:31
Avatar de uamistad  
Fecha de Ingreso: diciembre-2004
Ubicación: Cd. de México
Mensajes: 1.395
Antigüedad: 19 años, 4 meses
Puntos: 1
Cita:
Lamentablemente el CSS solo muestra, no convierte el value. Es decir, si almaceno en BBDD algo q por CSS esta en mayusculas con el text-transform:uppercase, lo q grabare estara como lo haya escrito el usuario, ya sea mayusculas, minusculas o una mezcla de.
Es que sinceramente no se me hace justificable armar un código en Javascript para algo que CSS ya realiza en una sola línea.

Ahora, tienes razón, sólo muestra, pero lo que tú necesitas es guardarlo así en una base de datos.

Bien, pues algún lenguaje de programación vas a utilizar para comunicarte con tu base de datos, ¿cierto? Quizá sea PHP, ASP, Java, etc.

Digamos que utilizas PHP, al momento de insertar podrías usar la función de PHP strtoupper() y nuevamente, con una sola instrucción, todas se convirtieron en mayúsculas.

Lo verdaderamente valioso de hacerlo de esta forma es la capacidad de hacerlo sin importar que el usuario tenga desactivado javascript.
__________________
"Di no al Internet Explorer" -Proverbio Chino-
  #6 (permalink)  
Antiguo 20/02/2006, 03:38
Avatar de Amröd  
Fecha de Ingreso: febrero-2006
Mensajes: 9
Antigüedad: 18 años, 2 meses
Puntos: 0
Basicamente estas reproduciendo lo q yo le argumente a mi jefe...

Gracias, al menos no soy el unico q opina asi.

La cosa es q es una aplicacion empresarial bastante grande, y es muy probable q se pueda acceder a los datos desde otras aplicaciones desde las q puede q no tengamos todo el control. Por eso la necesidad de q el contenido de los campos sea el q se ve en todo momento.

Yo sugeri el CSS para mostrar y convertir a mayusculas en BBDD (oracle en este caso), o en el server antes de enviar a BBDD (arquitectura J2EE).
Incluso meter un toUpperCase() al hacer un onBlur()... pero ni caso.

Y donde hay capitan no manda marinero, como bien sabemos (bueno, tampoco es q me pueda quejar tanto :P)

Muchas gracias en cualquier caso.

Por si sirve de algo, creo q ya hemos encontrado la solucion (y si, es un tocho de codigo de narices).

Para IE:

function setCaretTo(control)
{
if (control.createTextRange)
{
var range = control.createTextRange();
range.collapse(true);
range.moveStart('character',caret_pos);
range.select();
} else if (control.setSelectionRange)
{
control.focus();
control.setSelectionRange(caret_pos, caret_pos);
}
}

y para opera y FF utilizando el txt.selectionStart.

En cualquier caso, muchas gracias.
  #7 (permalink)  
Antiguo 20/02/2006, 17:10
(Desactivado)
 
Fecha de Ingreso: noviembre-2002
Ubicación: Ciudad Autónoma de Buenos Aires
Mensajes: 2.367
Antigüedad: 21 años, 5 meses
Puntos: 317
Hola Amröd , uamistad :

Esa última idea funcionaba muy bien, uamistad, lástima que es solamente para la vista. Pero el "jefe" no tiene por qué darse cuenta.

Código:
<input style="text-transform:uppercase" 
value="doble click para ver el valor" size="40" 
ondblclick="alert(this.value.toUpperCase())" />
Y corrige el primer código, Amröd, la c con cedilla y la eñe no caben en un escript.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 19:53.