Views: 5481
Number of votes: 3
Average rating:

ElencySolutions Image Map and Hot Spot Editor v1.0 Released

Introduction

A few weeks ago I was speaking to my colleague Mark Everard (aka “The Doctor”) about a requirement he has for a new EPiServer project.

The client has a requirement to add images but also pick hot spots on the image.  When the image is rendered and a hot spot is clicked a div will fade in.

As I have plenty of spare time on the train and I have not done anything with Silverlight and wanted to get more familiar with it I decided to build an image map editor in Silverlight which will be integrated into EPiServer.

I know there are already open source projects out there for image map editing (most probably better) but I wanted to create my own to get familiar with various concepts within Silverlight and hopefully the properties that have come out of it will be useful to some developers Smile.

The code can be downloaded from codeplex. Beware the code isn’t the tidiest, after all this was a training exercise and I had to learn/change things on the go.  But it works!

Installation

The ElencySolutions.ImageMap.Properties.dll can be downloaded from codeplex.

All you need to do is copy this dll to your EPiServer CMS 6 sites bin folder and the new properties and image map editor will be available to use to use.


Using the Image Map Property

When you add the image map property to a page the edit controls for the property will look like the following:


The property has the following property settings:


Popup height – The height of the editing popup window.

Popup width – The width of the editing popup window.

When you click the “Edit Image Map” button you will be shown an editor like the following:

You will notice there is a Preview button, when this is clicked a preview dialog will be displayed so the editor can test there image map (when in preview mode all link targets will be set to open a new window).


The image map property stores a strongly typed ImageMap object.  When the property is bound to an EPiServer Property control the image map will be rendered.  The ImageMap class also has a GetHtml method which will return the html for the image map.


Using the Hot Spot Property

The hot spot property has the following property settings:

Image url property name – The name of a property that will contain the hot spot image url.

Image height property name – The name of a property that will contain the hot spot image width,

Image width property name – The name of a property that will contain the hot spot image height.

Popup height – The height of the editing popup window.

Popup width – The width of the editing popup window.

Hot Spot Sample Usage

The code and images below demonstrate using the hot spot property within a collection of hot spots by using the ElencySolutions.MultipleProperty Properties.

1. Create a HotSpotItem class

   1:  namespace EPiServer.HotSpots.Entities
   2:  {
   3:      using System;
   4:      using System.Runtime.Serialization;
   5:      using Core;
   6:      using ElencySolutions.ImageMap.Properties;
   7:      using ElencySolutions.MultipleProperty;
   8:      using SpecializedProperties;
   9:   
  10:      [Serializable]
  11:      [DataContract]
  12:      [KnownType(typeof(HotSpotItem))]
  13:      public class HotSpotItem
  14:      {
  15:          public HotSpotItem()
  16:          {
  17:              // initialise default values
  18:              Heading = string.Empty;
  19:              ShortDescription = string.Empty;
  20:              MoreInfoLinkUrl = "#";
  21:              HotSpot = new HotSpot();
  22:          }
  23:   
  24:          [MultiplePropertyEntityProperty(Caption = "Heading",
  25:              Type = typeof(PropertyString),
  26:              SortIndex = 100,
  27:              Required = true)]
  28:          [DataMember]
  29:          public string Heading { get; set; }
  30:   
  31:          [MultiplePropertyEntityProperty(Caption = "Short Description",
  32:              Type = typeof(PropertyString),
  33:              SortIndex = 110,
  34:              Required = true)]
  35:          [DataMember]
  36:          public string ShortDescription { get; set; }
  37:   
  38:          [MultiplePropertyEntityProperty(Caption = "More info link url",
  39:              Type = typeof(PropertyUrl),
  40:              SortIndex = 120,
  41:              Required = false)]
  42:          [DataMember]
  43:          public string MoreInfoLinkUrl { get; set; }
  44:   
  45:          [MultiplePropertyEntityProperty(Caption = "Hot spot",
  46:              Type = typeof(HotSpotProperty),
  47:              SortIndex = 120,
  48:              Required = false,
  49:              PropertySettingsCreator = typeof(HotSpotSettingsCreator))]
  50:          [DataMember]
  51:          public HotSpot HotSpot { get; set; }
  52:   
  53:      }
  54:   
  55:      public class HotSpotSettingsCreator : IMultiplePropertySettingsCreator
  56:      {
  57:          
  58:          public Core.PropertySettings.IPropertySettings CreatePropertySettings()
  59:          {
  60:              HotSpotPropertySettings settings = new HotSpotPropertySettings
  61:                                                     {
  62:                                                         ImageUrlPropertyName = "ImageUrl",
  63:                                                         ImageHeightPropertyName = "ImageHeight",
  64:                                                         ImageWidthPropertyName = "ImageWidth",
  65:                                                         PopupWidth = 800,
  66:                                                         PopupHeight = 380
  67:                                                      };
  68:              return settings;
  69:          }
  70:      }
  71:   
  72:  }


