Recommendations for dropdown menu items that are too wide? - javascript

What kinds of options do I have when a dropdown menu is faced with text that is so wide that extending the menu's width to accommodate is not feasible? i.e. It breaks the page layout, or just looks too ugly if the dropdown is adjusted to fit the long item.
Truncation?
Truncation plus full hover text?
Don't allow items that long?
Anyone encountered any elegant solutions to this?
Thanks.

I realise I'm fairly late to this question, but I've been hunting for an answer and I may have found a fairly elegant solution.
Have a look here:
http://www.getharvest.com/blog/2009/12/dropdown-problems-on-internet-explorer/
http://www.dougboude.com/blog/1/2008/05/Viewing-Option-Text-in-IE7-thats-Wider-than-the-Select-List.cfm
The first link talks about a couple of solutions before recommending a solution based on the second link.
The idea is that on click, you change the width of the <select> tag such that it is big enough to show the full text of the options. By keeping the <select> tag inside a div with overflow set to 'hidden', it doesn't screw with the rest of the page.
Try it out - it's a pretty good solution.

Truncation with tooltip would be my choice....
The last time i had to do that i used a telerik control, which was quite UI rich.

I agree with GordonB regarding truncating the options. Excessively long options can be hard to read, and as you mentioned it looks horrible.
If your dropdown is populated from user input, however, I'd restrict the length. What can be said with 15 words should be said with 5 ... if it can't, then perhaps a dropdown isn't your best option.
For example, if your options are the titles of research papers and their authors, you can probably abbreviate them down to a few key words ("String Theory and You [Brown 2008]"). On the other hand, if the options themselves differ by only a few words and lose meaning if they are truncated (e.g. a list of options like "Peanut butter and grape jelly sandwich with carrot sticks and soy milk" and "Peanut butter and boysenberry jelly sandwith with carrot sticks and 2% milk") maybe you would be better served by displaying all the options sequentially, accompanied by a checkbox or radio button as appropriate.
(If you're using ASP.NET, basically I'm saying using a repeater instead of a DropDownList)
This second approach might also allow you to incorporate other elements that you wouldn't be able to in a dropdown. Take a look at this Amazon search result page for ideas.

Give the element a maximum width with the CSS property max-width.

Most browsers show the options at full width regardless of the dropdown's actual width whereas IE crops them to the width of the select box. So the problem is really browser specific.
I've made a solution using absolute positioning on the dropdown so that I could extend it's width on hover in IE without breaking my layout. A bit hacky but it's one option.

I've been using commercial ASP.NET control that is implemented using <div> rather than <select>. This way we could put multiline elements on it, style it as we wanted and do some other stuff.

Depends how wide you are talking, what the context is. Often this comes down to a design problem rather than a coding problem. If the text is really long you will have usability problems regardless because reading long text in a dropdown is difficult. My options would be:
If the dropdown is really narrow and the longest items aren't very long (eg 3-4 words) change the design to accommodate it.
If the text is really long (eg sentences) then truncate it if you can. Sometimes text isn't amenable to this (eg. you may end up with multiple items with the same text). You can't really put tooltips on select list items.
If the text is really long and can't be truncated, you may want to consider a different UI option.

Why not create a calculated field which is based on the lengthy field.
Only create it to only be the first 50 (say) characters.
=LEFT([Title],50)
Then reference that field in the drop down.

Related

Why is the bounding rectangle of the selection range wider than the actual text selection?

