MessageBox con un solo campo?
Facciamo ora in modo che sia possibile aprire una piccola messageBox (anche NON modale) per visualizzare solo una tastiera rapida (senza tasti Si/No).
L'obiettivo è quello di creare la message box con una sola istruzione, collegandola all'input text;
e infine invocare l'onClose
Naturalmente ricicliamo tutto il contenitore (i vari div) e il sistema di tastiere, isolandolo nella funzione buildBox per comodità; lasciamo al constructor, ovvero _msgBox, il compito di definire e valorizzare i campi; e spostiamo in buildBox la logica di disegno. Aggiungiamo un paio di parametri, isModal e showButtons per permettere di discriminare nella fase di disegno. Di default prenderanno un valore compatible con le message Box create finora; inoltre se la messageBox non deve essere modal, vengono ridotti automaticamente i margini (padding):
_msgBox.prototype.buildBox = function(isModal, showButtons) [...] var rDivBoxHD = document.createElement('div'); if (!showButtons) rDivBoxHD.className = 'hd bighd' else rDivBoxHD.className = 'hd' [...]
Le operazioni che - per utilizzare una tastiera _senza_ la messageBox - avevo messo nella funzione getSingleKeyboard sono diverse; e la "nuova" messageBox che andiamo ora a creare usa alcuni di questi comandi.
La nuova messageBox dedicata
Devo derivare una nuova classe, _msgBoxSingle, da _msgBox. Il sistema è simile a quello che ho usato per creare _keyboardAlfa ereditando da _keyboard. Però qui devo anche passare dei parametri.
Per far ciò la funzione da invocare non è più call bensì apply: il resto dell'invocazione rimane immutato; ma per passare i parametri ad apply dovrò costruire un Array dei parametri e passare quello:
_msgBoxSingle.prototype = new _msgBox(); _msgBoxSingle.prototype.constructor = _msgBox; function _msgBoxSingle(aColor, inputElement, sCaption, sCallBack, defaultValue) { var iWidth = 280; var iHeight = 350; var aParams = new Array(aColor, iWidth, iHeight, "center", true, false, true); _msgBox.apply( this, aParams);
La principale differenza rispetto alla messageBox è nell'uso: la funzione show() mostra la tastiera, e devo impostare una callBack per il risultato:
[...] this.callBack = sCallBack; this.collegaEventi() // serve ad assegnare divContent e divHeader...
Nel seguito della funzione _msgBoxSingle dovremo differenziare la parte di disegno per disegnare solo un input box (editInputElement) sopra la tastiera (così se uno usa un touch-screen non copre l'importo con la mano).
Prima di tutto crea l'elemento input ed un elemento centerInput nel quale incapsularlo:
var centerInput = document.createElement('center'); this.editInputElement = document.createElement('input'); this.editInputElement.className= "mainInputField" this.editInputElement.style.width = parseInt(this.layerWidth) - 20;
Poi prevedo che mi sia passato in alternativa: un elemento input (che dovrò modificare) oppure un valore di default:
if (inputElement instanceof Object) { this.editInputElement.value = inputElement.value } else this.editInputElement.value = defaultValue; centerInput.appendChild(this.editInputElement)
inputElement è l'elemento INPUT (opzionale); se lo ricevo dovrò alla fine aggiornarne il valore.
editInputElement invece è l'elemento INPUT che ho appena creato all'interno della messageBox.
this.inputElement = inputElement this.divContent.innerHTML = ''; this.divContent.appendChild(centerInput); this.divHeader.innerHTML = sCaption
Infine, mi riassegno tutti i valori:
this.Keyboard = this.Keyboards.KeyboardNum
onHide viene invocata quando si preme invio. Però deve anche nascondere la messageBox (altrimenti la tastiera nasconde sé stessa ma non la message Box!). L'handler che vado a chiamare lo definisco direttamente all'interno dell'oggetto _msgBoxSingle.
this.Keyboard.onHide = this.onHideHandler; this.Keyboards.activeInputField = this.editInputElement }
Ultima modifica, faccio l'override del metodo show() per mostrare anche la tastiera: Questo metodo invoca il metodo del _msgBox usando call, quindi visualizza la tastiera
_msgBoxSingle.prototype.show = function () { _msgBox.prototype.show.call(this); // no params to show.... ma usando call devo passare // come primo parametro l'istanza dell'oggetto su cui eseguire il metodo. this.Keyboard.show(); }
Vediamo direttamente il codice reale usato nell'applicazione per utilizzare la tastiera: l'ultimo parametro '2' è il valore predefinito; ho passato null in quanto nell'applicazione non uso INPUT per visualizzare i dati ma li presento in una forma diversa.
var ScontoE_Keyb function scontoValutaCallback(newValue) { alert('Hai richiesto uno sconto di ' + newValue); } function apriScontoE_Keyb() { /* Dimostro l'uso della messagebox con sola tastiera per campo singolo numerico */ if (!ScontoE_Keyb) { ScontoE_Keyb = new _msgBoxSingle('blue', null, 'Sconto', scontoValutaCallback, '2') } ScontoE_Keyb.show() }
Conclusioni
Una volta creato un oggetto, è semplice aggiungere funzionalità.
Ma prendendosi la briga di creare oggetti derivati ottengo il duplice beneficio di
- Non complicare il codice (ciascun oggetto può risiedere in files diversi tra l'altro)
- Non modificare per nulla o quasi il codice dell'oggetto da cui derivo - quindi riduco il rischio di introdurre nuovi bachi.
I file descritti in questo articolo si possono scaricare dall'introduzione