Configurer Bonjour Mounter pour utiliser votre compte Box.net

Bonjour Mounter (téléchargeable ici) est une application Mac permettant de monter automatiquement des disques réseaux (afp, smb, cifs, webdav et ftp). Ayant eu beaucoup de difficultés à monter mon compte Box.net, voici une capture avec les réglages fonctionnels:

Le champs "server" n'accepte pas de "http://" ou de "https://" et l'adresse ne doit pas contenir de "/" terminateur. C'est uniquement grâce à l'application "Messages Console" et Bonjour Mounter en mode Debug que j'ai pu découvrir d'où venait le problème.

Gérer les éléments input radio avec jQuery

J’ai eu hier une question sur la manipulation des éléments radio en Javascript. La personne voulait vérifier que pour chacun de ses groupes de radio, au moins un radio était sélectionné.

Plusieurs solutions en Javascript “pur” existent sur Internet mais aucune ne semblait simple à appliquer par cette personne. Je propose donc ici quelques snippets jQuery pour exploiter simplement les éléments Radio.

Nous partirons donc d’une page incluant la librairie jQuery et le code XHTML suivant :

<form action="?" method="get" id="monForm">
<input type="radio" name="opt1" value="1" checked="checked" />
<input type="radio" name="opt1" value="2" />
<input type="radio" name="opt1" value="3"/>

<input type="radio" name="opt2" value="1" />
<input type="radio" name="opt2" value="2" checked="checked" />
<input type="radio" name="opt2" value="3" />

<input type="radio" name="opt3" value="1" checked="checked" />
<input type="radio" name="opt3" value="2" />
<input type="radio" name="opt3" value="3"/>
</form>


Accéder aux inputs de type radio en jQuery

Il existe plusieurs façon d’accéder aux inputs de type radio en jQuery, j’ai réalisé quelques tests afin de définir quelles expressions étaient les plus rapides :

Benchmark jQuery
Il en ressort que l’expression input[type=radio] est plus rapide que input:radio (mais est-elle autant générique ?)

