Page 1 of 2

How do I make a menu option show underline on a mouse over?

Posted: Mon Feb 09, 2015 5:37 pm
by rmarsh
I'd like my menu options to underline on a mouse over event.

How do I do this?

Re: How do I make a menu option show underline on a mouse over?

Posted: Mon Feb 09, 2015 11:19 pm
by Scott Klement
Hi Ray,

Are you referring to our "Detect Menus" feature in Genie? Currently it shows a "reverse image" when you mouse over a menu option, but you want to show an underline instead?

Or do you mean you want to write your own underlining routine, unrelated to our detect menus?

Can you show an example?

Re: How do I make a menu option show underline on a mouse over?

Posted: Tue Feb 10, 2015 1:47 pm
by rmarsh
What I'm working with is a screen comprised of subfile windows that function as a menu for a 3rd party software package that we use.

I've reformated the screen and hidden the selection boxes. When you click on a menu item it fills the selection box with an 'X' and does a presskey("Enter"). This works fine. I've tried to change the field using js in the onmouseover event with no luck. No results at all actually. I'd like to have some sort of visual cue to the user that the menu line is clickable.
SFLMenuHybrid.JPG
SFLMenuHybrid.JPG (37.57 KiB) Viewed 2664 times
SFLMenuGS.JPG
SFLMenuGS.JPG (73.24 KiB) Viewed 2664 times

Re: How do I make a menu option show underline on a mouse over?

Posted: Tue Feb 10, 2015 1:54 pm
by Scott Klement
This would normally be done in the CSS for your skin.

For example, if you wanted it to show an underline when the mouse hovers over a link, you'd do something like this:

Code: Select all

a:hover {
    text-decoration: underline;
}
That's just off the top of my head, you'll want to look at what's in the CSS already and incorporate this into that.

Re: How do I make a menu option show underline on a mouse over?

Posted: Wed Feb 11, 2015 4:00 pm
by rmarsh
I found that changing the css class of the element to A20 will cause it to inherit this behavior. A20 is the class used in the creation of command key buttons. I did find that it only worked at the screen level if I changed the field type to hyperlink. Textbox and output field did not work.

One thing I am trying to fix is the underline when the text is shorter than the field length.
UnderlineMenuItem.png
UnderlineMenuItem.png (2.93 KiB) Viewed 2655 times
I'd like to have only the words underlined. I tried replacing the trailing &sbsp to no avail. Here is a code snippet.

Code: Select all

var a = getOutputFields();
for (var i = 0; i < a.length; i++) 
{
 ...
        a[i].innerHTML = get(a[i]);
        applyProperty(a[i],"field type","hyperlink");
        applyProperty(a[i],"css class","A20");
 ...
}
The get() trims out the &nbsp; just fine but the applyProperty puts them back. If I put the get() last then it seems to undo the property settings.

Re: How do I make a menu option show underline on a mouse over?

Posted: Wed Feb 11, 2015 4:56 pm
by Scott Klement
A20 is the class used for anything with a 5250 "display attribute" of x'20', which is the "normal green text" display attribute in 5250... it shouldn't have an underline on it?

I don't think I would force your hyperlinks to use A20. Instead, define a new CSS class 'CrackerLink' (or whatever makes sense to you) and apply that...

Are you only calling get() because it trims the blanks from the field?

I think I'd have to play with it to understand it...

Re: How do I make a menu option show underline on a mouse over?

Posted: Wed Feb 11, 2015 6:47 pm
by Scott Klement
Now that I have a copy of your skin, if you can make me a Ctrl-F9 of this screen, I can try it in your skin and see what it does... then I could look at how to fix the issue with the blanks.

Re: How do I make a menu option show underline on a mouse over?

Posted: Wed Feb 11, 2015 6:53 pm
by rmarsh
I'll try creating a new class and see if that works better.

The reason I used A20 is because I saw this in the css file for the skin.

Code: Select all

DIV.A20 A, A {
  font-family: sans-serif;
  font-size: 12px;
  font-weight: bold;
  color: #0067C3;
  text-decoration: none;
}
DIV.A20 A:hover {
  text-decoration: underline;
}
When I changed the field type to hyperlink and the css class to A20 I got the underline and the finger pointer cursor behavior on hover. Without the A20 class I only got the finger. O_o

