How to substitute specific pages? [HTML Multilingual Website] - javascript

My question is pretty straight forward.
I have a static HTML website in English.
www.website.com
www.website.com/services
www.website.com/contacts
I also have it translated in German:
www.website.com/de/
www.website.com/de/services
www.website.com/de/contacts
My button (flag) for changing language is located next to my navigation:
<ul class="language">
<li class="de"></li>
</ul>
Option 1: I can just replace the "#" with the German version of the page. For example on www.website.com it is <a href="www.website.com/de/"> and on www.website.com/services it is <a href="www.website.com/de/services">
But this is so much work. Is there an easier way for calling pages by using javascript or .htaccess..or whatever you suggest.
My pages are in .html, so the .php option isn't efficient. And adding "id" to every element in order to translate it.. is even more complicated than the first option.
Thanks in advance!

Ideally, you should probably do that with the server-side language of your website (PHP / ASP / Java / …). If you still want to do it in Javascript, you can do something like that to add /de on front of your current location:
<a href="www.website.com/de/" id="language">
<script>document.getElementById('language').setAttribute('href', '/de'+document.location.pathname);</script>

yep I suspect this javascript should work:
$(document).ready(() => {
let path = window.location.pathname;
if (path.startsWith('/de'))
$('a.lang-switch').attr('href', path.substr(3));
else
$('a.lang-switch').attr('href', '/de' + path);
console.log($('a').attr('href'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="lang-switch">Change Language</a>

Do you have two distinct copies of the HTML? If so, this is probably pretty easy.
Go with your first option, but only for changing languages.
Include a <meta> tag that indicates the current language
Use a javascript event listener to intercept each link clicked and insert the language based on the above meta tag. Something like this;
let lang = document.getElementsByName('lang')[0].getAttribute('lang');
// Get the parent DIV, add click listener...
document.body.addEventListener("click", function(e) {
// e.target was the clicked element
if(e.target && e.target.nodeName == "A") {
e.target.href.replace('yourwebsite.com', `yourwebsite.com/${lang}/`);
}
});
<meta name='lang' lang='de'>
References:
Part of code taken from an answer here

Related

Append string to every url on page load

I have my website in English but want to show it in Spanish when page loads. So, I got a script from Google Translate that I put in my header file but I need to append some #googtrans(en|fr) at the end of every URL. What I've done so far is:
$(document).ready(function () {
$('a').each(function () {
this.href += '#googtrans(en|es)';
})
});
But a problem with this code is, it is blocking my popups and bootstrap dropdowns.
Is there any simple way to put that trailing string to every URL on page load.
Filter out links that have attributes or classes you don't want the hash applied to:
For example:
$('a').not('[data-toggle], [href^="#"]').prop('hash','#googtrans(en|es)');
If selectors in not() aren't enough you can use the more robust filter() method
A more ideal approach would be being able to have classes on your <a> to represent the ones you do want modified.
<a class="translate">
$('a.translate').prop('hash','#googtrans(en|es)');
OR
<div class="translate">
<a>
</div>
$('.translate a').prop('hash','#googtrans(en|es)');
Note that using the hash property achieves the same as concatenating href
Without seeing more of your html it is hard to provide a lot more help
Now you replace with this code all <a> tags.
Best way - it's taking Google Translator block links on other div, like this:
<div id="gtr">
...
</div>
And Script:
$(document).ready(function () {
$('#gtr a').each(function () {
$(this).attr('href', $(this).attr('href')+'#googtrans(en|es)');
});
});
Instead of
this.href += “#googtrans(en|es)”;
Try this:
$(this).attr("href", $(this).attr("href") + "#googtrans(en|es)");

Split website link into 2 href link?

On my website public: http://abv.mk/company.aspx?id=40056 , i want to split http://www.donholding.com.mk & http://www.webklinika.mk to be separate links (and separate clickable like two different links - hrefs).
But in my admin-panel for the field website i only have 1 field available, where i input 2 web site links splited with ","
So is it possible in the public asp-file "company.aspx", to edit the file and insert some Javascript code, so i split the link from 1 href to 2 hrefs ?
<span id="ctl00_ContentPlaceHolder1_lblComWeb"><a target="_blank" href="http://www.donholding.com.mk, www.webklinika.mk" title="">www.donholding.com.mk, www.webklinika.mk</a> | donholding#live.com</span>
I'm guessing you have one field in the DB which stores the URL. This should probably instead be its own table - company_url, which takes company_id (in thie case, 40056) and the URL. You should bring back a DataSet, and create a HTML string to put in to the Literal (or whatever you're using).
That's the "you should do this" answer.
Now.. you could do...
$(document).ready(function(){
var el = $('span[id$="lblComWeb"]');
var el_a = el.children('a');
links = el_a.html();
links = links.split(',');
el.html('');
$.each(links,function(l){
var e = ''+links[l]+'';
el.append((l > 0 ? ',' : '') + e);
});
});
as you're already using jQuery. However, it's cheap and dirty and nasty and yucky.
Just putting that snippet in to your company.aspx file (between some tags) should do the trick.
This page only allows you to display one website.
The href property of the a html tag only support reference to one address/page.
What you could do is put there the link to another page which is yours, and in this page you can put as many different links to anywhere you want and other information too. Maybe search for some URL shortener service which allows something like this.
Now, if you actually do have access to the source code and modify it, all you have to do is:
<span id="ctl00_ContentPlaceHolder1_lblComWeb">
<a target="_blank" href="http://www.donholding.com.mk" >www.donholding.com.mk</a>, <a target="_blank" href="www.webklinika.mk" >www.webklinika.mk</a> | donholding#live.com
</span>

replace content of div with another content

I've been building a list of links, all of which should change the content of a div to another specific content (about 4 lines of stuff: name, website, contact etc.) upon a click.
I found this code:
<script type="text/javascript">
function ReplaceContentInContainer(id,content) {
var container = document.getElementById(id);
container.innerHTML = content;
}
</script>
and used it in such a way:
<li class="pl11">
superlink')">Pomorskie</a>
</li>
And it doesn't work as I expected.
It changes hyperlinks text from 'Pomorskie' to 'superlink'.
The plain text works just fine but I need links.
here's the http://xn--pytyfundamentowe-jyc.pl/projektanci/kontakty-p/ (only two of them show anything)
But after trying all of your recomendations, I think I'd jump to different divs with #links, cause nothing worked with this :/
Thanks a lot for trying, and cheers :)
Just as a completely sideways look at this, I'd suggest avoiding the nesting weirdness / complexity, and reducing the problem down.
Setup the content in a hidden (ie. <div id="replacements">...</div>) Grab the innerHTML from the node you want, and be done with it.
Much easier to get replacement content from non-devs that way too, kinda works great if you're in a team.
// Probably better in a separate helpers.js file.
function replaceContentInContainer(target, source) {
document.getElementById(target).innerHTML = document.getElementById(source).innerHTML;
}
Control it with: (lose that href=javascript: and use onClick, better as an event handler, but for brevity I'll inline it as an onClick attribute here, and use a button.)
<button onClick="replaceContentInContainer('target', 'replace_target')">Replace it</button>
We have our target somewhere in the document.
<div id="target">My content will be replaced</div>
Then the replacement content sits hidden inside a replacements div.
<div id="replacements" style="display:none">
<span id="replace_target">superlink</span>
</div>
Here it is in JSBin
Improve the dynamic nature of this by using Handlebars or another nice JS templating library, but that's an exercise for the OP.
edit: Note, you should also name functions with a leading lowercase letter, and reserve the leading uppercase style for Class names e.g. var mySweetInstance = new MySpecialObject();
The quotes are mismatched! So when you click you are getting a JavaScript error.
The browser sees this string:
href="javascript:ReplaceContentInContainer('wojewodztwo', 'superlink')">Pomorskie<
as:
href="javascript:ReplaceContentInContainer('wojewodztwo', '<a href="
Chnage the " inside to #quot;
<li class="pl11">
Pomorskie
</li>
Example fiddle.
Also note, using the href tag for JavaScript is a BAD practice.
You've got a problem with nested quotes. Take a look in your DOM inspector to see what the HTML parser built from it! (in this demo, for example)
You either need to HTML-escape the quotes inside the attribute as " or ", or convert them to apostrophes and escape them inside the JS string with backslashes:
<a href="j[…]r('wojewodztwo', '<a href="http://address.com">superlink</a>')">…
<a href="j[…]r('wojewodztwo', '<a href=\'http://address.com\'>superlink</a>')">…
See working demos here and here.
Better, you should use a onclick attribute instead of a javascript-pseudo-url:
<a onclick="ReplaceContentInContainer('wojewodztwo', …)">Pomorskie</a>
or even a javascript-registered event handler:
<li class="pl11">
<a id="superlink">Pomorskie</a>
</li>
<script type="text/javascript">
function replaceContentInContainer(id,content) {
var container = document.getElementById(id);
container.innerHTML = content;
}
document.getElementBId("superlink").onclick = function(event) {
replaceContentInContainer('wojewodztwo', 'superlink');
event.prevenDefault();
};
</script>
(demo)

JS - Shouldn't this be written better? One function vs multiples?

I have a tweet stream where new tweets are added at the top and the older ones pushed down. You can click on the entire tweet and a panel slides down to reveal, "reply", "retweet", "favorite" etc. The panel is added to each new tweet added in the stream.
The code below works. Shouldn't this be better written so that only one call is being made? Or, as a new tweet is added. would I just have to add to the code with div#tc4, ul#tb4 etc?
$(document).ready(function () {
$("div#tc1").click(function () {
$("ul#tb1").slideToggle("fast");
});
$("div#tc2").click(function () {
$('ul#tb2').slideToggle("fast");
});
$("div#tc3").click(function () {
$('ul#tb3').slideToggle("fast");
});
});
Added Markup:
<div id="tc1" class="tweetcontainer">
<div class="avatarcontainer">
<div class="avatar"></div>
</div>
<div class="content">
<div class="tweetheader">
<div class="name">
<h1>John Drake</h1>
</div>
<div class="tweethandle">
<h2>#Drakejon</h2>
</div>
<div class="tweettime">10m</div>
</div>
<div>
<p>Exceptional Buys Ranger To Give Monitoring Shot In The Arm To Its 'DevOps' Platform http://tcrn.ch/11m3BrO by #sohear </p>
</div>
</div>
</div>
<!-------------Tool Bar -------------------------------->
<ul id="tb1" class="toolbar">
<li><a class="reply" href="#"><span>reply</span></a></li>
<li><a class="retweet" href="#"><span>retweet</span></a></li>
<li><a class="favorite" href="#"><span>favorite</span></a></li>
<li><a class="track" href="#"><span>track</span></a></li>
<li><a class="details" href="#"><span>details</span></a></li>
</ul>
I highly recommend separating your javascript from your detailed page function. The best way to do this is to put the retweeting panel inside the tweet container, then you don't even need to give it an id at all or encode in the javascript information about your html structure and ids. You can then just do:
$('.tweetcontainer').on('click', function(event) {
if ($(event.target).is(':descendantof(.toolbar)')) {
//ignore all clicks within the toolbar itself
return;
}
$(this).find('.toolbar').slideToggle();
});​
It's that easy! See it in action in a jsFiddle.
Now you can add as many tweet containers as you want to your page--and your javascript doesn't have to change one bit. Other solutions that require knowledge of specific ids linking to specific ids are suboptimal.
Note the descendantof pseudo-selector is custom (see the fiddle to find out how it works). Also, since you didn't provide any css, I had to choose some--it was quick so don't expect much. (Aww heck I just saw you updated your question to provide a jsFiddle with css giving a far prettier result--but I won't change mine now.) I did have to add a class to the actual tweet itself, but there is probably a better way to style it.
And if you want a click on the displayed toolbar itself (outside of a link) to allow collapsing the toolbar, change the code above to :descendantof(a).
If you don't want to change your page layout, another way to it is to encode the information about the linkage between html parts in the html itself using a data attribute. Change your tweetcontainer div to add a data attribute with a jQuery style selector in it that will properly locate the target:
<div class="tweetcontainer" data-target="#tb1">
You don't really have to remove the id if you use it elsewhere, but I wanted you to see that you don't need it any more. Then on document.ready:
$('.tweetcontainer').click(function () {
$($(this).data('target')).slideToggle('fast');
});
Here is another jsFiddle demonstrating this alternate technique (though it less elegant, in my opinion).
Last, I would like to mention that it seems possible you have a little bit of "div-itis". (We have all been there.) The toolbar anchor elements have unnecessary spans inside of them. The tweet name h1 element is inside a div, but could just be an h1 with class="name" instead.
In general, if there is only a single item inside a div and you can change your stylesheet to eliminate the div, then the div isn't needed. There are an awful lot of nested divs in your html, and I encourage you to remove as many of them as you can. Apply style to the other block elements you use and at least some, if not many, won't be needed.
I'd suggest (though currently untested):
$('div[id^="tc"]').click(function(){
var num = parseInt(this.id.replace(/\D+/g,''),10);
$('#tb' + num).slideToggle("fast");
});
Though given that you don't need the num to be a number (it'd be fine as a string), you could safely omit the parseInt().
Yes, you can write this code much more compactly like this:
$(document).ready(function() {
for (var i = 1; i < 3; i++) {
$("div#tc" + i).click(function() { $("ul#tb" + i).slideToggle("fast"); } );
}
});

JQuery Copy text & paste into textarea

I've created a javascript function that will take a hidden span, copy the text within that span and insert it into a single textarea tag on a website. I've written a function in JavaScript that does this (well, kinda, only after a few clicks), but I know there's a better way - any thoughts? The behavior is similar to a Retweet for twitter, but using sections of a post on a blog instead. Oh, and I'm also calling out to jquery in the header.
<script type="text/javascript">
function repost_submit(postID) {
$("#repost-" + postID).click(function(){
$("#cat_post_box").empty();
var str = $("span#repost_msg-" + postID).text();
$("#cat_post_box").text(str);
});
}
</script>
Based on the comment in your question, I am assuming you have something like this in your HTML:
copy post
And I am also assuming that because you are passing a post ID there can be more than one per page.
Part of the beauty of jQuery is that you can do really cool stuff to sets of elements without having to use inline Javascript events. These are considered a bad practice nowadays, as it is best to separate Javascript from your presentation code.
The proper way, then, would be to do something like this:
<a href="#" id='copy-5' class='copy_link'>copy post</a>
And then you can have many more that look similar:
<a href="#" id='copy-5' class='copy_link'>copy post</a>
<a href="#" id='copy-6' class='copy_link'>copy post</a>
<a href="#" id='copy-7' class='copy_link'>copy post</a>
Finally, you can write code with jQuery to do something like this:
$(function() { // wait for the DOM to be ready
$('a.copy_link').click(function() { // whenever a copy link is clicked...
var id = this.id.split('-').pop(); // get the id of the post
var str = $('#repost_msg-' + id); // span not required, since it is an ID lookup
$('#cat_post_box').val(str); // empty not required, and val() is the proper way to change the value of an input element (even textareas)
return false;
});
});
This is the best way to do it even if there is only one post in the page. Part of the problem with your code is that on the first click it BINDS the function, and in the subsequent clicks is when it finally gets called. You could go for a quick and dirty fix by changing that around to just be in document.ready.
$("#repost-" + postID).click(function(){
$("#cat_post_box").val(''); // Instead of empty() - because empty remove all children from a element.
$("#cat_post_box").text($("#repost_msg-" + postID).text());//span isn't required because you have and id. so the selector is as efficient as it can be.
});
And wrap everything in a $(document).ready(function(){ /Insert the code here/ }) so that it will bind to $("#repost-" + postID) button or link when the DOM is loaded.
I had a problem with Paolo's example when I clicked on the link the text that appeared in #cat_post_box was "object Object". Once I added ".text()" to the end of that statement I worked.
var str = $('#repost_msg-' + id).text();
Thanks for you example Paolo!

Categories