Highlight text programmatically

Please post all questions and comments regarding Help & Manual 7 here.

Moderators: Alexander Halser, Tim Green

Post Reply
Ken Zahrt
Posts: 8
Joined: Fri Nov 10, 2017 1:45 am

Highlight text programmatically

Unread post by Ken Zahrt »

Hi, I'm new to Help & Manual and this forum. I've done some help authoring a long time ago, but my expertise is in software development and project management. I just purchased H+M 7 to do some help for an app I'm working on and have a question.

What I'd like to do is to allow a user to click on a hotspot on a picture and have my HTML help respond by highlighting some relevant text elsewhere on the same page.

For example: I have a picture of a dialog box with several edit boxes on it, each of which has a hotspot. Elsewhere on the page is a text string. Each of the edit boxes provides the text for its own segment of the string. When the user clicks on one of the edit controls, I want its segment of the string to become highlighted and all the other segments resume the transparent background, thus illustrating where that edit box's text winds up in the string.

Is it possible to do this? Is there some kind of link or other tool that would do this simply?

I suspect that I could do this with a script link. If I were to break the string into segments in the XML, then perhaps a script could clear the background on all the segments and set it for the proper segment. Problem is, I don't know enough about scripting to write something like this, so:

Does this sound like a feasible approach?

Where is a good place to go to learn about writing a script such as I described above?

Has anyone written a script like this that I might be able to take a look at?

Thanks,

Ken
User avatar
Tim Green
Site Admin
Posts: 23155
Joined: Mon Jun 24, 2002 9:11 am
Location: Bruehl, Germany
Contact:

Re: Highlight text programmatically

Unread post by Tim Green »

Hi Ken,

This is relatively easy to script since Help+Manual pages always have jQuery integrated, which makes it a lot easier to reference things on the page. First you need to add the script for highlighting the element you are going to show on the page to your skin:
  1. Open the .hmskin file you are going to be using to publish in Help+Manual and in the Project Explorer on the left navigate down to Configuration > HTML Page Templates > Default.
  2. Locate the closing </head> tag in the source code of the template and insert this directly before it:

    Code: Select all

    <script>function hiliteText(target) {
       var $tg = $(target);
       if ($tg.css("background-color") == "transparent")
           $tg.css("background-color","yellow");
       else
           $tg.css("background-color","transparent");
    }</script>
You can change "yellow" for the highlight to any CSS color name or code you want to use. Yellow is usually a good choice, however.

Next you need to tag the text that you want to highlight in your topics. You need to do this with the HTML Code Object tool in the Write > Insert Object tab. Use a DIV tag for an entire paragraph and a SPAN tag for text within a paragraph. It goes like this:
  1. Click at the beginning of the text to highlight, open the Code Object Tool and enter this for a full paragraph or multiple paragraphs:

    Code: Select all

    <div id="hl1">
    or this for text within a paragraph:

    Code: Select all

    <span id="hl1">
    The id attribute can be anything you like but it must be unique in the topic. Make sure that the option HTML code must not be enclosed in a block tag is ON!
  2. Then go to the end of the text to be highlighted and enter another HTML code object containing just </div> to close the DIV version or </span> to close the SPAN version. Again, make sure that the option HTML code must not be enclosed in a block tag is ON!
Now you just need to create your script links in your image hotspots to turn the highlighting on and off when the user clicks it. Make a note of the id attribute from the DIV or SPAN you entered. Then double-click on the image in the HM editor, click on Hotspots to open the hotspot editor and choose the script link option with HTML JavaScript as the mode and enter the following in the script box:

Code: Select all

javascript:hiliteText('#hl1');
This is for the hl1 ID for the example from above. You need to enter the specific ID of the text you want to highlight in practice. Note that it's VERY important to use single quotes around the ID attribute here, otherwise you will just get an error. You must also include the # character before the ID, otherwise the text won't be found. Then the text will get highlighted when the user clicks and returned to transparent when they click again.
Regards,
Tim (EC Software Documentation & User Support)

