|
Per aumentare l'usabilità dobbiamo aggiungere una tastiera a video. Questo richiede un nuovo oggetto, che chiameremo con molta fantasia Keyboard. Inoltre, viste le maggiori dimensioni del box, la grafica deve permettere risoluzioni fino a 1600x1200 L'oggetto Keyboardfunction _keyboard() { this.activeInputField this.FieldId=-1 this.chars = new Array ('789','456','123','0'); this.keyboardTable } Questo è l'oggetto; è collegato all'oggetto HTML contenente i tasti dalla proprietà _msgBox.prototype.checkKeyboard = function () { if (!this.Keyboard) { this.Keyboard = new _keyboard() this.divKeyboard.appendChild(this.Keyboard.show()) } }
_msgBox.prototype.showKeyboard = function () { /* In base al campo selezionato visualizzerò la tastiera più opportuna */ this.checkKeyboard() this.divKeyboard.style.display = 'block'; } La tabella che conterrà la tastiera deve essere costruita con il DOM se vogliamo che gli eventi passino correttamente in tutti i browser. _keyboard.prototype.show = function () {
var kTable = document.createElement("table"); kTable.className = 'keyb'; kTable.id = 'table_keyboard'; msgBoxInstance.collegaEvento(kTable, 'click', this.handleClick) var kRow var kCell
for (var i=0; i<this.chars.length; i++) { aRow = this.chars[i]; kRow = kTable.insertRow(-1); for (var j=0; j<aRow.length; j++) { kCell = kRow.insertCell(-1) kCell.unselectable="on" kCell.appendChild(document.createTextNode(aRow.charAt(j))) kCell.className='key'; kCell.value = aRow.charAt(j) } } this.keyboardTable = kTable; return kTable }
Il metodo handleClick dell'oggetto _keyboard identifica il tasto che ha originato l'evento click e ne utilizza la proprietà value. _keyboard.prototype.handleClick = function (e) { { /* gestisce l'input da tastiera virtuale (per modifica articolo) leggi anche http://www.quirksmode.org/js/introevents.html */ var td try { if (e instanceof Object) { // firefox td = (e.target?e.target:e) // gestisco anche che venga // passato direttamente l'oggetto come parametro } else td = event.srcElement;
// td è l'oggetto cliccato - si spera con un carattere come attributo "value"... while ((td) && (td.className!='key')) { td = td.parentElement; } if (td) { var k = msgBoxInstance.Keyboard; k.replaceSelection (k.activeInputField, td.value) msgBoxInstance.fields[k.FieldId].value = k.activeInputField.value } else log1('handleClick: object not found'); } catch(ex) { log1('errore: ' + ex) } } }
La posizione del cursoreCercherò di essere breve. Il funzionamento per Firefox è piuttosto lineare. Invece in Internet Explorer abbiamo difficoltà maggiori. In particolare la differenza è che mentre firefox ricorda la posizione del cursore all'interno di un campo anche se questo campo non ha il focus, altrettanto non vale per IE. Il codice usato qui è preso dal valido esempio pubblicato http://www.faqts.com/knowledge_base/view.phtml/aid/13562 ed usa lo stesso "trucchetto" per evitare questo problema: aggiungere a tutti gli elementi che potrebbero "rubare" il focus dal nostro campo input la proprietà unselectable=true. Un'altra strada praticabile e più pulita è - solo per IE - di salvare il range corrente in una proprietà dinamica input.lastRange = input.createTextRange _prima_ che questo perda il focus (evento - proprietario IE - onlosecapture) Quindi all'interno dell'oggetto Keyboard definisco alcune funzioni per gestire il focus: setSelectionRange imposta l'area selezionata (oppure, se selectionStart = selectionEnd, posiziona il cursore alla posizione indicata) _keyboard.prototype.setSelectionRange = function (input, selectionStart, selectionEnd) { if (input.setSelectionRange) { input.focus(); input.setSelectionRange(selectionStart, selectionEnd); } else if (input.createTextRange) { var range = input.createTextRange();
range.collapse(true); range.moveEnd('character', selectionEnd); range.moveStart('character', selectionStart); range.select(); } }
e replaceSelection: sostituisce la selezione oppure aggiunge alla posizione corrente. _keyboard.prototype.replaceSelection = function (input, replaceString) { if (input.setSelectionRange) { var selectionStart = input.selectionStart; var selectionEnd = input.selectionEnd; input.value = input.value.substring(0, selectionStart) + replaceString + input.value.substring(selectionEnd); this.setCaretToPos(input, selectionStart + replaceString.length); } else if (document.selection) { var range = document.selection.createRange(); if (range.parentElement() == input) { // ovvero c'è una selezione nel nostro input box. var isCollapsed = (range.text == ''); range.text = replaceString; } else { // fallback in caso il focus sia stato preso da un altro campo // (in tal caso selection.createRange() non fa riferimento a input) input.value += replaceString; } } else { // fallback per altri browsers input.value += replaceString; } }
Ora rivediamo come usare questa funzionalità (dal nostro file msgBox.html): function request() { msgBox_Edit.virtualKeyboard = true; msgBox_Edit.clearFields() msgBox_Edit.addField('Nick', 'nick', 'Nemo') msgBox_Edit.addField('e-Mail', 'email', '
Questo indirizzo e-mail è protetto dallo spam bot. Abilita Javascript per vederlo.
') msgBox_Edit.request('Ma chi sei?',elaboraRispostaRequest, 'un\'altra domanda di cultura generale', -1) }
E nella callback potremo semplicemente elencare i campi e vederne i valori: function elaboraRispostaRequest(msgResult) { var txl = document.getElementById('textlog'); txl.value = 'risultato msgBox: '+ msgResult+'\n' + 'attiva: '+ msgBoxAttiva + '\nId: ' + msgBoxInstance.id_msgBox ;
var aField for (var i=0; i< msgBox_Edit.fields.length; i++) { aField = msgBox_Edit.fields[i] txl.value += '\nCampo '+i+' ('+aField.desc+')= '+aField.value } }
Nelle prossime puntate vedremo di rendere più potente questa funzione, fornendo sia tastiere dedicate che alcuni tasti standard; e aggiungeremo la validazione essenziale dei campi. I file descritti in questo articolo si possono scaricare dall'introduzione
|