0

I'm trying to use maphilight in my ASP.NET C# page to allow you to hover over a cell in a gridview control and highlight an area (hotspot) in an illustration below, similar to how it's done in the maphilight feature demo (see "Mouse over this to trigger... on that page). It would be helpful to click the cell to turn on/off the highlights. Finally, I want to be able to click on the hotspot to highlight gridview rows. I'm having all sorts of trouble and am wondering if a) I could be more successful by using a different approach or b) I am using the right approach but need to tweak my solution a bit.

Here's the background:

  1. My gridview data is populated from a database.
  2. There may be multiple rows in the gridview that link to the same hotspot.
  3. The is also populated from the database.
  4. I'm using an imagemap with tags to allow the user to click on an illustration hotspot and highlight the gridview row.

I've gotten #4 to work. When it's just a regular <asp:ImageMap>, I can populate it from codebehind and set the hotspot links to include a Request.QueryString to this same page, which I then use to highlight every applicable gridview row. That's not really an issue.

Question #1 How can I add an ID to the gridview hyperlink, per maphighlight requirements? I know that in order for the maphighlight javascript to work, the hyperlink anchor needs an ID; however, adding an eval statement in the id field throws an error stating that "The server tag is not well formed":

<asp:GridView ID="Listing" runat="server" CssClass="table table-bordered" OnRowDataBound="Listing_RowDataBound" >
<Columns>
    <asp:BoundField HeaderText="Index" DataField="index_number" />
    <asp:TemplateField HeaderText="Item Number">
    <ItemTemplate>
        <asp:HyperLink ID="hyperlink<%# Eval("item_number")%>" runat="server"><%# Eval("item_number")%></asp:HyperLink>
    </ItemTemplate>
    </asp:TemplateField>
    <asp:BoundField HeaderText="Part Number" DataField="part_number" />
    <asp:BoundField HeaderText="Description" DataField="description" />
    <asp:BoundField HeaderText="Qty" DataField="quantity" />
</Columns>
</asp:GridView>

So I tried to use codebehind to add an ID to the <a>:

protected void Listing_RowDataBound(object sender, GridViewRowEventArgs e)
{
    foreach (GridViewRow row in HKDetailsDataView.Rows)
    {
        row.Cells[3].Attributes.Add("id","hyperlink" + row.Cells[3].Text);
    }
}

But it adds the ID to the TD, not the hyperlink, and the Text attribute is blank.

<td id="hyperlink">
    <a>1</a>
</td>

Question #2 How can I populate <img>, <map>, and <area> tags for multiple illustrations? I've been able to get an <asp:ImageMap> tag working...but I can't remember the specifics. But maphilight needs an HTML <map> and <area> tags to work. My current (non-functional) attempt is to use an <asp:Repeater> to populate the map and area tags, but it only half works: the area half.

This repeater:

<asp:Repeater ID="IllustrationRepeater" runat="server" OnDataBinding="IllustrationRepeater_DataBinding" OnItemDataBound="IllustrationRepeater_ItemDataBound" >
    <HeaderTemplate>
    <asp:PlaceHolder ID="image_placeholder" runat="server" />
    <asp:PlaceHolder ID="map_placeholder" runat="server" />
    </HeaderTemplate>
    <ItemTemplate>
    <asp:Label id="universal_resource_locator" runat="server" Text='<%#Eval("universal_resource_locator") %>' Visible="false" ></asp:Label>
    <asp:Label id="document_id" runat="server" Text='<%#Eval("document_id") %>' Visible="false" ></asp:Label>
    <area id="hotspot" 
        shape='<%#Eval("link_type") %>' 
        coords='<%#Eval("circle_center_x") %>,<%#Eval("circle_center_y") %>,<%#Eval("circle_diameter") %>'
        href='/rpstl/hk_details_new?figure_number=<%#Eval("figure_index_number") %>&item_number=<%#Eval("item_number") %>'
        title='<%#Eval("item_number") %>'
        alt='<%#Eval("item_number") %>' 
        target="_self" 
        class='group<%#Eval("item_number") %>}' 
        data-maphilight='{"groupBy":group<%#Eval("item_number") %>}' />
    </ItemTemplate>
    <FooterTemplate>
    </map>
    </FooterTemplate>
</asp:Repeater>

generates this HTML:

<area id="hotspot" 
    shape='circle' 
    coords='12,19,25'
    href='/rpstl/hk_details_new?figure_number=172&item_number=1'
    title='1'
    alt='1' 
    target="_self" 
    class='group1}' 
    data-maphilight='{"groupBy":group1}' />
<area id="hotspot" 
    shape='circle' 
    coords='505,311,25'
    href='/rpstl/hk_details_new?figure_number=172&item_number=1'
    title='1'
    alt='1' 
    target="_self" 
    class='group1}' 
    data-maphilight='{"groupBy":group1}' />
<area id="hotspot" 
    shape='circle' 
    coords='12,48,25'
    href='/rpstl/hk_details_new?figure_number=172&item_number=2'
    title='2'
    alt='2' 
    target="_self" 
    class='group2}' 
    data-maphilight='{"groupBy":group2}' />

I think this should work; however, if there are three illustrations, I need three separate <map> tags, with the corresponding <area> tags contained in each. And as I've found out, you cannot process an Eval in the header template. To work with maphilight, I'd need an individual <map> opening tag with a unique name attribute for each illustration. I've got a function to replace the two placeholders, but it's not working to generate the tags:

protected void IllustrationRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Header)
    {

        ** INSERT CODE TO RETRIEVE URL AND DOCUMENTID **
        
        var url = "";
        var documentId = "";

        if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(documentId))
        {
        PlaceHolder imagePlaceHolder = FindControl("image_placeholder") as PlaceHolder;
        Image image = new Image();
        image.Attributes.Add("src", url);
        image.Attributes.Add("class", "map");
        image.Attributes.Add("usemap", documentId);
        IllustrationRepeater.HeaderTemplate.InstantiateIn(image);

        PlaceHolder mapPlaceHolder = FindControl("map_placeholder") as PlaceHolder;
        ImageMap map = new ImageMap();
        map.Attributes.Add("name", documentId);
        map.Attributes.Add("id", documentId);
        IllustrationRepeater.HeaderTemplate.InstantiateIn(image);
    }
}

I can pull the DataTable that populated the repeater from a ViewState variable that I stored it in when I populated the repeater from the database, but I'm not sure how to find the right record since I don't know which illustration is being used, and I can't retrieve data from the repeater item since the header appears to populate before any items are populated.

Question #3 Is there an easier or more efficient way to do this than using maphilight, due to all of the issues above?

Brig Cook
  • 21
  • 5

0 Answers0