Assign links and classes in JavaScript - javascript

I have a site that is in English and Spanish, and in each page of the site there is a link that leads to the Spanish version of that specific page, so if the user were on the "home.php" page, it would look like this:
<div id="language">
<ul class="language">
<li class="english"></li>
<li class="divider"></li>
<li class="spanish"></li>
</ul>
</div>
What I would like to do is leave the href and the class in the <a> tags in the HTML blank and assign a class and an href URL to the <a> depending on the page the user is on, that way I could, for example, just add that language div to an external file, and use an <include> to attach it to each page. To accomplish this I'm using the following code:
$('ul.menubar a').each(function(){
if(location.href.match('home.php')){
$('ul.language li.english a').addClass('active');
$('ul.language li.english a').append(function() {
$(this).attr('onclick', 'return false;');
});
$('ul.language li.spanish a').addClass('notactive');
$('ul.language a[href!="home.php"]').append(function() {
$(this).attr('href', 'inicio.php');
});
}
}
The problem is that the English version of the site has 4 links in the navigation bar (home.php, services.php, aboutus.php, contact.php), and the Spanish version likewise (with the corresponding translation of the URL names). I think that having to repeat that code 8 times (1 for each link, 4 links in each language) would be excessive and would actually add more code than simply adding the class and href url in the HTML. The point of using JS would be to simplify things.
So I basically would like to know if anyone can think of a better way to do this, that wouldn't require that much code. I'm trying to avoid having to, in the event that I'd need to change something, have to edit each different page. Also, I would like to know if this is the best way to achieve want I want to do using JavaScript.

HTML is best suited for managing content. CSS is best suited for presenting that content, and JavaScript is best suited for determining how that content behaves. Instead of trying to inject links and control the HTML from JavaScript; instead, leave the content where it belongs, inside the HTML, and use JavaScript to define one or two event-handlers to take action based on the class values on the hyperlinks themselves.
You already have a class on your English hyperlinks, and a separate class on your Spanish hyperlinks, so you can use this to your advantage.
Writing the Click Handlers:
Since toggling your "Language switch" most likely causes a boolean value to be set, you can use two click handlers to target all of your English links and all of your Spanish links, and then control the behavior based on the value of that switch at the time the links are clicked.
// handler for all English links
$('li.english a').click(function(event) {
event.preventDefault();
if(/* Switch is english */) {
window.location = $(this).attr("href");
}
});
// handler for all Spanish links
$('li.spanish a').click(function() {
event.preventDefault();
if(/* Switch is SPANISH */) {
window.location = $(this).attr("href");
}
});
Note that when a link is clicked, we first check the switch. Depending on it's value, we either redirect to that hyperlink, or simply prevent the default behavior -- going to a new page -- from completing.
Handling the Presentation:
Now, your other problem is going to be that, assuming your Spanish site and your English site are one in the same, you'll now see 8 hyperlinks in total. Again, this is where your switch can come in handy.
// single handedly hide or display the relevant content, based on the switch
function switchToEnglish() {
$('.english').show();
$('.spanish').hide();
}
function switchToSpanish() {
$('.spanish').show();
$('.english').hide();
}
Now, I don't know what else is contained in your switch function, but the general idea here is that we don't need to modify the content. We just need to show and hide the content. You'd need to integrate this concept into your existing switch function, if you don't already have something like this in place.
There are several advantages in this approach:
Your Web designers will still see href's in the HTML and can read and understand the HTML without needing your help or needing to go and look at JavaScript code. Not only will they see familiar patterns that they're used to seeing, but you'll likely have a better working relationship with them.
Search engines spidering your site will be able to read the links and follow them.
Browsers without JavaScript will be able to process the links. Some people seem to care about this. I don't. But it's worth mentioning anyway.
In summary, you're right about it being easier to manage in HTML. By using this technique, you can eliminate the repetition in the code that you're rightfully concerned about, and also move the content back to the HTML, as your gut is telling you is the correct thing to do. Not only will your code be more readable, but you'll get better SEO results as well.

Related

What is the simplest way to filter the content of a web page from a drop down menu?

I would like to be able to allow a user to "filter" the contents of an HTML page from a drop down menu.
I have minimal coding skills but maintain a simple website produced using Emacs org-mode. (easy to assemble pages and produce different versions of the same content using tags.) The output is simple HTML.
I can easily produce different versions of a page and make them selectable with a drop down menu to move between them, but this means I have different versions of the same content on my website, which makes retrieval from search engines confusing.
Ideally, I would like user A to be able to select to see the whole page, user B to see some of it, and user C to see most of it except a small portion. This is a convenience to the users (not for security, etc.)
What is the simplest way of implementing this? I realize a web developer would probably use Ajax, etc., but that's not me.
Sounds like you could make use of showing/hiding sections of the page with some DIVs based on a drop down SELECT.
To do this, you wrap the content that you want to filter in some DIVs and create a JavaScript function that "filters" the displayed content based on the value attribute of the SELECT.
Here is a simple example:
HTML
<select id="myDropdown" onchange="filterContent();">
<option value="A">All content</option>
<option value="B">Some content</option>
<option value="C">Little content</option>
</select>
<div id="contentA">
** Content A ***
</div>
<div id="contentB">
** Content B ***
</div>
<div id="contentC">
** Content C ***
</div>
JavaScript
function filterContent() {
var user = document.getElementById("myDropdown").value;
var contentA = document.getElementById("contentA");
var contentB = document.getElementById("contentB");
var contentC = document.getElementById("contentC");
if(user=="A") {
contentA.style.display="block";
contentB.style.display="block";
contentC.style.display="block";
} else if (user=="B") {
contentA.style.display="none";
contentB.style.display="block";
contentC.style.display="block";
} else if (user=="C") {
contentA.style.display="none";
contentB.style.display="none";
contentC.style.display="block";
}
}
Try it here: http://jsfiddle.net/JsZ8S/
Here is another example with multiple different sections that can be shown or hidden based on the selection. Note that the scheme used for IDs is contentA1, contentA2, etc. the letter being the user and the number after the letter is the sequence since IDs must be unique. Also note the difference in the JavaScript code - because we have more sections, we have to account for showing and hiding them in the if/else block: http://jsfiddle.net/JsZ8S/2/
In case you are ready to use jQuery another example is using classes. If you find that you are creating numerous sections and are tired of keeping track of IDs, you might want to use classes. Classes in this case, work like IDs that you can use again and again. You mark any section you want displayed to all users (user A) with class="contentA", any area for users A and B with class="contentB" and everything else just leave unmarked. This is starting to get a bit un-simple at this point but see what you think.
Here is an example (requires jQuery) using classes: http://jsfiddle.net/JsZ8S/5/
You cannot do it with HTML alone. HTML defines a static document with static formatting. You need at least a little bit of JavaScript to dynamically change the page. Otherwise you have to create some sort of link or button that takes the browser to a new page with the desired changes. (This is about how the web worked for the first 5 or so years.)
A small about of JavaScript plus a library like jQuery should make this easy enough to do if you have any programming experience.
HTML is used to just creating the markup and CSS is used to style it. There is no way you can do "filtering" in plain HTML. You will definitely need some JavaScript knowledge. Try your hands on jQuery and angularJS. They are really easy to learn and the documentation is pretty amazing.

How can I make a "reverse preventDefault" in jQuery?

In Private Logistics: Privacy-Sensitive Calendar, Todo, and Personal Information Management, data that is entered can be edited with a click, and there is support for either entering a link as <a href="... or entering a URL, which will be linkified.
This works great but it presents a problem when someone clicks on a link. The desired behavior is for the link to open and not to put the snippet of text into edit mode, which is the reverse of the usual pattern implemented by event.preventDefault()' or '...return false;}. (Clicks outside the link on the element should put the containing element in edit mode, same as a container that doesn't happen to have a link.)
How can I reverse the more common pattern using jQuery? My best guess now is to attempt introspection on the event target and see if it is an anchor. But that's just a best guess; I have seen plenty of examples of the pattern that would cancel the link loading another page but performing the added Ajax functionality of putting the container into edit mode; I'm not sure I've seen the reverse of that pattern which would follow the link and not put the container into edit mode.
I also see a way to dodge the matter by having links load in the same page, but that's the sort of solution I'd prefer to only adopt if there are intractable issues with implementation or the like.
Generally, you don't want to clean up your broad strokes, instead, don't make such broad strokes. Use an if statement prior to running e.preventDefault().
Something like:
var preventedLinks = $('a.preventthislink');
$('a').click(function(e){
if ($(this).index(preventedLinks) != -1) {
e.preventDefault();
}
});
you could alternatively just change the class of whatever you are preventing default on:
$(document).ready(function(){
$('.blue').removeClass('blue').addClass('green');
});

How to create interactive tags in html file?

I don't know anything about programming, so I'm trying to find out where to start learning + how difficult my problem is. Since I don't have any programming knowledge, I'll try to describe my problem in natural language, hope that is OK.
I have the html file of the penal code (a type of law). It contains many different rules, that are in numbered paragraphs (§ 1, § 4, etc).
Now I want to look at the source code and manually “tag” the paragraphs according to specific criteria. For example all the paragraphs that concern the use of a weapon get the “weapon” tag, or that have a minimum sentencing of 1 year and higher get a “crime” tag, etc.
At the end I want to view an interactive html file in Firefox/Chrome, where I could for example click on a “crime” button, and all §§§ that were tagged with “crime” would appear in bold red, keeping the rest of the document intact. Ideally I would also be able to click on “weapon” and would only see the §§§ tagged with “weapon”, making the rest of the document disappear.
The function it's just for me, so it would only need to work on a Xubuntu 11.04 desktop with Firefox or Chrome. The original source file would be http://bundesrecht.juris.de/stgb/BJNR001270871.html. The code looks strange to me, is there a way to convert it into something more easily manually editable?
Any help would be greatly appreciated. Primarily I don't know where to start learning. Do I need to know HTML, jQuery, or a programming language like Python? Do I need to set up an Apache server on my PC? Perhaps because of my ignorance of programming, this seems like a not too complex function. Am I mistaken in the belief that an amateur could build something like thins maybe one month?
I think this is not very difficult to make, although the tagging process can be quite labour-intensive.
You don't need much programming skills, especially when you want to tag stuff manually. You probably only need basic HTML and CSS and some Javascript to pull this off.
What I would do is the following
Create a local copy of the HTML file (use Save As in your browser)
Manually tag each § by giving it the appropriate tag as a classname
Create a list of all available tags and let javascript filter out the § you'd like to see
Now Step 1 is pretty easy I guess, so I'll go right to Step 2. The paragraphs in the HTML file are formatted according to a certain pattern, e.g.:
<div class="jnnorm" id="BJNR001270871BJNE009802307" title="Einzelnorm">
<div class="jnheader">
<a name="BJNR001270871BJNE009802307"/>Nichtamtliches Inhaltsverzeichnis
<h3><span class="jnenbez">§ 31</span> <span class="jnentitel">Rücktritt vom Versuch der Beteiligung</span></h3>
</div>
<div class="jnhtml">
<div>
<div class="jurAbsatz">
(1) Nach § 30 wird nicht bestraft, wer freiwillig etc.
</div>
</div>
</div>
</div>
What you want to do now is add your tag to the <div> element with the class jnnorm. So the above example would become (if the tag weapon would be appropriate):
<div class="jnnorm weapon" id="BJNR001270871BJNE009802307" title="Einzelnorm">
You do that for each paragraph in the HTML. This will be pretty boring, but okay.
Now Step 3. First create a list of links of all the tags you've just created. How you create lists in html is explained here. Put this at the top of the HTML document. What you want to do with javascript is when you click on one of the links in your list that only the paragraphs with the given class are shown. This is most easily done with jQuery's click event and the show and hide methods.
Updated with jQuery example
Make a menu like this
<ul id="menu">
<li id="weapon">Weapons</li>
<li id="crime">Crime</li>
</ul>
And then use the following jQuery
<script>
$(document).ready(function(){
// When a <li> element inside an <ul> with the id "menu" is clicked, do the following
$('ul#menu li').click(function(){
// Get the id of the <li> element and append a '.' so we get the right name for the tag (class) we want to show
var tag = '.' + $(this).attr('id');
// Hide all elements of class 'jnnorm'
$('.jnnorm').hide();
// Show all elements with the class name of tag we want
$(tag).show();
});
});
</script>
Note: HTML classes are denoted as .classname in jQuery whereas HTML id's are denoted as #idname.
Good luck!
This could be done using purely HTML/CSS and Javascript, so not server would be needed. JQuery would make the javascript side easier.
Basic idea of how to do it:
Use CSS style classes for your "tags"
Have a button for each tag with an onclick handler that uses JQuery to highlight everything with that tag (or make everything else invisible)
The HTML source code actually looks nicely structured, though it could use a few more linebreaks for sub-paragraphs. Any good HTML/XML editor has an autoformat feature that handles this, though you could get any specific format you want using a programming language with convenient text-manipulation facilities, such as Perl, awk or Python.

Making a span/div/p href-like or stopping href "executing" links

I have the problem to "stop" href executing any links.
So my question is:
1) Is it possible replace href-elements that generate internal (#) links with any component, maybe <p>, <div> or <span> (or whatever could be working) that keep the same behaviour of <a> element (hovering, underlined etc) but not executing any link?
2) Alternative, a "trick" to avoiding href elements execute links?
1 or 2 without using jquery or any other js library possibly
Thanks Randomize
There are all sorts of tricks that can be employed to do this kind of thing, but what you need to be careful of is modifying the behaviour from that which the users have come to expect from a browser.
For example , it would be possible to swap the meaning of 'OK' & 'Cancel' buttons, but this would just confuse the user. (An extreme example, I know, but you get the idea)
If you could supply some more information about why you are trying to do this, there may be a better way of approaching things.
You can either add an onclick attribute to specific <a> elements:
Or modify the href like this:
To make them look like links, without redirecting the browser.
If instead, you already have a bunch of links with hrefs, and you simply wish to make them all non-redirecting, then the following jQuery will do this to all links on the page:
$(function () {
$('a').click(false);
});
Although nice and short, the above only works with jQuery-1.4.3+. If you are using an older version, then you can use the expanded form:
$(function () {
$('a').click(function () { return false; });
});
Yes. You can prevent links from the default action - the recommended way is to have links work normally (in case JS is disabled or not available - think "mobile browsers"), and then override the default action with JS.
Unfortunately, due to cross-browser incompatibilities, there are three ways to do this ("traditional","W3C" and "IE") and you need all of them: stopPropagation(), cancelBubble and return false. See a complete example at QuirksMode: http://www.quirksmode.org/js/events_order.html#link9
(Incidentally most JS frameworks abstract this away, so in jQuery you'd do this:
$('a').click(function(event){
// do something on click here
event.preventDefault();
});
This does the same thing as the QuirksMode example, but is a easier-to-read example.)
TO disable the link via js add onclick="this.href='javascript:void(0)';" like so:
link text
You can use a similar tactic to make other elements work link links:
<div onclick="this.href='http://www.mysite.com';"></div>
This is working in IE, chrome and firefox:
text link
In the function return void(0):
function functionX() {
...
return void(0);
}