I need to get the bounding rectangle of the text selection. I am using this code:
if (window.getSelection && window.getSelection().rangeCount) {
var range = window.getSelection().getRangeAt(0).cloneRange()
if (range.getBoundingClientRect && range.getBoundingClientRect()!=null)
return range.getBoundingClientRect()
}
But it often returns a rectangle that is much wider than the text selection, even though every element of the selected text doesn't extend that wide.
For example, when I select the text of the fist two paragraphs of https://simple.wikipedia.org/wiki/Gluon the rectangle includes the picture to the right.
It seems that the problem occurs every time when the paragraph boundary is inside of the text selection, and this makes the rectangle to extend to the paragraph width.
How to solve this problem?
The image being included in the multi-paragraph selection may be a problem for what you want to accomplish or the way you want to interpret the document structure--yet isn't "wrong" from the point of view of the HTML/CSS layout model or the browser's layout engine.
Simplifying the document structure:
<div id="nw-content-text">
<div style="float: right">
<img src="gluons.png">
</div>
<p>From Wikipedia...</p>
<p>Gluons are what hold quarks together...</p>
...
</div>
In Chrome e.g., inspect the page. Then in the Elements view select either of the <p> tags. The rendered view will show highlighted background extending across the image area:
That's because the image floating to the right is indeed consuming part of the paragraph's maximum possible bounding box. If you want to consider just paragraph text, that feels wrong, but it's how the CSS layout model works. Depending on your font sizes and such, you may be able to select the third para as it flows underneath the image, and it indeed flows to the same far right edge.
Given the float: right of the image's container, the browser "thinks" the image and its container <div>s "lives" to the right of the first para, but before the second. That is its logical "attachment point" or "anchor point." Select the first para, and the browser knows the image isn't included. Select the second, and likewise. Select the combination, though, and the image is correctly included because the anchor point lives between the two paragraphs. Ask for the bounding box of either para alone and the browser responds with a tight box. But ask for tbe bounds of the selection that spans those paras, and it must include the anchor point and contained image that anchor point represents. The much larger bounding box including the image is the right answer.
Okay, so much for the layout theory explaining why this happens as it does. Now how to get it to do what you want it to do, and exclude the contained image from the selection bounding box?
Given that CSS and the browser doesn't interpret the selection the way you want, you won't be able to use getBoundingClientRect() on the selection directly. However, you can navigate from the selection to the nodes included, and filter out any tags that you don't want. In this case, you seem to only want <p> tags, which are easy enough to filter for. Compute the bounding box of each para in your selection, then return a box that is the union of them.
Beware that working with ranges is a bit tricky, especially as browsers historically had different models for how to manage them. A cross-browser library like rangy might help, though simply navigating from a range to the underlying nodes probably doesn't require that much extra framework. There are quite a few articles on Stack Overflow about "getting from JavaScript selection to underlying nodes," with many code samples. They're not all simple...but just filtering for paras is a fairly simple case. Or if you don't want to dive into all the range issues, you can use something like Selection.containsNode() to less elegantly but still quickly iterate through possible nodes and see if they're in the selection.
Also beware: Your example document makes things simple by just needing filtering for paras, and by having just one floating item to exclude. But the variability across all HTML / CSS documents is enormous. That variability can make solutions fragile. E.g. if sometimes you need to filter for more than just <p> elements, or need to filter into the middle of text nodes not affiliated with a tightly-wrapped tag, things quickly get more dicey. The variations and the different edge cases will complexify your reinterpretation of what a selection's bounding box should enclose (and should ignore).

Modeling overlapping HTML spans w/ different CSS

I'm looking for a good way to model something keeping track of different overlapping CSS groups, similar to the following:
This is just a test sentence for an example.
(This is) just a (test sentence) for an example.
(This is just) a test (sentence for an example.)
Depending on what radio buttons are selected, I'd like to to enable different CSS styles for each of the groups in parenthesis. So for #2 for example, (This is) will always have a different default style, and will highlight red when moused over, but only when option 2 is selected. There will be a lot of different options, so I'd like to avoid having multiple copies of the source text if necessary.
The problem is that you can't have spans overlap. The only way I could thing of doing this is giving each word multiple css classes, like:
group2_word1,group3_word1, etc..., and then do a lot of javascript coding to simulate the behavior I want. This sounds like a terrible idea to me.
Is there a better way?
I remember a javascript library that was able to do word/letter based inline text styling but I do not remember the name. All I could find out by now is a lib called rangy. Maybe you want to give it a try. I will try to find the other lib too and report back if I find it.
Take a look at the CSSClassApplierModule that could do just what you are looking for.

Drop down list with large number of words in each selection