Yes I was trying to remove the &nbsp from the field to hopfully have a nice clean underline of only the menu item title. e.g. Master Files instead of Master Files .

Re: How do I make a menu option show underline on a mouse over?

Posted: Thu Feb 12, 2015 2:06 am
by Scott Klement
Ray,

No need to send the Ctrl-F9 json.txt, I found that you had already sent us this previously in the following thread -- So, I got it now.. no need to send it.
http://www.profoundlogic.com/forum/view ... 5&start=10

I took a look at this in the skin you sent me (and also reviewed that other thread that discusses the replaceidots() function), and I see what the problem is! You're modifying innerHTML directly, and it's causing some strange results.

When your screen is received from the server, Genie is saving all the screen info (with all of it's widget properties, et al) into a complex data structure array in memory. We'll call this "Genie Data". Next, it runs through the "Genie Data" and builds the HTML elements so that the screen is built, etc, so you can screen the screen in your browser. Once that is complete, of course, it runs your screen's onload function.

You are doing applyProperty(myWidget, "field type", "hyperlink") -- which asks Genie to go back to the "Genie Data" and re-draw the widget as a hyperlink instead of as an output field. So far, so good...

The problem is, you have code that's changing the innerHTML of these elements -- but this is just changing the HTML directly, it is not changing the underlying "Genie Data"! So when you change innerHTML and then apply the "field type" property, it's discarding your innerHTML and re-building it from the Genie data -- and therefore you are losing your changes. That's why doing innerHTML = get(the-widget) is being lost, because you do it before apply the field type...

The other problem you noticed is that if you move the innerHTML change to after applying the field type, it will no longer be a hyperlink. This is because the innerHTML of a hyperlink widget looks like this (using HTML to illustrate it)

Code: Select all

<div id="my-widget">
   <a href="javascript:void(0)">Text On Screen Here (with trailing blanks)</a>
</div>
So if you retrieve "my-widget" and then change the innerHTML to "Text on Screen Here", you are wiping out the <a> tag, and therefore it's no longer a link, it's just text on the screen.

Yet another problem is that -- I think you forgot -- the replaceidots() function runs after you're doing this code... so at this point in the process, the data still contains ". . . " at the end of the field, so trimming the blanks at this point won't work anyway, you'll need to do the replaceidots() before you do the get() to trim the data.... buuuuut... that brings up yet another problem, in that replaceidots() also modifies innerHTML directly as well, so if you do it before applying the field type, you'll lose your changes...

Finally, there's also the problem I mentioned earlier in that you are applying the A20 class, which isn't really the correct thing to do here. However -- this isn't actually causing any of your problems right now... using A20 is a bad idea, but it's not one of the problems at hand. Let me explain: The A20 glass is supposed to denote "normal" text on the screen, and it is used widely in all 5250 screens you display. Right now it's configured to show underlines when there is a link inside an A20 class widget, and you mouse-over those... so it will work for you. However, forcing all of your links to A20 is a bad idea because if you ever decide to change the color, font, etc of "plain green text" in Genie, it'll end up affecting your links too, and that's not what you want! Or, conversely, if you ever want to change the way these links look, changing the A20 class to do that will end up changing all "plain green text" on all 5250 screens. So you don't want to use the "A20" class, not because it won't work, but because it locks these links into always having the same formatting as plain green text -- which I don't think is what you want. If you use a separate class, you can maintain them separately.

Okay, this message is getting very long, so to summarize:

1) When you change innerHTML directly, you're not updating the underlying "genie data". You can use applyProperty(), changeElementValue() or pui.set() instead of modifying the innerHTML, and this will update the underlying "genie data", too.

2) replaceidots() should be run before this loop that is trimming blanks from the links -- but this also needs to be modified to update the genie data, not just the innerHTML.

3) You should not try to set the innerHTML of a hyperlink widget, since it'll wipe out the HTML <a> tag which is what makes it into a link.

4) You should create your own class rather than A20, not because A20 won't work (it will) but because down the road you may not want these links to always share the same styling as A20 (which stands for "plain green text")

