Deeplinking div blocks - javascript

I am looking for a way to deep link div blocks. On a particular page I might have several div blocks each with its own contents. One of this blocks is visible, others are hidden. Once a link or a button is pressed the corresponding div is shown and others are hidden. Here is the HTML for the divs:
<div id="6ba28aae2dae153a1686cfee276632d8" class="page-block" style="display: block;">
<p>
1st block.
</p>
</div>
<div id="55cead0effa915778913d8667d0ae3a9" class="page-block" style="display: none;">
<p>
2nd block.
</p>
</div>
And here is the JavaScript used to switch the blocks.
/* Hide and show necessary blocks. */
function switchBlocks(UID)
{
var blocks = $('div.page-block');
for (i=0; i<blocks.length; i++)
{
if (blocks[i].id == UID)
{
blocks[i].style.display= 'block';
// Get the current URL and split it at the # mark
urlArray = window.location.href.split("#");
// Select the part before #
subURL = urlArray[0];
// Create a fake URL by adding UID to subURL
history.pushState(null, null, subURL + '#' + UID);
}
else
{
blocks[i].style.display= 'none';
}
}
}
What I am trying to do now is assign each block its unique URL by using the blocks ID. I am able to update the URL with the relevant ID yet can't figure out how to link the particular URL to a specific block so that the corresponding block is shown when accessing its URL.
I have studying the tutorial on the HTML5 History API but can't quite figure out how to apply it to my case.

if(window.location.hash == "#55cead0effa915778913d8667d0ae3a9")
{
$("div.page-block").hide();
$("div#55cead0effa915778913d8667d0ae3a9").show();
}
or
hash_id = window.location.hash;
if(hash_id.length > 0)
{
$("div.page-block").hide();
$(hash_id).show();
}

I think it is better to add and remove classes then having the desired css effect. I believe this is more efficient but I could be wrong.
You could also store a reference to the old div that is being shown so that you could just hide that one and show the other rather then iterating over an entire list of divs. In reality you only need to show one div and hide one div.
As far as browser history support. Do you need this to be cross browser supported? html5 history API is not supported in all browsers. This may not be a problem or concern for you.
List of supported browsers
http://caniuse.com/#search=history
I have used jquery bbq to add history support to a web application. It works well in older browsers.
http://benalman.com/projects/jquery-bbq-plugin/
For big javascript projects Backbone.js is the way to go it has browser history support as well as many other helpful built in functions that make it easy to manage your code base.

Related

Add a class attribute to certain links

I have pages on my site that go through a translation proxy. I need the displayed text in certain links to not be translated. I can add class="notranslate" to the link and the translator will skip over it no problem. However, I have hundreds of pages created before I implemented the translator and I'll have hundreds more as I keep going along—manually adding the class is not really an option.
The links I'm specifically concerned with are ones whose display text are literal URLs or email addresses. The translator doesn't touch the href attributes so the links still work as expected, but the displayed string gets mangled. For instance, in Vietnamese, "organization#domain.com" is displayed as "tổ chức#domain.com," and a link whose display text should be "domain.com/committees" is translated to "domain.com/commitaries."
So I'm looking for a solution that finds a elements whose display text contains "#" or "/" and adds class="notranslate". I don't think I need too robust a solution as I otherwise don't use the "#" or "/" in link display text often, if ever, except in these situations. I would guess this could be done with Javascript, but I'm a JS beginner at best. An option that filters content on the backend through Wordpress could also be a nice solution.
This is simple using jquery, ideally this will need to load before your translations plugin.
Note: If you have jquery already loaded as most wordpress themes already do, then you can remove the first line from this code, which includes the jquery library.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
$( document ).ready(function() {
$("a").each(function() {
let text = $(this).text();
if(text.includes("#")) {
$(this).addClass('notranslate');
}
if(text.includes("/")) {
$(this).addClass('notranslate');
}
})
});
</script>

Mobile first when using match media?

I have a page that uses multiple form elements. Far too many for a smartphone without scrolling, which I don't want. To solve this problem, I put the form elements in a carousel.
When I don't need the carousel (larger displays) I need to eliminate it. The only way I know of to do this is to reassign the parent properties of the carousel items and then remove the carousel.
This approach works fine using java-script. However, to pull this off I would need to use match media to call the java-script functions. Since most legacy browsers (which don't support match media) are used by desktops wouldn't this go against mobile first development?
Would it be wiser to design for legacy browsers and then upgrade the page for newer, more robust devices that can understand more updated languages or am I approaching this problem entirely wrong? I would rather not add a polyfill to fix this problem if I don't have to. Forgive my ignorance if I'm not seeing the simple solution here.
Here is a snippet that changes the parent div for large displays at codepen.
// Transfer elements from carousel to a larger div display
function SetParentDiv() {
var newParent = document.getElementById('LargeDisplayPage');
var oldParent = document.getElementById('1');
// Carousel items are 3 divs with numbered id's
for (var x=1; x < 4; x++) {
oldParent = document.getElementById(x);
while (oldParent.childNodes.length > 0) {
newParent.appendChild(oldParent.childNodes[0]);
}; ///endwhile
}; // endfor
document.getElementById('SmallDevicePage').style.display = 'none';
...
Here is the full Code Pen

How to disable hyperlinks within a PDF rendered by PDF.js

I'm looking into PDF.js for use in a web app. So far, it's meeting all of our business requirements. However, management has requested that we have the ability to disable hyperlinks within the PDF. We don't necessarily have to get rid of the blue text and underline, but if the user clicks on the hyperlink, it shouldn't go anywhere.
I've looked carefully through what API there is and couldn't find anything for it. I also looked through the source code, but nothing jumped out at me as something I could comment out in order to disable hyperlinks. Is there any way to disable hyperlinks contained within a PDF?
After a great deal of experimentation, I found out how to do this by modifying the source. There is a block of code that begins with the following:
document.addEventListener('pagerendered', function (e) {
At the end of the function before the close bracket, add the following code:
var allowInternalLinks = true;
var page = document.getElementById('pageContainer' + pageNumber);
var hyperlinks = page.getElementsByTagName('a');
for (var i=0; i<hyperlinks.length; i++){
if (!allowInternalLinks || hyperlinks[i].className != 'internalLink'){
hyperlinks[i].onclick = function(e) {
e.preventDefault();
}
}
};
What this does is take the rendered page, iterate through all of the hyperlinks on that page, and disable them. I have also added a boolean variable that allows you to optionally allow or disallow internal links (i.e. links that take the user to another location within the document).

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.

Assign links and classes in 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.

Categories

Resources