2. Create a HotSpots entity.

   1:  namespace EPiServer.HotSpots.Entities
   2:  {
   3:      using System;
   4:      using System.Collections.Generic;
   5:      using System.Runtime.Serialization;
   6:      using ElencySolutions.MultipleProperty;
   7:   
   8:      [Serializable]
   9:      [CollectionDataContract]
  10:      [KnownType(typeof(HotSpots))]
  11:      [MultiplePropertyEntity(AddButtonText = "Add Hot Spot", ListItemInformationHeader = "Hot Spot")]
  12:      public class HotSpots : List<HotSpotItem>
  13:      {
  14:   
  15:          public override string ToString()
  16:          {
  17:              return MultiplePropertyHelper.SerializeObject(this);
  18:          }
  19:   
  20:      }
  21:  }

3. Create a PropertyHotSpot class.
   1:  namespace EPiServer.HotSpots.CustomProperties
   2:  {
   3:      using System;
   4:      using ElencySolutions.MultipleProperty;
   5:      using PlugIn;
   6:   
   7:      [Serializable]
   8:      [PageDefinitionTypePlugIn(DisplayName = "PropertyHotSpots", Description = "Hot spots picker")]
   9:      public class PropertyHotSpots : MultiplePropertyBase<Entities.HotSpots, Entities.HotSpotItem>
  10:      {
  11:   
  12:          public override string GetListItemDescription(Entities.HotSpotItem entity)
  13:          {
  14:              return string.Format("Heading: {0} (Left: {1}px, Top {2}px)", entity.Heading, entity.HotSpot.Left, entity.HotSpot.Top);
  15:          }
  16:   
  17:      }
  18:  }

4. Add the new PropertyHotSpot to a page type and when editing the hotspots you will see something like the following in edit mode:


When clicking the ellipses button for the hot spot you will be presented with an editor dialog like the following:


5. Custom code and markup will need to be created to render the hotspots, some example markup is below:

 

   1:   <script type="text/javascript">
   2:       $(document).ready(function () {
   3:           $('.hotspot').each(function () {
   4:               $(this).bind('click', function () {
   5:                   var id = '#hotspotpanel_' + $(this).attr('id');
   6:                   $(id).css('display') == "none" ? $(id).fadeIn(300) : $(id).fadeOut(300)
   7:               });
   8:           });
   9:       });
  10:  </script>
  11:  <div id="hotspots">
  12:      <img src="<%=CurrentPage.ImageUrl%>" alt="" height="<%=CurrentPage.ImageHeight%>px" width="<%=CurrentPage.ImageWidth%>px" />
  13:   
  14:      <%
  15:          int index = 0;
  16:          foreach (HotSpotItem currentHotSpot in CurrentPage.HotSpots)
  17:          {%>
  18:   
  19:          <div class="hotspot" id="<%=index%>" style="top:<%=currentHotSpot.HotSpot.Top - 6%>px;left:<%=currentHotSpot.HotSpot.Left - 6%>px">
  20:          &nbsp;
  21:          </div>
  22:          <div class="panel" id="hotspotpanel_<%=index%>" style="top:<%=currentHotSpot.HotSpot.Top - 6%>px;left:<%=currentHotSpot.HotSpot.Left + 12%>px">
  23:          <div class="panelHeading">
  24:              <%=currentHotSpot.Heading%>
  25:          </div>
  26:          <div class="panelContent">
  27:              <%=currentHotSpot.ShortDescription%>
  28:              <br /><br />
  29:              <a href="<%=string.IsNullOrEmpty(currentHotSpot.MoreInfoLinkUrl) ? "#" : currentHotSpot.MoreInfoLinkUrl%>" title="More info">More info</a>
  30:          </div>
  31:          </div>
  32:      <%
  33:              index++;
  34:          }%>
  35:  </div>

 