Le résultat sont très variable lorsque l’on précise un contexte (ici #monForm) et un grand nombre de radio. Je pense donc que les trois dernières expressions ne sont pas à prendre en compte dans l’analyse, du moins pour le moment. (Je travaille actuellement à améliorer mon outils de Benchmark afin que chacun puisse tester ses propres expressions jQuery).

Récupérer tout les input radios appartenant à un même groupe

$('input[type=radio][name=opt1]');//ici retourne 3 éléments input

Connaître si un groupe de radio à une valeur

$('input[type=radio][name=opt1]:checked').length; // Doit être égal à 1 si un radio à été sélectionné dans le groupe de opt1.

Vérifier que tout les radios ont été sélectionnés

$('input[type=radio]:checked').length; // Si au moins un radio est sélectionné pour chaque groupe, ce snippet retourne 3 (dans notre exemple)

Récupérer la valeur d’un groupe de radio

$('input[type=radio][name=opt1]:checked').attr('value'); //Retourne la valeur du radio sélectionné dans le groupe opt1. Retourne vide si aucun radio sélectionné

Trouver le style réellement appliqué sur un élément (sans jQuery)

Etant en train de développer un addon pour Firefox/Firebug qui aidera plus d’un développeur (en tout cas moi) j’ai eu besoin de connaitre le fontFamily d’un élément. Dans cet article je ne traiterai donc que de la façon de récupérer un fontFamily. Cependant la récupération d’autres propriétés CSS (via une fonction générique par exemple) est tout à fait possible.

 

Si le fontFamily a directement été défini (in-line) sur l’élément

<span id='monEl' style='font-family:Tahoma'>Javascript</span>

... alors un simple :

document.getElementById('monEl').style.fontFamily;

ou

$('#monEl').css('fontFamily');

... suffit pour récupérer la valeur de la propriété fontFamily de l’élément.

 

Maintenant si l’on supprime l’attribut style de notre span#monEl le code suivant retournera une chaine vide :

document.getElementById('monEl').style.fontFamily;//retourne ""

Cependant le code jQuery, lui, fonctionnera.

 

Arriver à nos fin sans jQuery

Au début je pensait qu’il suffirait d’effectuer une boucle sur les éléments parents du DOM : remonter à chaque fois d’un élément et dès qu’un élément a un fontFamily de valide, stopper la boucle et retourner sa valeur. Mais il y a beaucoup plus simple.

 

jQuery procède d’une façon différente. En regardant son code de plus près j’ai découvert qu’il avait recourt à la méthode DOM de niveau 2 getComputedStyle() pour récupérer la valeur d’un attribut CSS hérité d’un élément parent. Malheureusement cette méthode ne semble pas être intégré sous IE qui lui dispose de la propriété currentStyle.

 

Voici donc une fonction (basé sur le code utilisé par jQuery) qui retourne, pour un élément donné, la valeur du fontFamily associé :

function getFontFamily(el){
    var ret;
    if (el.style && el.style['fontFamily'])//Si l'élément a déjà la propriété de définie
        ret = el.style['fontFamily'];
    else if (document.defaultView.getComputedStyle){//Firefox, Opera
        var computedStyle = document.defaultView.getComputedStyle(el, null );

        if(computedStyle)
            ret = computedStyle.fontFamily;
    }
    else if (el.currentStyle)//Internet Explorer
        ret = el.currentStyle['fontFamily'];
    return ret;
}

Testé sous Firefox et Chrome.

Réaliser une copie profonde d’objet (deep copy) en Javascript

Un des problèmes récurrent avec Javascript est qu’il est difficile de savoir si une variable passée par référence ou par valeur.

En VB (VB6, VB.NET) il est possible de déclarer dans l’entête de la fonction by val ou by ref pour préciser le mode de passage mais ce n’est pas le cas en Javascript.

//Création de l'objet monObjet
var monObjet = new Object();

// monDeuxiemeObjet réfère à l'objet monObjet
var monDeuxiemeObjet = monObjet;

// On modifie une propriété du premier objet
monObjet.unePropriete = true;

// Les changements sont aussi appliqué sur le second objet
// (Le deuxième objet réfère au premier objet)
alert( monObjet.unePropriete === monDeuxiemeObjet.unePropriete );//affiche true

 

Dans cette exemple, la copie de monObjet dans monDeuxiemeObjet à été effectuée par référence, ce qui signifie que monDeuxiemeObjet pointe vers l’adresse de monObjet (même si la réalité est un peu plus complexe que cela…monDeuxiemeObjet pointe sur la référence de l’objet final monObjet mais c’est une autre histoire).

 

Seulement dans certains cas, il arrive que nous ayons besoin de réaliser une vrai copie. Par exemple sauvegarder monObjet dans une variable temporaire et effectuer des traitements uniquement sur cette variable sans que cela n’affecte monObjet. Dans certains cas là méthode que je vous propose n’est pas indispensable notamment dans le cas où l’objet à copier n’est pas complexe.

 

Heureusement jQuery intègre la méthode extend. Basiquement elle permet de gérer l’héritage d’un objet vers un à plusieurs autres objets. Mais elle permet aussi la copie profonde (deep copy) d’un objet vers un autre et donc une copie par valeur (et non plus par référence) via son paramètre optionnel “deep”.

 

jQuery.extend( [deep], target, object1, [objectN] )

 

//Création de l'objet monObjet
var monObjet = new Object();

var monDeuxiemeObjet = {};
$.extend(true,monObjet,monDeuxiemeObjet);//deep copy

// On modifie une propriété du premier objet
monObjet.unePropriete = true;

// Les changements ne sont pas appliqué sur le second objet
// monDeuxiemeObjet.unePropriete est indéfini
alert( monObjet.unePropriete === monDeuxiemeObjet.unePropriete );//affiche false

Ici, monDeuxiemeObjet ne réfère plus à monObjet. Ces deux objets possèdent chacun leurs propres adresses mémoires, il est ainsi possible de travailler sur l’un sans modifier l’autre.