Modeling overlapping HTML spans w/ different CSS - javascript

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.

Related

Customizable/Themable UI

I would like to offer my users the ability to customize the look and feel of the website.
I am giving them a color picker to choose a color scheme. I would like to dynamically generate few matching colors and apply them.
My questions are:
1.) How can i generate a color scheme based on the choosen color ? (some matching colors and contrasting colors for the background)
2.) What are the best practices for achieving a themable interface ?
I am writing an AngularJS SPA app with pure HTML with REST API as backend.
Right now for my 2nd question, I am retrieving the color setting and applying them for body.
<body style="background:color:{{bgcolor}}; color:{{fgcolor}}">
I am looking for something more elegant.
You can do this with ngStyle as you have above... but as you noted, it's not very elegant.
The simple truth is that nothing in AngularJS itself is really designed to address this problem other than the ngStyle directive itself. However, while I haven't exactly seen a "best practice" for this, you might take some ideas from Drupal's "Color" module, which is one of its base/core modules. You can do the same thing in Angular very easily.
What this does is go back to stylesheets, which I'm assuming you skipped over because it didn't seem like an obvious solution for something dynamic. But they have a clever answer. In a piece of code, after the user picks a color, they write out a stylesheet with a unique ID for its filename. They put these in a directory where other user-uploaded assets are kept, so they don't mix with core site code (minimize the potential attack vector). Then they only need a simple rule in the page to include the stylesheet itself.
You can easily emulate all of this with Angular, although you'll need your server's help, of course. But the nice thing about it is it's much easier for you to maintain. Instead of having to "sprinkle" ngStyle directives all over the place (one on everything you want styled) and potentially having conflicts with other things you want to do on some of those elements, the stylesheet can work exactly the way it's supposed to: using classes to target specific elements. You can make a template stylesheet that's easy to maintain, so that's a natural fit... and the best part is, it's easy to hook everything up.

Remove JavaScript styles, allowing CSS to take control

Preamble: Possible duplicate to my question can be found found here, although for me, this question was not sufficiently answered. A work-around is given, but a definitive answer to the question of whether or not it is possible, is not provided.
The question:
On my website, when a user clicks a button (or area of screen), I want that area to "flash" a couple of times before returning to its original state. (I think this gives the user a reassuring feel of something having been activated, as in some circumstances, they may have short delay before the feedback is given.)
Anyway, I've managed to get this working using a bit of JavaScript and jQuery, and you can see the results here >>.
As you may notice, the problem is that after the flashing is done, the element doesn't return to its original state. Rather, it keeps its last "flash" state, and overrides the underlying CSS styling which originally styles the object when the page loads.
I style the element with the following jQuery:
$jq_obj.css('background-color',flash_fg_color_).css('color',flash_bg_color_);
And I 'attempt' to un-style it with:
$jq_obj.removeAttr('background-color').removeAttr('color');
I've also tried:;
$jq_obj.css('background-color','').css('color','');
Despite the documentation saying that this should remove styling, it doesn't.
Is there a solution, or do I have to revert to the work-around solution referred to in my preamble? The nice thing about the JavaScript option is that it becomes a lot more versatile when you want to play around with the animations a bit.
Thanks,
===EDIT 2014-06-28===
As a demonstration of why the class solution is untidy, please see this fiddle: http://jsfiddle.net/Y9L4x/ (inspired by #BiffMaGriff 's proposed solutin here: http://jsfiddle.net/rte3G/)
The problem is that the elements being flashed could already be CSS-ed up to the hilt with multiple classes.
I recognise that I can remove styling classes first, before applying the "flash" classes, complicate the JavaScript and/or the CSS rules, etc. etc.
But the whole point of looking for a non-class-solution is that this option becomes extremely verbose in a real world situation, and you tend to have to program each flashing object individually, rather than the tidy one-JavaScript-function-fits-all that I'm searching for.
You are going to want to do your styles as classes.
.activated{
background-color: red; //or whatever else
}
and then with your jquery you can just toggle them a few times with the delays I assume you already have in your javascript.
$jq_obj.toggleClass('activated');
Try this:
$jq_obj.attr('style','');
The direct answer to the question appears to be a simple "No".
You cannot tell JavaScript to style an object, and then at a later stage, ask JavaScript to give styling responsibility back to CSS.
However, another messy work-around is to re-draw the HTML inside the element which contains your flashing-object.
$jq_flashing_obj.parent().html(original_html_);
This has the slight overhead of having to wrap your flashing object inside a div or span element, to ensure that the parent element contains nothing but your flashing element.
<div class="multiple-children">
link 1
<span class="wrapper">Click me to watch me flash</span>
link 3
</div>
You then, of course, have to capture the outerHTML of your flashing-object before the flashing starts.
original_html_ = $jq_obj[0].outerHTML;
The resulting JavaScript is a little bit verbose, as you see here: http://jsfiddle.net/CgsLs/ . However, it does have the following benefits:
Reusable on all clickable elements regardles of CSS :hover and other messy styling
Can optionally define the flash-color of the element inside the JS
Independent of CSS, meaning that the code is in one file, and therefore more maintainable
There are down-sides too
Requires the use of JQuery on() function (as opposed to simple click event handler)
Anyhoo... it may not be a solution for everyone. In some cases (maybe even most cases) the class option might be simpler.
But this is one other possible method of tackling this inherent shortcoming in JavaScript/Browser technology.

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.

