0

I tried to make a multilanguage site with html and javascript. For selecting the language I created three radio boxes (values: en, de, fr). The words which should be displayed are stored in a javascript object.

Here is the code:

$('#lang-setting').on('change', function () {
var lang = $('input:checked', '#lang-setting').val();
console.log(lang);
alert(lang);
$('#latitude-n').html(lang.latitude);
$('#longitude-n').html(lang.longitude);
$('#accuracy-n').html(lang.accuracy);
$('#words-n').html(lang.words);
$('#map-n').html(lang.map);
$('#test').html(de.test);
});

alert(lang) and console.log give the right language every time I select a language.

But: the other words don't change. They do if I replace the 'lang' with f.e. 'de' (see last code line).

AndiLeni
  • 481
  • 1
  • 6
  • 16
  • lang is a string, so lang.latitude is undefined. If you have made a global object called de in window with translations, what you need to do is window[lang].latitude, which computes to de.latitude if lang === 'de' – juvian Apr 17 '17 at 17:23
  • 1
    Basically a duplicate of: https://stackoverflow.com/questions/4244896/dynamically-access-object-property-using-variable –  Apr 17 '17 at 17:28
  • Possible duplicate of [Dynamically access object property using variable](http://stackoverflow.com/questions/4244896/dynamically-access-object-property-using-variable) – juvian Apr 17 '17 at 17:32
  • any HTML to show? How does look your object at all? – Roko C. Buljan Apr 17 '17 at 17:34
  • @juvian Your solution worked verry well. The only thing I still don't understand is why the 'window' prefix ist needed. – AndiLeni Apr 17 '17 at 17:36
  • Also why do you use checkoxes? So that one can read all languages at the same time? – Roko C. Buljan Apr 17 '17 at 17:36
  • You could also use a loop and target elements ID by your object propertyname instead if writing all those selectors... – Roko C. Buljan Apr 17 '17 at 17:40
  • @AndiLeni because your language objects are window.de, window.fr, window.en (the global scope is windows, so all variables defined with global scope are stored in windows object). Still, Tessa answer is a nicer approach – juvian Apr 17 '17 at 17:41
  • @juvian Now I understand it. Thanks for your explanation! – AndiLeni Apr 17 '17 at 17:43
  • 1
    @RokoC.Buljan should be radio boxes. thanks for mentioning – AndiLeni Apr 17 '17 at 17:44

2 Answers2

2

It doesn't work that way, you need brackets notation.

var words = {
  de: {
    lat: "Breitengrad",
    lon: "Längengrad"
  },
  en: {
    lat: "Latitude",
    lon: "Longitude"
  },
  fr: {}
};

function changeLanguage() {
  var lang = $('#lang-setting input:checked').val();
  $('#latitude-n').html(words[lang].lat);
}

$('#lang-setting input').click(changeLanguage);
changeLanguage();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="lang-setting">
  <input type="radio" value="en" name="lang" checked>En</option>
  <input type="radio" value="de" name="lang">De</option>
  <input type="radio" value="fr" name="lang">Fr</option>
</div>
<p>
  <span id="latitude-n"></span>: <input />
</p>
2

Your variable named lang is a string because you're setting it to the value of the radio input, so lang.latitude, lang.longitude, lang.accuracy, lang.words, and lang.map are all undefined.

I'm assuming you have global variables such as de set since you said de.test works.

It would probably be easiest to put all of those languages into a single object that you can then reference by the key, or the value of the radio input. I've also added a variable that allows you to select the default language and the function that will be performing the actual html change.

var translate = {
    default: 'en',
    en: {
        latitude: 'latitude',
        longitude: 'longitude',
        accuracy: 'accuracy',
        words: 'words',
        map: 'map',
    },
    de: {
        latitude: '',
        longitude: '',
        accuracy: '',
        words: '',
        map: '',
    },
    fr: {
        latitude: '',
        longitude: '',
        accuracy: '',
        words: '',
        map: '',
    },
    changeText: function(lang) {
        $('#latitude-n').html(translate[lang].latitude);
        $('#longitude-n').html(translate[lang].longitude);
        $('#accuracy-n').html(translate[lang].accuracy);
        $('#words-n').html(translate[lang].words);
        $('#map-n').html(translate[lang].map);
    }
}

Since you didn't post the HTML of your three radio buttons, I'm going to instead give them name attributes instead of id's of with the value "lang-settings" because having duplicate id's is invalid HTML. Below is the minimal HTML for these radio buttons.

<input name="lang-setting" value="en" type="radio" />
<input name="lang-setting" value="de" type="radio" />
<input name="lang-setting" value="fr" type="radio" />

Then for your listener, I've switched it to listen for "clicks" instead of changing, because the values of the radio button isn't actually changing, they're staying as "en", "de", and "fr". I've also added the function call in document ready to run your default language selection on page load.

$('input[name="lang-setting"]').on('click', function(e){
    var lang = $(this).val();
    translate.changeText(lang);
});
$(document).ready(function(){
    translate.changeText(translate.default);
});

Here's a working demo of it on JSFiddle

AuRise
  • 2,253
  • 19
  • 33
  • 1
    This is the best answer imo. – Lewis Apr 17 '17 at 17:38
  • I realy like your solution. Unfortunately it gives me this error message: Cannot read property 'latitude' of undefined – AndiLeni Apr 17 '17 at 17:46
  • Did you create the "translate" variable of objects? In the console, you should be able to type "translate.de.latitude" and it should give you the value of whatever you made it. I don't know German or French so I just left them as empty strings, but I Imagine you already have those values in your code to copy/paste into it. – AuRise Apr 17 '17 at 17:49
  • If that works, then add in a "debugger" after capturing the value of the "lang" variable inside the listener, and make sure we're getting the right string. – AuRise Apr 17 '17 at 17:51
  • I changed my code and it works fine now. If I might ask you another question, obviously I need to preselect a language before changing it. Otherwise there won't be any text at all. Can I simply set the lang var at the beginning so it only changes when I want it to change? – AndiLeni Apr 17 '17 at 17:59
  • See my answer on how to do that. –  Apr 17 '17 at 17:59
  • See my JSFiddle for updated code that allows you run a default language on page load. https://jsfiddle.net/TessaLiliana/s2Ldggs9/2/ – AuRise Apr 17 '17 at 18:08
  • I used the 'checked' prefix but it only affected the radio button (checked). Still no text shown EDIT: I think it's ok if I just enter the english names as default text so it only changes the text when needed. – AndiLeni Apr 17 '17 at 18:08
  • You shouldn't need to use the checked prefix at all because when the radio button is clicked, you know what button is checked at that time. Refresh the page or checkout the JSFiddle I added, and you'll see I included code snippets on how to get the default language on page load. – AuRise Apr 17 '17 at 18:13
  • @Tessa Thats impressive. I would have thought about this in a hundred years. But I'm a beginner so I guess I learned an important lesson today. – AndiLeni Apr 17 '17 at 18:15
  • That's the nicest thing anyone has said to me today! Thanks! We were all beginners at some point :) If there's one thing I've learned, there's about a million ways to do the same thing in programming, and most of them are right ;) – AuRise Apr 17 '17 at 18:22
  • 1
    And most of them either work and you dont't know why or they don't work and don't know why :) This probably applies to beginners only. – AndiLeni Apr 17 '17 at 19:03