Below is an example of the rendered hotspots:

 

Globalisation

Unfortunately I have not built any globalisation support into the silverlight app. But all of the text relevant to the image map and hot spot properties in EPiServer is maintainable using the relevant language files.

The settings currently available are below:

   1:  <?xml version="1.0" encoding="utf-8" standalone="yes"?>
   2:  <languages>
   3:    <language name="English" id="en">
   4:      <elencySolutionsImageMap>
   5:        <imageUrl>Image url</imageUrl>
   6:        <imageHeight>Image height</imageHeight>
   7:        <imageWidth>Image width</imageWidth>
   8:        <imageAltText>Image alt text</imageAltText>
   9:        <editImageMap>Edit Image Map</editImageMap>
  10:        <left>Left</left>
  11:        <top>Top</top>
  12:        <hotSpotPropertySettings>Hot Spot Property Settings</hotSpotPropertySettings>
  13:        <imageMapPropertySettings>Image Map Property Settings</imageMapPropertySettings>
  14:        <imageUrlPropertyName>Image url property name</imageUrlPropertyName>
  15:        <imageHeightPropertyName>Image height property name</imageHeightPropertyName>
  16:        <imageWidthPropertyName>Image width property name</imageWidthPropertyName>
  17:        <popupHeight>Popup height</popupHeight>
  18:        <popupWidth>Popup width</popupWidth>
  19:        <popupHeightRequired>You must enter a popup height</popupHeightRequired>
  20:        <popupWidthRequired>You must enter a popup width</popupWidthRequired>
  21:        <popupHeightValidation>You must enter a valid popup height</popupHeightValidation>
  22:        <popupWidthValidation>You must enter a valid popup width</popupWidthValidation>
  23:        <specifyImageWidthAndHeight>You must specify an image, height and width</specifyImageWidthAndHeight>
  24:        <defaultLinkUrl>Default link url</defaultLinkUrl>
  25:        <sameWindow>Same window</sameWindow>
  26:        <newWindow>New window</newWindow>
  27:        <target>Target</target>
  28:        <defaultLinkTarget>Default link Target</defaultLinkTarget>
  29:      </elencySolutionsImageMap>
  30:    </language>
  31:  </languages>


Feedback?

I am always eager to receive feedback good and bad. 

Please feel free to email or twitter me with any feedback @croweman or comment on the blog post Smile


Disclaimer

Although I have tested the assembly and am happy with it’s functioning there may well be little bugs that I have not spotted.  Please give it a thorough test before releasing it to the production environment and log any issues on codeplex.

    (By Mark Everard , 21 April 2011 12:48, Permanent link)

    Awesome stuff as always Lee, and not just because you're building code for my requirements - though that is a large part of it ;)

    Loving the right eye image!

    (By Lee Crowe , 21 April 2011 12:51, Permanent link)

    Thanks Mark. Always a pleasure to be of service :)

    (By Kirolos Gerges , 23 July 2015 14:15, Permanent link)

    Using EPiServer CMS 8 the "Edit image Map" is not popping up any editor. Are there other alternatives compatible with EPiserver 8?

    (By Mark Armitage , 23 September 2015 16:19, Permanent link)

    Hi,

    I'm using this in a load balanced environment and have found that when an image is selected and I click the Edit Image Map button the popup loads with the a message "You must specify an image" however if I access via one of the sites under the load balancer directly it works as expected. Have you seen this behaviour before and know how to fix it?

    Thanks,

    Mark

  Please login to post a comment