Possible to have multiple sizes of custom selectboxes?

I've been searching for a good way in which to style up a selectbox, and have found a couple of good jQuery plugins that do the trick... However, they replace the selectbox with an input and a list and then give it a specific class which is used to add your custom styling...
This is fine and dandy, but I need to be able to use multiple sizes. The script is adding the same class to all of the replaced elements, so there's no way that I can find to style them with different widths.
Here's the script I'm talking about: http://www.brainfault.com/2008/02/10/new-release-of-jquery-selectbox-replacement
I just need to be able to have two distinct sizes/widths of the custom selectboxes. One for numbers such as 1-1000, and another for longer textual names such as "Transylvania County Home Buyers Association".
Obviously, one size would look ridiculous if I used the larger size to hold a list of numbers that only goes to 1000, and visa versa.
Any ideas how to make it work?
That plugin lets you supply classes via its setup options; can't you just give it whatever classes you need to distinguish big ones from little ones?
Here's the page: http://www.brainfault.com/jquery-plugins/jquery-selectbox-replacement/

How to detect struckthrough text using JavaScript

I have a form which presents the user a list of checkboxes, some of which have the text label struckthrough some don't depending on initial conditions. This is functioning fine. During the form validation however, I would like to be able to detect which are struckthrough. I can figure out how to check if they're enabled, but whether the label is struckthrough is eluding me. Any ideas?
You'll have to use the DOM methods (or jQuery) to look at the parent element of the text to see if its a <del> tag.
Can you provide some sample source so I might be able to elaborate with an example.
Doing this with jQuery just makes so much more sense then trying to mess around with plain Javascript. Here is what you need, basically:
striked = $("strike"); // As mentioned, you should use `del` .. strike is depreciated
$.each(striked, function(i, el) {
alert($(el).html() + " is striked through. What do you want to do with it?");
});
Not sure what you want, but that would detect all elements with strike/del on your page. You can also change the search a bit, to restrict it to only within a certain form/div/whatever like so:
striked = $("strike", $("#myform_id"));
Hope that's what you were looking for.
If the strikeout (your struckthrough) is assigned via a CSS class, you can simple detect the class (since you can already detect enabled/disabled). Else like Darrell mentioned, jQuery will be a great method.
You basically have two categories of checkboxes which you are defining by their display qualities (struckthrough and not). This kind of "what does it look like" detection creates an artificial code-dependency which could cause a lot of trouble later:
The strikethrough effect can be accomplished in several ways (the del tag, the strike tag, CSS text-decoration: line-through, and possibly others in future versions of HTML/CSS). If you later change which way you do the effect, you'll have to update your js code to match
If you ever choose to reformat the list and stop using the strikethrough effect (e.g. you decide to make it invisible, or faded out, or have a red x over it), you will lose your ability to distinguish between the two types of checkboxes.
Instead, you should either assign a CSS class (like "nonUsableCheckboxes") to all strikethrough checkboxes, or generate a hidden field indicating if it is strikethrough or not. That way your javascript stays independent of your display code, and less prone to fail.

Categories

Resources