Friday, 4 July 2014

Tooltip Data Annotation

I am a fan of Data Annotations, I like the fact I can define stuff in one place and it works everywhere.
One thing I felt that was missing is a tooltip annotation, which then using the technique discussed in “Standardising through HTML helpers

Coding the Data Annotation

The Data Annotation is going to look like this
   [StringLength(255)]
   [DisplayName("Colour")]
   [ToolTip("This is the colour used in the Project Management Page,
 please use html colours.")]
   public string PriorityColour { getset; }
To create the data annotation is simple and documented here, but this is the code.

 public class ToolTipAttribute : DescriptionAttribute

 {
     public ToolTipAttribute()
         : base("")
     {

     }

     public ToolTipAttribute(string description)
         : base(description)
     {

     }
 }

Adding the Data Annotation to myTextboxFor

Depending on your JS control set of choice you may need to amend this slightly. I am using Bootstrap.
The first step is getting the tooltip from the Data Annotation, to do this we are going to get all of the Member Expressions from the Model.
As I have a number of different myxxxFor, I do this in a separate function. which is relatively simple, it is a case of iterating through the MemberExpressions until you find the tooltip and then returning the string.
private static string GetToolTipFromAnnotation(MemberExpression memberExpression)
   {
       string toolTip = "";

       foreach (Attribute attribute in memberExpression.Expression.Type 
.GetProperty(memberExpression.Member.Name).GetCustomAttributes(false))
       {
           if (typeof(ToolTipAttribute== attribute.GetType())
           {
               toolTip = ((ToolTipAttribute)attribute).Description;
           }
       }

       return toolTip;
   }

Calling this code from the MyTextBoxFor code is
string toolTip = GetToolTipFromAnnotation((MemberExpression)expression.Body);

Then we need to add some additional classes to our input class, 
in the last blog we had MyTextboxFor returning this.
return helper.TextBoxFor(expression, formatString, new { @class = additionalClass});

To include the tooltip we need a bit more.
return helper.TextBoxFor(expression, formatString, new {@class = additionalClass 
" tooltipHolder"@data_toggle = "tooltip"@data_content = toolTip});

Then on your page call the popover (or tooltip, I use popover as 
I prefer the look and feel.)
$(".tooltipHolder").popover({ trigger'hover' });
As usual the code is examples and may need more or less work for you but 
I hope it helps.