Private support:
Please do not email or PM me with private support requests -- post to the forum directly.
Ken Zahrt
Posts: 8
Joined: Fri Nov 10, 2017 1:45 am

Re: Highlight text programmatically

Unread post by Ken Zahrt »

Thanks, Tim. This looks like exactly what I want and it should be easy to implement. I have some questions, though, if you don't mind.

I will need to define a persistent variable to keep the ID of the last element that was highlighted, so that I can turn if off. I tried doing the following to do this, but when I click on the hotspot, a page that says: "Can't reach this page" is displayed.

I know that you said that it was important that I put a # in front of the ID and surround them both with single quotes, but I don't know how to use the single quotes when I'm passing the value of a variable to hiliteText. I also changed hiliteText to take a Boolean to indicate if I wanted to clear or set. Here's what I wrote (I should tell you this is the first javascript or jQuery that I have ever written.):

My two link scripts, which I entered using the H&M hotspot editor:

Code: Select all

// This is the variable I want to persist.
var lastID = "";

if (lastID != "")
    hiliteText(lastID, false); 
lastID = '#hlRailroad';
hiliteText(lastID,true);
and

Code: Select all

// This is the variable I want to persist.
var lastID = "";

if (lastID != "")
    hiliteText(lastID, false);
lastID = '#hlDivision';
hiliteText(lastID,true);
I doubt that lastID will persist when written this way, but I don't know how to declare it to do that.

Being brand new to H&M, I'm not using a skin yet, so I went to the configuration, as you said, and found what looks like a default file, and that's where I put the hilitText script. Here's the whole thing, with the script just before the </head>:

Code: Select all