I have an unusual situation. I have a drop down list that allows my users to select one of a number of different scenarios. My problem is that each scenario is about 100 words long. I want to show the user everything and a radio selection box would not be appropriate. What happens is that because of the very long rows my dropdown list appears so wide that it goes off the edge of the page.
Is there a way that I can split up text (I'm using C#) and add new lines so that dropdown list box contains "multi line" selections?
Hope this makes sense to you.
I don't think it's possible without some scripting. You can add width and white-space:pre-wrap to your select tag, but that only wraps the visible part. You can't, as Madmargigan suggested, use a title to show the complete string (the title won't show).
I have prepared a very basic script to demonstrate how you could do this with javascript. See this fiddle. It may give you ideas?
You cannot do this with the standard html dropdownlist. Some frameworks have workarounds for it (for instance, see ASP.NET's dropdownlist). There are also javascript libraries that offer solutions to this problem as well.

Ondrag ROT-13/ROT-47 decode

I have a little website where I would like to obfuscate some text to protected spoiling of users that accidentally read it untimely.
Much like the keywords on imdb were, where you have to rollover to reveal them.
I thought it would be a nice and interactive way to reveal the text if its marked.
Example:
How does a programmer express
h(is)|(er) love? Zl srryvatf sbe lbh
ner uneqpbqrq.
Now you would drag mark the obfuscated text much like you would get ready to copy it to your clipboard, and it should reveal.
Is there a way to do this? My current problem is a way to determine the current selection in javascript.
There is one tricky way I can think of with only CSS:
Use the same color text as the background color! Then when users highlight, the text is revealed. You would need to outline or draw attention to the part that they need to highlight to make it obvious.
Another way:
Stuff the rot13 into a readonly text input, and attach a select event with an AJAX call that decodes it. Will only work for smaller bits of spoiler text that fit in the input. You could try this with a textarea but it doesn't accept the readonly attribute (maybe doesn't matter).
There are many many other ways to do this (hide/show divs for example), but these are the closest/simplest ways I could think that match your requirement of selecting text to trigger the spoiler.
EDIT: With the background color solution, you would not want to encode the text, just make it "invisible" until it's highlighted. It's actually a pretty cheesy solution, and there are many others that are better, but the good part is that it is css only. Honestly I think forcing a complete highlight will be a pain for your users, just store the rot13 value in one place, the real value in another (hidden span maybe), and use js to swap them out on click or something. No need to actually process the decoding separately. You could probably do this with CSS alone and some smart :hover or :focus selectors.
EDIT2: For some reason it didn't occur to me that you can do rot13 decoding with javascript alone, I'm coming from the php world so now I feel pretty foolish. Sorry I didn't answer your question better, but hopefully some of this is useful. GL!
jCarat (jQuery Caret Plugin) should cover your needs.

Bearing in mind accessibility, is it kosher to dynamically group LIs into DIVs?

Hi
To make convenient some animation, my strategy for a client-side script involves grouping list items into DIVs. It seems that having anything other than LIs as the children of OL or UL elements does validate. However, I'd be doing this in script, so no validation issue (for what that's worth!).
But might this cause a problem with screen readers and so on?
Thanks for any thoughts
One way to find out! I don't think there would be too much trouble, but the only way to know is to test it. Javascript's interaction with screen readers is a complex subject, so I'm hesitant to make any firm judgments. NVDA seems like a good place to start. :D
I'd normally steer clear of invalid markup, but I can't think of a better way to group things in the way you want to. Perhaps consider whether a single list is the best markup to use rather than multiple lists or some other set of constructs. Since you are needing to group list items in this way, it seems likely that there's a semantic reason for grouping them in markup as well.
As it goes, if browsers cope with the invalid markup in question, it is likely to work in screen readers and the like as well. As CrazyJugglerDrummer says, it's best to test it. However, you never know when that invalid markup is going to start causing problems in future software releases.
First off, screen readers and JavaScript do not have the best track record of compatibility. (Correct me if I'm wrong, I am no expert on usability) From what I have come to understand, screen readers typically read a static version of your page, and refresh it at seemingly random times irregardless of what dynamic changes have occured through JavaScript. This was my last experience with screen readers, but that was 3 years ago so things may have changed for the better.
To give an example, if your dynamic list is in fact an accordion that expands and contracts, you cannot with any degree of certainty know if a screen reader will display the text being shown (even if the JavaScript made the text visible to the screen).
Before I would start worrying about problems your script might cause for screen readers, I would instead focus on your overall accessibility of the site structure (HTML+CSS). Are you making integral elements to your page keyboard focusable? Are you following WAI-ARIA guidelines? Are you using the correct technique to hide content (situation dependent) display:none, left:-9999px, or visibility:hidden?

Categories

Resources