Hope that makes sense. Since this message is getting too long, I will start a new one to tell you exaclty what I advise changing.

Yet another problem is that you are also modifying the innerHTML in the "replaceidots()" function.

Re: How do I make a menu option show underline on a mouse over?

Posted: Thu Feb 12, 2015 2:32 am
by Scott Klement
Step 1: Create a class to enable hyperlinks.

Lots of possibilities here, depending on how you want these to look -- but for now, we'll pick the same settings that A20 has since you seem to like that look. Add this code on to the end of your "Cracker Barrel Hybrid.css" file:

Code: Select all

/* The basic attributes of the link.  Sets the font, size, boldness, color. */
DIV.mylink A {
  font-family: sans-serif;
  font-size: 12px;
  font-weight: bold;
  color: #0067C3;
  text-decoration: none;
}

/* when mouse hovers over "mylink", add the underline */
DIV.mylink A:hover {
  text-decoration: underline;
}
Save changes. Click "Refresh" on the Genie toolbar to load the new copy of the CSS file into your browser. Note that "mylink" is an example name only -- pick whatever you prefer.

Step 2: Fix the replaceidots() function so it updates the genie data, not just innerHTML.

Right now you have this in replaceidots():

Code: Select all

function replaceiDots() {
  var fields = getOutputFields();
  for (var i = 0; i < fields.length; i++) {
    var field = fields[i];
    var str = field.id;
    if ((str.split("_")[2] == "43") || (str.split("_")[2] == "4")) {
      fields[i].innerHTML=fields[i].innerHTML.replace(/\&nbsp;\./mgi,"&nbsp;&nbsp;&nbsp;"));
      fields[i].innerHTML=fields[i].innerHTML.replace(/\" "\./mgi,"&nbsp;&nbsp;&nbsp;"));
    }
  }
}
Change it to use pui.set() instead of innerHTML. (Also, since 'field' is already defined to be 'fields', you can shorten the code a bit by using 'field') This will both update the innerHTML and the underlying genie data, so both are updated properly.
Here's the updated version:

Code: Select all

function replaceiDots() {
  var fields = getOutputFields();
  for (var i = 0; i < fields.length; i++) {
    var field = fields[i];
    var str = field.id;
    if ((str.split("_")[2] == "43") || (str.split("_")[2] == "4")) {
      pui.set(field, field.innerHTML.replace(/\&nbsp;\./mgi,"&nbsp;&nbsp;&nbsp;"));
      pui.set(field, field.innerHTML.replace(/\" "\./mgi,"&nbsp;&nbsp;&nbsp;"));
    }
  }
}
Again, after saving your changes use "Refresh" on the Genie toolbar to update the copy of custom.js in your browser.

Step 3: Put the replaceidots() at the top of your 'onload' function.

Should be easy enough... just cut/paste the replaceidots() so it's the first thing done in your onload function.

Step 4: Trim blanks from the value.

Right now you are attempting to do that with innerHTML and you are using our get() function because it trims blanks. In my opinion, this is sort of overkill to call get() when you already have the value. The Genie widgets that get their data from the 5250 screen all have a "value" property that is set to "script: value". This basically sets the widget's value to the underlying value from the 5250 screen. But you can add a trim() in there easily to remove blanks.

We can do it that way right in your existing loop in the onload, so make your onload loop do this:

Code: Select all

replaceiDots(); // Remove dots from menu items.

// Center Infinium copyright page.
var a = getOutputFields();
for (var i = 0; i < a.length; i++) 
{
    .
    .
        applyProperty(a[i],"value", "script: trim(value)");
        applyProperty(a[i],"css class","mylink");
        applyProperty(a[i],"field type","hyperlink");
    .
    .
}
// ( replaceiDots() was removed from down here... now at the top )
So this changes the value property to "trim(value)" and that'll trim the blanks. It also sets the CSS class to our new "mylink" class (if you used a different name in the CSS file, use that here, too). Finally, changes the type of field to hyperlink and this makes Genie re-draw the field using the updated values you set.

Hopefully this is everything.

Also, I wanted to say, I'm impressed... this is some really complicated stuff you're doing here, I'm really impressed that you figured this all out yourself (with a little help from me.) I didn't realize you were so good with Javascript!