<%DOCTYPE%>
<html>
<head>
   <title><%TOPIC_TITLE%></title>
   <meta name="generator" content="Help & Manual" />
   <meta name="keywords" content="<%TOPIC_KEYWORDS%>" />
   <meta http-equiv="Content-Type" content="text/html; charset=<%DOCCHARSET%>" />
   <IF_CHM><meta http-equiv="X-UA-Compatible" content="IE=9" /></IF_CHM>
   <IF_HTML><meta http-equiv="X-UA-Compatible" content="IE=edge" /></IF_HTML>
   <meta name="description" content="<%TOPIC_DESCRIPTION%>" />
   <meta name="picture" content="<%TOPIC_PICTURE%>" />
   <link type="text/css" href="<%STYLESHEET%>" rel="stylesheet" />
   <style type="text/css">
     body { margin: 0px; background: #FFFFFF; }
   </style>
   <script>function hiliteText(target, hilite) {
      var $tg = $(target);
      if (hilite)
          $tg.css("background-color","yellow");
      else
          $tg.css("background-color","transparent");
   }</script>
</head>
<body>

<IF_TOPIC_HEADER>
<table style="width:100%; border:none; border-spacing:0px; padding:5px; background:#4D4D4D">
  <tr style="vertical-align:middle">
    <td style="text-align:left">
      <%TOPIC_HEADER%>
    </td>
    <td style="text-align:right">
     <a href="<%HREF_DEFAULT_PAGE%>">Top</a>&nbsp;
     <IF_PREVIOUS_PAGE><a href="<%HREF_PREVIOUS_PAGE%>">Previous</a>&nbsp;</IF_PREVIOUS_PAGE>
     <IF_NEXT_PAGE><a href="<%HREF_NEXT_PAGE%>">Next</a></IF_NEXT_PAGE>
    </td>
  </tr>
</table>
</IF_TOPIC_HEADER>

<!-- Placeholder for topic body. -->
<table style="width:100%;border:none;border-spacing:0px"><tr style="vertical-align:top"><td style="text-align:left;padding:5px">
<%TOPIC_TEXT%>
</td></tr></table>

</body>
</html>
And the text string, showing the two spans I created, using the Code Object Tool.

Code: Select all

<para styleclass="Body Text" style="margin-top:10px; margin-right:10px; margin-left:10px;"><html-code width="100" height="16" inline="true" translate="true"><![CDATA[<span id="hlRailroad">
]]></html-code><text styleclass="Body Text" translate="true">PCo.PFtW&C</text><html-code width="100" height="16" inline="true" translate="true"><![CDATA[</span>
]]></html-code><text styleclass="Body Text" translate="true">.v01.0a.IN-21 1916r32c54p22w18</text><html-code width="100" height="16" inline="true" translate="true"><![CDATA[<span id="hlDivision">
]]></html-code><text styleclass="Body Text" translate="true"> Ft. Wayne Div</text><html-code width="100" height="16" inline="true" translate="true"><![CDATA[</span>
]]></html-code><text styleclass="Body Text" translate="true"> Some notes Smithville Branch [B&O.v01.IN-12] [joint with CV&M] - Fort Wayne [Reading Co. Agreement] Property List PL_B033-Li400i.tif</text></para>
One final thing: I couldn't find anything in the H&M help telling me how to debug a script. Where can I find instructions to do that?

Thanks,

Ken
Ken Zahrt
Posts: 8
Joined: Fri Nov 10, 2017 1:45 am

Re: Highlight text programmatically

Unread post by Ken Zahrt »

Hi Tim,

I just noticed that I forgot to put javascript: in front of my calls to hiliteText. I made that change to both scripts but still got the same result.

Code: Select all

var lastID = ""; 

if (lastID != "")
    javascript:hiliteText(lastID, false); 
lastID = '#hlRailroad'; 
javascript:hiliteText(lastID,true);
and

Code: Select all

var lastID = ""; 

if (lastID != "")
    javascript:hiliteText(lastID, false); 
lastID = '#hlDivision'; 
javascript:hiliteText(lastID,true);
User avatar
Tim Green
Site Admin
Posts: 23155
Joined: Mon Jun 24, 2002 9:11 am
Location: Bruehl, Germany
Contact:

Re: Highlight text programmatically

Unread post by Tim Green »

Hi Ken,

You can't enter scripts in the hotspot editor. At least, not like that. Scripts from the hotspot are simply added to the href="" attribute of the link, so they will fail completely as soon as you use a carriage return or a double quote, and you are using both. 8) You need to rewrite the function you are using to include those capabilities, not try to put them in the hotspot link. That should really only contain the call to the function -- or you need to edit it externally and serialize everything into a single line without any double quotes.
I just noticed that I forgot to put javascript: in front of my calls to hiliteText. I made that change to both scripts but still got the same result.
When you do it like that failure occurs long before you reach the javascript:, which needs to be at the beginning. You would need this instead (example):

Code: Select all

javascript: var lastID = '';if (lastID !='') hiliteText(lastID,false);lastID='#hlRailroad';hiliteText(lastID,true);
Also, the call hiliteText(lastID, false); will do nothing unless you have rewritten the function to accept two arguments.
One final thing: I couldn't find anything in the H&M help telling me how to debug a script. Where can I find instructions to do that?
You wouldn't do that in Help+Manual. You would do it in the browser, just as with any JavaScript, by opening the JS console with F12.

You don't need to store the state to switch off, there is an easier way to do it. You just need to switch all the targets on the page off every time you start, then switch the current one as needed. To do this you need to add a class to the targets so that you can access all of them at the same time:

Code: Select all

<div id="hl1" class="hstarget">
and
<span id="hl1" class="hstarget">
Then replace the script with this:

Code: Select all

<script>function hiliteText(target) {
   var $tg = $(target), $tall = $(".hstarget"), dohl = true;
   if (target=="off") {
    $tall.css("background-color","transparent");
    return;
  }
   if ($tg.css("background-color") != "transparent")
       dohl = false;
   $tall.css("background-color","transparent");
   if (dohl)
       $tg.css("background-color","yellow");
}</script>
This version of the script also allows you to create a hotspot that will only turn off all the highlights, to provide a "Highlights Off" button. You just need to enter the following as the hotspot script:

Code: Select all

javascript:hiliteText('off');
Regards,
Tim (EC Software Documentation & User Support)

Private support:
Please do not email or PM me with private support requests -- post to the forum directly.
Ken Zahrt
Posts: 8
Joined: Fri Nov 10, 2017 1:45 am

Re: Highlight text programmatically

Unread post by Ken Zahrt »

Hi Tim,

I see what you're getting at and have made the changes as, I hope, you told me to, but now I'm getting the following script error:
Script Error - 01.png
The script error indicates that it's having trouble finding hiliteText, and I've checked to make sure I didn't mistype it, and it's good. I'm wondering, though. In your first response, you told me I should put the script into my skin file, but as I'm not using a skin, I put it in the code that was in the Default tab when I brought up Configuration->HTML Page Templates->Default. Could that be the problem? Do I have to use a skin in order to do this?

I tried to upload my project file, but it wouldn't accept either the .hmxz or .zip file, so I'm attaching some images so you can see what I've done.
Turn Yellow Script - 01.png
File Information Dialog Box - 01.png
More images in next response...

Thanks,

Ken
You do not have the required permissions to view the files attached to this post.
Ken Zahrt
Posts: 8
Joined: Fri Nov 10, 2017 1:45 am

Re: Highlight text programmatically

Unread post by Ken Zahrt »

To continue...

This is the HTML code that was generated when I used the Insert HTML code object tool:
String HTML - 01.png
And the hotspot scrips:
Hotspot Editor - 01.png
The word wrap in the script was done by the editor - I typed it all as one line - no spaces or LFs.

I think that covers everything you should need to see, but let me know if you need to see any more. If you want me to send you my project file, that's fine, but the board would not let me upload either a .hmxz or .zip file.

Sorry to be such trouble for something that is seemingly so easy.

Thanks,

Ken
You do not have the required permissions to view the files attached to this post.
Ken Zahrt
Posts: 8
Joined: Fri Nov 10, 2017 1:45 am

Re: Highlight text programmatically

Unread post by Ken Zahrt »

Just noticed that I didn't have the semicolon at the end of either of my calls "javascript:hiliteText('#hlRailroad');". I made that change and ran it again, but I still get the same script error. :frustration:

-Ken
User avatar
Tim Green
Site Admin
Posts: 23155
Joined: Mon Jun 24, 2002 9:11 am
Location: Bruehl, Germany
Contact:

Re: Highlight text programmatically

Unread post by Tim Green »

Hi Ken,

Please mail me your project at support AT ec-software.com (replace the AT with @) and I'll check it for you. This will be a lot faster and easier than trying to guess via the forum. 8)
Regards,
Tim (EC Software Documentation & User Support)

Private support:
Please do not email or PM me with private support requests -- post to the forum directly.
Ken Zahrt
Posts: 8
Joined: Fri Nov 10, 2017 1:45 am

Re: Highlight text programmatically

Unread post by Ken Zahrt »

On its way to you. Thanks!
User avatar
Tim Green
Site Admin
Posts: 23155
Joined: Mon Jun 24, 2002 9:11 am
Location: Bruehl, Germany
Contact:

Re: Highlight text programmatically

Unread post by Tim Green »

Hi Ken,

Thanks for the project. These were the problems:
  • Overlapping span tags
    The ending span tags were between other tag pairs. Your tags need to begin and end as single units, like this:

    Code: Select all

    <span> xxxxx </span><span>xxxx</span><span>xxxxxx</span>
  • Missing class attributes
    Only your first span tag has the class="hstarget" attribute. You need it in all of them.
  • You are using a skin, so the HTML page template edit is not being used
    If you look in the Publish screen you will see that skins are selected for both your CHM and your WebHelp output (Select Skin bar). Click on the bar and select "remove skin" at the bottom. If you want to use a skin then you need to edit the .hmskin file and add the script to the page template there.
Regards,
Tim (EC Software Documentation & User Support)

Private support:
Please do not email or PM me with private support requests -- post to the forum directly.
Ken Zahrt
Posts: 8
Joined: Fri Nov 10, 2017 1:45 am

Re: Highlight text programmatically

Unread post by Ken Zahrt »

Thanks, Tim. It works great and is now doing exactly what I wanted it to do. :D
Post Reply