Archives mensuelles : avril 2013

Visual Studio / Javascript : Commentaire d’API dans l’IntelliSense

L’éditeur JavaScript de Visual Studio est un de mes préférés notamment grâce à l’IntelliSense dont j’avais parlé dans un précédent article. Nous allons voir dans ce post comment améliorer l’intelliSense afin de pouvoir voir les paramètres attendu par une fonction JavaScript, sa description, ….

Visual Studio utilise pour JavaScript les commentaires XML comme en C# à la différence que ceux-ci doivent se trouver au début du corps de la fonction et non au dessus.

var exampleFunction = function (a, b, c) {
    /// <summary>Exemple de description d'un fonction</summary>;
    /// <param name="a" type="String">description d'un paramètre de type string</param>
    /// <param name="b" type="int">description d'un paramètre de type int</param>
    /// <param name="c" type="Object">description d'un paramètre de type Objet</param>
    ... ici le code de la fonction
}

Sans et avec commentaires de fonction :
VS2012-FunctionWithOutComment

VS2012 - Fonction avec Commentaire

Par défaut, malheureusement, Visual Studio ne génère pas automatiquement le squelette des commentaires lors de l’insertion de ///. Il existe cependant des extensions qui permettent de le faire :

L’IntelliSense peut afficher les commentaires dans les scénarios suivants :

  • 1 fichier .js référence un auter fichier .js .
  • 1 fichier .js référence 1 fichier .aspx ou cshtml.
  • 1 fichier .aspx ou .cshtml qui référence 1 fichier .js.

L’IntelliSense n’est pas disponible quand un fichier .aspx (ou .cshtml) référence un autre fichier.aspx (ou .cshtml).

Il existe une version de JQuery avec les commentaires compatible avec VS dont j’avais parlé dans un précédent article concernant les astuces JQuery.

Il faut savoir qu’il existe une autre norme pour les commentaires API en JavaScript JsDoc et que Web Essentials 2012 permet de gérer.

Références

Bon codage !!

Firefox/Chrome : Forcer l’état d’un élément

Les navigateurs modernes possèdent aujourd’hui des outils pour développeurs très puissant que ça soit pour le HTML, CSS, JavaScript, profiling, … En CSS, la possibilité d’éditer les styles en « live » est très pratique mais peut s’avérer complexe dans certains cas comme la gestion des états (hover, focus, …). Voyons comment debugger plus facilement ce cas avec les consoles web de Chrome, Firefox et Firefug (extension pour Firefox bien connue des développeurs web). (Je n’ai pas trouver comment faire sous IE et n’utilise pas d’autres navigateurs comme Opera ou Safari …)

En effet il est possible de forcer un état sur un élément avec ces outils, ce qui est très pratique notamment pour l’état :hover (survol d’un élément).

Chrome

Il faut faire un clic droit sur l’élément dans l’inspecteur d’élément (Onglet Elements dans la barre d’outils développeur. F12 pour l’ouvrir) et choisir l’état dans le menu Force element state.

Les états gérés sont :

  • active
  • hover
  • focus
  • visited

Forcer un état sous Chrome

Firefox

Sous Firefox, cela fonctionne de la même façon que sous Chrome à la seule différence que l’état visited n’est pas disponible.

Forcer un état sous Firefox

Firebug

Avec Firebug, l’activation est un peu plus difficile à trouver. Une fois l’élément sélectionné dans l’explorateur HTML, il faut cliquer sur la flèche de l’onglet Style pour pouvoir activer l’état voulu. Firebug ne gère que les états :hover, :active et :focus comme Firefox.

Forcer un état avec Firebug

CSS : Tronquer du texte

Voici une petite astuce afin de tronquer un texte en CSS si celui-ci dépasse de son conteneur.

Voici le code CSS qui permet d’effectuer cet « effet » qui est très bien supportée même sous IE ;).

h1 {
    white-space : nowrap; //permet de forcer le non retour à la ligne
    overflow : hidden; //permet de masquer si ça dépasse
    text-overflow : ellipsis; //permet de rajouter ... si ça dépasse
}

Une petite démo avec des boites style Modern UI (Windows 8).

Texte tronqué

Références

ASP.NET MVC : Etendre un Helper

ASP.NET MVC fournit par défaut des Helpers afin de générer du code HTML facilement. Il existe ainsi des helper pour la gestion des URLs, des inputs de formulaires, …

Une des bonnes pratiques est de créer des helpers perso afin de ne pas mettre de code C# directement dans la vue.

J’ai été confronté récemment dans mon projet à étendre un helper inclus de base dans ASP.NET MVC, celui des dropdownlist. En effet, je devais rendre éditable une liste select en fonction de mon modèle. Afin d’éviter d’avoir du code spaghetti dans ma page vue cshtml, j’ai étendu le Helper fournit par défaut afin de lui passer un paramètre supplémentaire, un booléen canEdit déterminant le statut éditable ou non de mon select.

Il existe 6 signatures pour la méthode DropDownListFor pour lesquelles j’ai ajouté mon paramètre. J’ai été confronté à une difficulté pour une des signatures qui passe en paramètres les attributs html sous la forme d’un objet. Il existe une méthode statique AnonymousObjectToHtmlAttributes qui permet de transformer votre objet en un dictionnaire (RouteValueDictionary) et il devient alors aisé de rajouter un attribut à votre select.

var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
attrs.Add("disabled", "disabled");

Le code complet (sans les commentaires API)

public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, SelectList selectList, bool canEdit)
{
	if (canEdit)
	{
		return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList);
	}
	var htmlAttributes = new Dictionary<string, object>();
	htmlAttributes.Add("disabled", "disabled");
	return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, htmlAttributes);
}

public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, SelectList selectList, string optionLabel, bool canEdit)
{
	if (!canEdit)
	{
		return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, optionLabel);
	}
	var htmlAttributes = new Dictionary<string, object>();
	htmlAttributes.Add("disabled", "disabled");
	return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, optionLabel, htmlAttributes);
}

public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, SelectList selectList, string optionLabel, IDictionary<string, object> htmlAttributes, bool canEdit)
{
	if (!canEdit)
	{
		htmlAttributes.Add("disabled", "disabled");
	}
	return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, optionLabel, htmlAttributes);
}

public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, SelectList selectList, IDictionary<string, object> htmlAttributes, bool canEdit)
{
	if (!canEdit)
	{
		htmlAttributes.Add("disabled", "disabled");
	}
	return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, htmlAttributes);
}


public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, SelectList selectList, object htmlAttributes, bool canEdit)
{
	if (canEdit)
	{
		return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, htmlAttributes);
	}
	var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
	attrs.Add("disabled", "disabled");
	return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, attrs);
}

public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, SelectList selectList, string optionLabel, object htmlAttributes, bool canEdit)
{
	if (canEdit)
	{
		return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, optionLabel, htmlAttributes);
	}
	var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
	attrs.Add("disabled", "disabled");
	return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, optionLabel, attrs);
}

Et un petit exemple d’utilisation

@Html.DropDownListFor(x => x.MyPropId, new SelectList(Model.MyValues, "ValueId", "ValueName"), Model.User.IsAdmin || Model.User.HasEditRight)