jQuery Graceful Degradation

I want to spruce up some areas of my website with a few jQuery animations here and there, and I'm looking to replace my AJAX code entirely since my existing code is having some cross-browser compatibility issues. However, since jQuery is a JavaScript library, I'm worried about my pages not functioning correctly when JavaScript is turned off or doesn't exist in a user's browser.
I'll give an example: Currently, I'm using a pure CSS tooltip to give my users (players, the site is a browser game) information on other users. For example, if the other players in the game satisfy one or more conditions, a target icon is displayed next to their name, and upon hovering over that target icon information regarding the reasons behind the target is displayed. This is useful information, as it helps my players to know who they should plan to attack next in the game.
Currently, I do such tooltips using CSS. I have a parent div that holds the image of the target icon of class "info". I then have a div inside of that with class "tooltip" that, on the hover state of the "info" class that it is contained in, is shown, but on the normal state is hidden. I thought it was rather clever when I read about it, and since no JavaScript is used it works on any CSS compliant browser.
I would like to use jQuery to achieve the same effect, mostly because it would look much cleaner, but also because I believe quick and subtle animations can make such things "randomly appearing" make a lot more sense to the user, especially on the first encounter. I'm just wondering if the two will conflict. This is only one example of this, there are numerous other examples where the inability to use JavaScript would hinder the site.
So what I'm asking I guess is, how does one make a jQuery site degrade gracefully on browsers that do not support JavaScript, but otherwise do support most CSS? My goal is for the site to function on a basic level for all users, regardless of choice in browser. The animation is a good example, but I'm also worried about the more dynamic bits, like the auto-updating with AJAX, etc. Are there any good resources on how to achieve this, or do you have any advice about the best way such degradability could be achieved?
Thanks
PS: Totally irrelevant, but Firefox seems to think that "degradability" isn't a word, but "biodegradability" (with the "bio" prefix) is. Weird...
If you consider the "Cascading Order" of css, could you not just add a css style at the very end of all your previous css definition in order to cancel any css effect you currently have for tooltip effect ?
That css rule would only be declared if Javascript is activated and JQuery detected.
That way, you are sure your css tooltip effect is not in conflict with your JQuery effect.
Something like:
a.info:hover span{ display:none}
with the use of "js_enabled" class to make this css rule conditional.
You also can do it by adding css rule on the fly:
function createCSSRule(rule,attributes)
{
//Create the CSS rule
var newRule = "\n"+rule+"{\n";
for (var attribute in attributes)
{
newRule += "\t" + attribute + ": " + attributes[attribute] + ";\n";
}
newRule += "}\n";
//Inject it in the style element or create a new one if it doesn't exist
styleTag = $E('style[type="text/css"]') || new Element("style").setProperty('type','text/css').injectInside(document.head);
if(window.ie)
{
styleTag.styleSheet.cssText += newRule;
}
else
{
styleTag.appendText(newRule);
}
}
The most simple solution for Separation of CSS and Javascrip is to remove your css class
function jscss(a,o,c1,c2)
{
switch (a){
case 'swap':
o.className=!jscss('check',o,c1)?o.className.replace(c2,c1): <-
o.className.replace(c1,c2);
break;
case 'add':
if(!jscss('check',o,c1)){o.className+=o.className?' '+c1:c1;}
break;
case 'remove':
var rep=o.className.match(' '+c1)?' '+c1:c1;
o.className=o.className.replace(rep,'');
break;
case 'check':
return new RegExp('\\b'+c1+'\\b').test(o.className)
break;
}
}
This example function takes four parameters:
a
defines the action you want the function to perform.
o
the object in question.
c1
the name of the first class
c2
the name of the second class
Possible actions are:
swap
replaces class c1 with class c2 in object o.
add
adds class c1 to the object o.
remove
removes class c1 from the object o.
check
test if class c1 is already applied to object o and returns true or false.
If something can be done completely in CSS I say keep it that way. If lack of javascript in the browser is a concern, then most of the time I show the entire page unaffected.
Say for instance I'm going to use jQuery to toggle an element when a checkbox is clicked. On page load I look at the checkbox and update the element accordingly. If javascript is not enabled the element will still appear and the site will still be usable. Just not as nice.
Man, you have a browser-based game, right? You have less than 1% users with JS disabled! And that 1% is the apocalyptic number because I can BET that you have less than that ;)
Anyhow, if you are really concerned about this, just do the site without any JavaScript. And make it functional 100%. After your site works completely without any JS flavour, just start to improve with jQuery (or any other library; jQuery is the best :P ). But with careful: do not change ANY of you HTML. It's easier than it looks ;)
And yes, if you have things that work without JS (like those tooltips) keep it!

Categories

Resources