Try our conversational search powered by Generative AI!

Lee Crowe
Apr 21, 2011
  8292
(3 votes)

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.

Apr 21, 2011

Comments

Apr 21, 2011 12:48 PM

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!

Apr 21, 2011 12:51 PM

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

Kirolos Gerges
Kirolos Gerges Jul 23, 2015 02:15 PM

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

Mark A
Mark A Sep 23, 2015 04:19 PM

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 comment.
Latest blogs
Fix your Search & Navigation (Find) indexing job, please

Once upon a time, a colleague asked me to look into a customer database with weird spikes in database log usage. (You might start to wonder why I a...

Quan Mai | Apr 17, 2024 | Syndicated blog

The A/A Test: What You Need to Know

Sure, we all know what an A/B test can do. But what is an A/A test? How is it different? With an A/B test, we know that we can take a webpage (our...

Lindsey Rogers | Apr 15, 2024

.Net Core Timezone ID's Windows vs Linux

Hey all, First post here and I would like to talk about Timezone ID's and How Windows and Linux systems use different IDs. We currently run a .NET...

sheider | Apr 15, 2024

What's new in Language Manager 5.3.0

In Language Manager (LM) version 5.2.0, we added an option in appsettings.json called TranslateOrCopyContentAreaChildrenBlockForTypes . It does...

Quoc Anh Nguyen | Apr 15, 2024

Optimizely Search & Navigation: Boosting in Unified Search

In the Optimizely Search & Navigation admin view, administrators can set a certain weight of different properties (title, content, summary, or...

Tung Tran | Apr 15, 2024

Optimizely CMS – Getting all content of a specific property with a simple SQL script

When you need to retrieve all content of a specific property from a Page/Block type, normally you will use the IContentLoader or IContentRepository...

Tung Tran | Apr 15, 2024