Aggiungiamo un protototipo delle funzioni per gestire input.
Visto che le funzioni che avranno bisogno di richiedere input variano, realizziamo un sistema a campi dinamici: ovvero in fase di inizializzazione voglio definire nomi e descrizioni dei campi; e visualizzare la richiesta con la message box.
Prima di tutto creo un oggetto "_field" che contiene le proprietà:
function _field(fieldDesc, fieldName, fieldDefaultValue)
{
// nota bene: fieldName deve essere valido come identificatore,
// quindi niente spazi né caratteri strani.
this.name = fieldName; //.replace(/ /i,"") ...
this.desc = fieldDesc
Non sono sicuro che venga passato un valore di default; quindi per evitare che venga visualizzato "undefined" nel campo, potrei verificare (arguments.length>2) prima di effettuare l'assegnazione; ma così è molto più sintetico: se fieldDefaultValue non è valorizzato (=undefined) restituirà falso e quindi verrà scelto il valore dopo l'OR logico ( || )
this.defaultValue=fieldDefaultValue||""
this.value=fieldDefaultValue
this.inputID // conterrà l'ID dell'input che verrà usato per inserire il campo
}
Quindi nella messageBox avrò la nuova proprietà Fields, un array di _field ed un paio di funzioni per aggiungere ed eliminare i campi:
_msgBox.prototype.addField = function (fieldDesc, fieldName, fieldDefaultValue)
{
this.fields.splice(this.fields.length,0,new _field(fieldName,
fieldDesc, fieldDefaultValue))
}
_msgBox.prototype.clearFields = function ()
{
this.fields.splice(0,this.fields.length);
}
Infine, la funzione per riportare il valore dall'input all'array di campi:
_msgBox.prototype.editField = function(FieldId, InputID)
{
// Questo evento viene invocato dall'onchange di un input box
// quindi non ha un accesso diretto all'istanza dell'oggetto dall'interno
// e bisogna usare il riferimento assoluto
with (msgBoxInstance)
{
fields[FieldId].value=document.getElementById(InputID).value
}
}
Ed ora un paio di abbellimenti: coloriamo il box che ha il focus con la funzione selectField e deleselezioniamo tutti gli altri con unselectAllFields. I dettagli li potete guardare nel codice, si tratta semplicemente di applicare uno stile:
Ora mettiamo tutto insieme: il metodo getFieldsHTML() disegnerà una serie di input grossomodo così:
<INPUT type=text class='input' id='field_0_email' value='Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.'
onchange=''msgBoxInstance.editField(1,'field_0_email')">
La funzione che effettua tutto il disegno si avvale di un po' di variabili per semplificare la lettura. Purtroppo il codice per comporre html è spesso difficile da leggere, vediamo di ridurre il mal di testa:
_msgBox.prototype.getFieldsHTML = function ()
{
var aHTML="<center><table class='fields'>"
var aInputID
var aInput
var aInputFunc
var aField
var aSelectedClass
with (this)
{
for (var i=0; i<fields.length; i++)
{
if (i==0)
aSelectedClass=' selected'
else
aSelectedClass='';
aField = fields[i];
aInputID= "field_"+msgBoxAttiva+"_"+aField.name
aField.inputID = aInputID
aInputFunc = " onchange='msgBoxInstance.editField("+ i +",\""+
aInputID +"\")' "
aInputFunc += " onfocus='msgBoxInstance.selectField("+ i +",\""+
aInputID+"\")' "
aInput = "<input type=text class='input"+aSelectedClass+"' id='"+
aInputID+"' value='"+aField.defaultValue+"' "+aInputFunc+"/>";
aHTML += "<tr><td class='label'><label for='"+aInputID+"'>" +
aField.desc + "</label></td><td class='input'>" + aInput + "</td></tr>\n";
}
}
return aHTML+"</table></center>"
}
Nelle prossime puntate vedremo di rendere più potente questa funzione, fornendo sia tastiere dedicate per modificare i testi con touchscreen oppure con il mouse; e aggiungeremo la validazione essenziale dei campi.
I file descritti in questo articolo si possono scaricare dall'introduzione