by Claudio Cicali
2009 July 29
29 July 2009
–
–
Potrei aver scritto questo post 45 volte, ormai, e tutte le volte ci ricasco. E bestemmio.
Prima o poi ti capita che il cliente ti chieda “l’export per excel” di qualche tabulato. Tu al volo allora gli proponi l’export in csv che tanto Excel lo apre come fosse un xls, sperando di svincolarti dai micragnosi (e fino a poco tempo fa) misteriosi formati proprietati Microsoft. Capra e cavoli? Tutto liscio? Certo, come no.
Prepari il tuo bell’export CSV come tutti sanno fare e magari approfondisci anche il discorso.
Con OpenOffice, ovviamente, tutto liscio.
Ecco invece i problemi con Excel (sarei tentato di dire “qualsiasi versione”, ma in realtà ho provato solo con MS Office 2003)
- per Excel la “C” di “CSV” sta per “semicolon” e non per “comma”. Già. Occorre separare i campi con un punto e virgola, non con una virgola (ancora una volta OOo non fa una piega cambiando questo “default” – si limita a dire “Oh, OK.”; giuro che l’ho sentito) [edit: come dice calca nei commenti questo comportamento potrebbe essere una impostazione del locale... boh]
- il problema più grave, però, è che per Excel un CSV può essere soltanto in LATIN1 e niente altro. Avete codificato il CSV in UTF8? Tempo perso. No way. Niente da fare. Da qualche parte si legge che aggiungendo il dovuto BOM all’inizio del file il signorino dovrebbe onorarlo… a me non è sembrato.
La cosa curiosa, per quanto riguarda quest’ultimo punto, è che se da Excel stesso esporti uno sheet in fomato CSV contenente dei caratteri non ASCII, il CSV che ottieni è appunto non in formato UTF8, e dunque avrai le famose accentate sminchiate. Va da sé che non esiste opzione per modificare questo comportamento.
Se sei stato più fortunato di me, fammelo sapere e te ne sarò grato.
by Claudio Cicali
2009 July 27
27 July 2009
–
–
Ieri ho avuto necessità di mettere il cursore sul primo campo di una form, automaticamente all’apertura della pagina. Il primo campo però che non contenesse la classe “hasDatepicker” (un widget di jQueryUI). Tagliando qui e là alla fine credo di aver risolto con una sola riga di codice che, aldilà del suo scopo, contiene diverse cosette che vorrei condividere. Il codice (che usa jQuery) è questo:
var fi;
(fi = $('form :input').not(".hasDatepicker")) && fi.length && fi[0].focus();
In italiano si legge così: prendi tutti gli elementi input della form, elimina quelli che hanno classe “hasDatepicker”. Dei risultanti (se esistono) prendi il primo e rendilo attivo.
(se hai in mente un modo per ottimizzare ancora, ti prego di leggere la nota alla fine del post)
Cosa possiamo rilevare, di interessante, da una sola righetta di codice?
- Il one liner usa la tecnica del “corto circuito”, visto che JavaScript ce lo permette: un’espressione viene valutata da sinistra verso destra e l’elaborazione viene interrotta appena si raggiunge un valore che non può cambiare. In questo caso, la sequenza di “&&” fa sì che appena una delle tre espressioni è falsa, la valutazione viene interrotta (in questo caso quella che ci interessa in particolare è la seconda, che in pratica verifica se è stato trovato almeno un elemento).
- La prima parte dell’espressione (l’assegnamento) deve essere racchiusa tra parentesi perché altrimenti non sarebbe sintatticamente valida. In questo modo invece si forza l’interprete a valutarla in maniera atomica, so to speak. Le parentesi come “aiutino” sintattico si trovano spesso, in JavaScript.
- jQuery oltre ai selettori standard e quelli usabili anche tramite querySelectorAll, ne ha alcuni suoi molto comodi. Uno di questi è appunto “:input” che permette di selezionare tutti gli elementi input di una form ma anche select e textarea in un colpo solo.
- Ottenuta una selezione di elementi (sempre assimilabile ad un array anche se la selezione è vuota, come si vede dalla seconda e terza parte dell’espressione), è possibile filtrare via degli elementi non voluti tramite il metodo “not”. Esiste anche il metodo controparte filter(), che permette di elminare gli elementi che NON hanno corrispondenza con il suo parametro/i.
Nota: probabilmente c’è un modo ancora più corto per fare questa operazione… la prima cosa che mi viene in mente è usare l’attribute selector, in modo da scrivere qualcosa come $(“form :input[class!=hasDatepicker]:first”). Quello che non mi piace molto, in questo contesto, è che l’operatore “!=” di quel selettore, ritorna true anche quando l’attributo “class” dell’elemento non è presente del tutto, per cui la selezione potrebbe essere “prendi il primo input della form che non ha una classe” che non è esattamente quello che volevo (dovrei fare delle prove, in effetti). Inoltre, probabilmente, questo articoletto non sarebbe mai nato ;)
by Claudio Cicali
2009 July 17
17 July 2009
–
–
Questo brevissimo articolo potrebbe essere sicuramente un addendum ad un mio precedente articolo.
La tecnica dei “namespace anonimi” (il nome credo di averlo appena inventato e mi scuso se non fosse formalmente correttissimo) è utile nel caso si volesse aggiungere uno snippet di codice JavaScript all’interno di un template per fare una cosa molto specifica che non merita di essere inserita all’interno dei file JavaScript di tutta l’applicazione. Ne ho avuto bisogno recentemente quando ho dovuto far scomparire un campo di una form se il valore di una certa SELECT non fosse impostato. Avevo bisogno di una variable di appoggio, ma ovviamente non volevo che questa finisse nell’oggetto globale.
Senza indugiare oltre, ecco il codice (l’ho diviso in tre passi per chiarezza espositiva):
/* Passo 1.
Definiamo una funzione anonima per creare un namespace;
è necessario racchiudere la definizione all'interno di una coppia
di parentesi, o il parser JavaScript darebbe errore */
(function() {
});
/* Passo 2.
Inseriamo all'interno del nostro "namespace" il codice che ci
interessa eseguire. Si noti che la variable $s in questo modo
non è globale ma rimane chiusa nel namespace (che era quello
che volevamo ottenere) */
(function() {
var $s = $('#generatingActionId');
if ($s.val() == '') {
$('#generatingActionRef-label').hide();
}
});
/* Passo 3.
Infine "attiviamo" il nostro codice, eseguendo la funzione anonima;
notare la coppia di parentesi direttamente alla fine della definizione
della funzione */
(function() {
var $s = $('#generatingActionId');
if ($s.val() == '') {
$('#generatingActionRef-label').hide();
}
})();
by Claudio Cicali
2009 July 14
14 July 2009
–
–

Per dare la propria adesione all’appello di Diritto alla Rete contro il ddl Alfano che imbavaglia la Internet italiana: Diritto alla rete. Per maggiori informazioni si veda anche qui.