Implementing Google Translate with custom flag icons
Asked Answered
B

14

25

Currently, I'm using the simple Google Translate drop-down menu found here: http://translate.google.com/translate_tools

I'd like to also be able to click on some flag icons I have and trigger the same javascript calls that are called by the text-based links in the google translate widget.

Anyone have ideas on how to accomplish this? I can't figure out how to make clicking on the flags initiate the same behavior as clicking on the google translate text links.

Biologist answered 7/5, 2012 at 18:2 Comment(1)
E
53

Had a lot of fun finding a solution for this question!

<!-- Use CSS to replace link text with flag icons -->
<ul class="translation-links">
  <li><a href="#" class="spanish" data-lang="Spanish">Spanish</a></li>
  <li><a href="#" class="german" data-lang="German">German</a></li>
</ul>

<!-- Code provided by Google -->
<div id="google_translate_element"></div>
<script type="text/javascript">
  function googleTranslateElementInit() {
    new google.translate.TranslateElement({pageLanguage: 'en', layout: google.translate.TranslateElement.InlineLayout.SIMPLE, autoDisplay: false}, 'google_translate_element');
  }
</script>
<script src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit" type="text/javascript"></script>

<!-- Flag click handler -->
<script type="text/javascript">
    $('.translation-links a').click(function() {
      var lang = $(this).data('lang');
      var $frame = $('.goog-te-menu-frame:first');
      if (!$frame.size()) {
        alert("Error: Could not find Google translate frame.");
        return false;
      }
      $frame.contents().find('.goog-te-menu2-item span.text:contains('+lang+')').get(0).click();
      return false;
    });
</script>
Eddi answered 19/7, 2012 at 14:34 Comment(11)
That is awesome, thank you. Do you have a way of accepting $ donations??Biologist
Not really, I'm just happy to help :)Eddi
Ah crap. It stopped working. The classes and structure you found seem to still be true. But the JS isn't finding those elements anymore. Something Google could have done to their JS to stop this from working?Biologist
For some reason the :contains() selector stopped working in this case. When I changed $frame.contents().find('.goog-te-menu2-item span.text:contains('+lang+')').get(0).click(); to $('.goog-te-menu-frame:first').contents().find('.goog-te-menu2-item span.text').each(function(){ if( $(this).html() == lang ) $(this).click(); }); It worked again.Biologist
The problem is user local. If it isnt english It wont work.Chartography
plus: for manually performing operations on closing of language translators we can do like this : var $lang_status_frame = $('.goog-te-banner-frame:first'); if (!$lang_status_frame.size()) { return false; }else{ //perform operations here. return true; }Winner
@Eddi Thanks for this solution, however I find that when clicking any li>a other than first, this click event converts website but same changes li:first->a.text to clicked li->a's text. I tried doing e.preventDefault, e.stopPropagation, but its not working. I think Google script is doing this. help me, how can I hide the original event target. I think the problem is google is changing 'select' element's first text, so it automatically changing text of first li>a.Shogunate
This solutions looks great but somehow, it doesnt work anymore. could there be a solution to thisDimmick
I get the following error if I use the above code. Please help me. Error: Permission denied to access property "document"Kerns
One thing to note using this solution is that Jquery's Size function is deprecated and depending on the version that you are using, it may no longer be implemented. api.jquery.com/sizeCounselor
var $frame = $('.goog-te-menu-frame:first'); -> this frame is only created once we choose an option from google translate language drop down.Monarchal
B
8

@mogelbrod code isn't always working so I hacked it a bit.

If user is logged in Google Account, Google will detect it's language and automatically translate language text so you won't be able to fire event on desired element because data-lang attribute won't be correct!

Users that aren't logged in Google Account and American / English users will have this. en

And for example; Croatian users will have this.

hr

In this case it's better to map language order. For example from above, that would be

0 - English

1 - French

2 - German

3 - Italian

HTML:

Note the data-placement property (you can change element order, but preserve placement as above).

<div class="translation-icons" style="visibility:hidden">
    <a href="#" class="eng" data-placement="0">eng icon</a>
    <a href="#" class="fra" data-placement="1">fra icon</a>
    <a href="#" class="ger" data-placement="2">ger icon</a>
    <a href="#" class="ita" data-placement="3">ita icon</a>
</div>

JS: I had to change find selector. Note that when user choses language, there's no more "Choose Language" element in #google_translate_element div so I had to handle that, too.

Also it's good not to show icons until all scripts (google translate) are loaded.

$(window).load(function () {

    $('.translation-icons').css('visibility', 'visible');

        $('.translation-icons a').click(function(e) {
            e.preventDefault();
            var placement = $(this).data('placement');
            var lang_num = $('.translation-icons a').length;
            var $frame = $('.goog-te-menu-frame:first');

            if (!$frame.size()) {
                alert("Error: Could not find Google translate frame.");
                return false;
            }

            var langs = $('.goog-te-menu-frame:first').contents().find('a span.text');

            if(langs.length != lang_num) placement = placement+1;

            langs.eq(placement).click();
            return false;
        });
});
Bataan answered 21/10, 2012 at 15:38 Comment(0)
B
4

@mogelbrod, I used your code above and it worked perfectly on Chrome, tried it on Firefox and Safari, did not work. The span.click event doesn't fire the event handler of google translate.

I came up with another method I just wanna share by using the google select instead the iframe-based plugin.

<!-- Use CSS to replace link text with flag icons -->
<ul class="translation-links">
  <li><a href="#" class="spanish" data-lang="Spanish">Spanish</a></li>
  <li><a href="#" class="german" data-lang="German">German</a></li>
</ul>

<!-- Code provided by Google -->
<div id="google_translate_element"></div>
<script type="text/javascript">
  function googleTranslateElementInit() {
    new google.translate.TranslateElement({pageLanguage: 'en', autoDisplay: false}, 'google_translate_element'); //remove the layout
  }
</script>
<script src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit" type="text/javascript"></script>


<script type="text/javascript">
    function triggerHtmlEvent(element, eventName) {
var event;
if(document.createEvent) {
    event = document.createEvent('HTMLEvents');
    event.initEvent(eventName, true, true);
    element.dispatchEvent(event);
} else {
    event = document.createEventObject();
    event.eventType = eventName;
    element.fireEvent('on' + event.eventType, event);
}
}
            <!-- Flag click handler -->
        $('.translation-links a').click(function(e) {
  e.preventDefault();
  var lang = $(this).data('lang');
  $('#google_translate_element select option').each(function(){
    if($(this).text().indexOf(lang) > -1) {
        $(this).parent().val($(this).val());
        var container = document.getElementById('google_translate_element');
        var select = container.getElementsByTagName('select')[0];
        triggerHtmlEvent(select, 'change');
    }
});
});

        </script>

Tested on: Chrome (win & Mac), Safari(Win & Mac), FireFox (win) and IE8

By the way, the issue of the span.click event I encountered on Firefox and Safari could be solved by using the triggerHtmlEvent function above, I haven't tried it though.

Berns answered 6/1, 2013 at 5:28 Comment(0)
C
4

Now no scripting is required!

Add the tag #googtrans(TO_LANG_CODE) to the address that your respective flag links to.

Here TO_LANG_CODE is the language code for the language you want. This assumes the page uses Google Website Translator as in the question and your original language can be automatically identified.

Identifying the original language can help avoid errors, to do so use the form #googtrans(FROM_LANG_CODE|TO_LANG_CODE).

Example:
http://nykopingsguiden.se/#googtrans(se|es) translates the Swedish page
http://nykopingsguiden.se from Swedish to Spanish.

Capacitor answered 11/6, 2014 at 21:34 Comment(0)
C
4

I think this jsfiddle will help you out: https://jsfiddle.net/solodev/0stLrpqg/

function googleTranslateElementInit() {
  new google.translate.TranslateElement({pageLanguage: 'en', layout: google.translate.TranslateElement.FloatPosition.TOP_LEFT}, 'google_translate_element');
}

function triggerHtmlEvent(element, eventName) {
  var event;
  if (document.createEvent) {
    event = document.createEvent('HTMLEvents');
    event.initEvent(eventName, true, true);
    element.dispatchEvent(event);
  } else {
    event = document.createEventObject();
    event.eventType = eventName;
    element.fireEvent('on' + event.eventType, event);
  }
}

jQuery('.lang-select').click(function() {
  var theLang = jQuery(this).attr('data-lang');
  jQuery('.goog-te-combo').val(theLang);

  //alert(jQuery(this).attr('href'));
  window.location = jQuery(this).attr('href');
  location.reload();

});
Centrifugate answered 24/10, 2019 at 10:55 Comment(1)
When I change the language, the page is loaded but a progress bar favicon icon still works a bit then it's completed. How can I fix it?Fontanez
A
3

Implementing Google Translate With Custom Flag Icons

Refer to this link

enter image description here

The benifit of this custom list is than we can hide the google translator widget and use all the language to translate the web page.

<div id="google_translate_element" style="display: none">
    </div>
    <script type="text/javascript">
        function googleTranslateElementInit() {
            new google.translate.TranslateElement({ pageLanguage: 'en', layout: google.translate.TranslateElement.InlineLayout.SIMPLE, autoDisplay: false }, 'google_translate_element');
        }
    </script>
    <script src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"
        type="text/javascript"></script>
    <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
    <script>
        function translate(lang) {

            var $frame = $('.goog-te-menu-frame:first');
            if (!$frame.size()) {
                alert("Error: Could not find Google translate frame.");
                return false;
            }
            $frame.contents().find('.goog-te-menu2-item span.text:contains(' + lang + ')').get(0).click();
            return false;
        }
    </script>
Adolphus answered 3/7, 2015 at 7:2 Comment(3)
Using flags in relation to languages is generally a bad idea because languages are being spoken in different countries, plus some countries have more than one official language.Doghouse
Is it possible to change the shape of the flag? i what my flag to be in circles.. i am using wordpress plugin.. though i have a css box to edit.. i dont know how to change it in to circles.. would you please help me with thatFuzee
Doesn't work for the first time due to this code var $frame = $('.goog-te-menu-frame:first');Monarchal
L
1

default language issue sorted with the following code

if(lang!="English"){
        $frame.contents().find('.goog-te-menu2-item span.text:contains('+lang+')').get(0).click();
    }else{
        console.log($frame2.contents().find('.goog-te-banner .goog-te-button button').get(0));
        $frame2.contents().find('.goog-te-banner .goog-te-button button').get(1).click();
    }
Lorikeet answered 20/10, 2014 at 12:0 Comment(0)
D
1

To implement a totally backend solution (before the translate.js included) you just can create a php file which contains

<?php setcookie('googtrans', '/en'); header('location:index.html')?>

If you want your page in spanish you just add other php file like:

<?php setcookie('googtrans', '/en/es'); header('location:index.html')?>

Finally link this file to any 'a' tag

<a href="defaultLang.php"></a>
Dalia answered 14/1, 2015 at 15:50 Comment(0)
C
1

This is a fix to Boris Samardžija's solution as it fails whenever the names of the languages in the visitor's language result in their different order.

First, have correct language codes in some attribute of the icons. E.g. <a href="#" data-lang="German" data-class="de">. Then, make sure you will have google translate element available, e.g.:

<script type="text/javascript">
var tis;
function googleTranslateElementInit() {
    tis = new google.translate.TranslateElement({defaultLanguage: 'en', pageLanguage: 'en', includedLanguages: 'en,es,it,de,fr', layout: google.translate.TranslateElement.InlineLayout.SIMPLE, autoDisplay: false}, 'google_translate_element');
}
</script>

This allows you to find the language name to be translated to in the language of the visitor through the property sl of property C of the google element, which is a mapping of language codes to the names:

$(window).load(function () {    
    $('.translation-links a').click(function(e) {
        e.preventDefault();
        var $frame = $('.goog-te-menu-frame:first');

        if (!$frame.size()) {
            alert("Error: Could not find Google translate frame.");
            return false;
        }

        var codes_names = tis.C.sl;
        var selected_lang = codes_names[$(this).data('class')];

        $('.goog-te-menu-frame:first').contents().find('a span.text:contains(' + selected_lang + ')').click();

        return false;
    });
});
Celestine answered 15/8, 2015 at 5:53 Comment(0)
A
1

I was struggling with this problem too - to make the flags clickable and to hide the gtranslate select menu instead. Google probably changes thing from time to time so the codes above didn't work for me... Thought they brought me to the good ideas and finally the solution.

  1. map the languages. Choose the languages you need and loog good in which order they are shown in the gtranslate dropdow - the flag links should have the same order. It is important!

  2. in the function proveded bu google function googleTranslateElementInit(), add the MultilanguagePage: true parametr. I have also commented out the default language and pagelanguage... for some reason this works...

     //load the script of google  
    <script src="http://translate.google.com/translate_a/element.js?    cb=googleTranslateElementInit" type="text/javascript"></script>
    <script>
    
    function googleTranslateElementInit() {
    new google.translate.TranslateElement({
    //defaultLanguage: 'en', 
    //pageLanguage: 'en', 
    includedLanguages: 'de,nl,en,es,it,fr', 
    layout: google.translate.TranslateElement.InlineLayout.SIMPLE, 
    autoDisplay: false,
    multilanguagePage: true}, 'google_translate_element')
    };
    
    //this one I need because of the first menu with "select the language" item,              after the first click on the language it disappears 
    var clickCount = 0;
    
    $(window).load(function () {
    
        $('.translation-icons a').click(function(e) {
        e.preventDefault();
    
        var $frame = $('.goog-te-menu-frame:first');
    
        if (!$frame.size()) {
            alert("Error: Could not find Google translate frame.");
            return false;
            }
    
         //find the a links element inside the gtranlate first frame
        var langs = $('.goog-te-menu-frame:first').contents().find('.goog-te-menu2 a');
    
         //the number of the language in flag-elements
        var placement = $(this).data('placement');
    
     //this again I need to adjust the mapping numbers of the languages in the flag elements        
        if (clickCount == 0){
            placement = $(this).data('placement')+1;
            clickCount++;
            }
        //and finaly imitate click on the gtranslate element which is the same as the number of the language in flag link
        langs.eq(placement).find('span.text').click();
        return false;
    
    });
    });
    

And finaly the html of the "flag elements".(for now it's only text inside the , but you can put any img there if you want) And don;t forget to create the google translate element!

       <!-- Code provided by Google -->
       <div id="google_translate_element"></div>

    <div class="translation-icons">
       <a href="#" class="nl" data-placement="0">nl</a>
       <a href="#" class="de" data-placement="1">de</a>
       <a href="#" class="en" data-placement="2">en</a>
      <a href="#" class="fr" data-placement="3">fr</a>
      <a href="#" class="it" data-placement="4">it</a>
      <a href="#" class="sp" data-placement="5">es</a>
   </div>
Artful answered 17/10, 2015 at 12:39 Comment(0)
B
1

I made my own solution based on "select" version of Google Translate:

<div id="google_translate_element"></div><script type="text/javascript">
function googleTranslateElementInit() {
  new google.translate.TranslateElement({pageLanguage: 'pl', includedLanguages: 'de,en,pl', autoDisplay: false}, 'google_translate_element');
}
</script><script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>

I used setcookie() on PHP:

if ($_GET['lang']) {
  setcookie("googtrans", "", time() - 3600);
  $domena = "." . $_SERVER['HTTP_HOST'];
  setcookie("googtrans", '/pl/' . $_GET['lang'], time()+(3600*24), '/' , $domena);
}

I don't know why google script makes 2 same cookies, with the same name, but different domain:

look at the screen of EditThisCookie

($_COOKIE[] sees only one cookie)

so this code needs to name domain with "." on beggining, and first delete "googtrans" cookie (doesnt work without deleting ;/ ).

and here are my html icons:

wybierz język:
<a href="?lang=pl"><img src="imgcss/pl.png" alt="" /></a>
<a href="?lang=en"><img src="imgcss/en.png" alt="" /></a>
<a href="?lang=de"><img src="imgcss/de.png" alt="" /></a>

and to hide default google select list which is generated, just add one line to css code:

#google_translate_element {display: none; }

Remember to change page language values before using code above ;)

Bolshevist answered 10/2, 2016 at 18:5 Comment(0)
D
1

I have the running code. Where you can create a custom select box with your flag or HTML.

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Google Translation</title>
</head>
<body>
    <form id="form1" runat="server">
    <div id="google_translate_element" style="display: none">
    </div>
    <script type="text/javascript">
        function googleTranslateElementInit() {
            new google.translate.TranslateElement({ pageLanguage: 'en', layout: google.translate.TranslateElement.InlineLayout.SIMPLE, autoDisplay: false }, 'google_translate_element');
        }
    </script>
    <script src="http://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"
        type="text/javascript"></script>
    <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
    <script>
        function translateLanguage(lang) {
           console.log(lang);
           googleTranslateElementInit();
            var $frame = $('.goog-te-menu-frame:first');
            console.log($frame);
            if (!$frame.size()) {
                alert("Error: Could not find Google translate frame.");
                return false;
            }
            $frame.contents().find('.goog-te-menu2-item span.text:contains(' + lang + ')').get(0).click();
            return false;
        }
    </script>
       <select id="newdemo" onchange="translateLanguage(this.value);">
        <option><a href="javascript:;" val="German"><span>German </span>
            <img src="img/flags/germany_flag.jpg" alt="" /></a> </option>
        <option><a href="javascript:;" val="Italian"><span>Italian
        </span>
            <img src="img/flags/italy_flag.jpg" alt="" /></a> </option>
        <option><a href="javascript:;" val="Hindi"><span>Hindi </span>
            <img src="img/flags/india_flag.png" alt="" /></a> </option>
        <option><a href="javascript:;" val="French"><span>French </span>
            <img src="img/flags/french_flag.jpg" alt="" /></a> </option>
        <option><a href="javascript:;" val="Spanish"><span>Spanish
        </span>
            <img src="img/flags/spain_flag.jpg" alt="" /></a> </option>
        <option><a href="javascript:;" val="Russian"><span>Russian
        </span>
            <img src="img/flags/russia_flag.jpg" alt="" /></a> </option>
    </select>
    <div>
        In this article we explain how to translate the web page into different language
        using google translator. We create a custom country list with flag and call the
        google translator code using javascript custom code. The benifit of this custom
        list is than we can hide the google translator widget and use all the language to
        translate the web page.
    </div>
    </form>
</body>
</html>
Degauss answered 12/6, 2019 at 9:54 Comment(0)
M
1

I have been researching a lot and in the end this works correctly for me:

<div id="google_translate_element"> </div>
<div class="menu-traslate-header">
<ul>
  <li><a href="#googtrans/es">Español</a></li>
  <li><a href="#googtrans/zh-CN">汉语</a></li>
  <li><a href="#googtrans/vi">Việt</a></li>
  <li><a href="#googtrans/ru">Русский</a></li>
  <li><a href="#googtrans/sq">SHQIP</a></li>
  <li><a href="#googtrans/km">ខ្មែរ</a></li>
  <li><a href="#googtrans/fr">Français</a></li>
  <li><a href="#googtrans/ar">عربي</a></li>
</ul>
</div>
 <script type="text/javascript">
function googleTranslateElementInit() {
  new google.translate.TranslateElement({
    pageLanguage: 'en', 
    includedLanguages: 'ar,en,es,fr,km,ru,sq,vi,zh-CN', 
    layout: google.translate.TranslateElement.InlineLayout.SIMPLE, 
    multilanguagePage: true, 
    gaTrack: true, 
  }, 'google_translate_element');
}
</script>
<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
 <script type="text/javascript">
jQuery(document).ready(function($) {
  $('.menu-traslate-header ul li a').click(function(event) {
      window.location = $(this).attr('href');
      location.reload();
  });
});
</script>
Methodical answered 5/4, 2021 at 16:48 Comment(0)
E
-1
<script type="text/javascript" src="jquery-1.8.2.min.js"></script>


 <li><a href="#googtrans(en|en)" class="lang-en lang-select" data-lang="en"><img src="English.png" alt="USA"></a></li>
 <li><a href="#googtrans(en|fr)" class="lang-es lang-select" data-lang="fr"><img src="/French.png" alt="FRANCE"></a></li>
<li><a href="#googtrans(en|de)" class="lang-es lang-select" data-lang="de"><img src="German.png" alt="Germany"></a></li>

<li><a href="#googtrans(en|it)" class="lang-es lang-select" data-lang="it"><img src="Italian.png" alt="Italy"></a></li>
<li><a href="#googtrans(en|ja)" class="lang-es lang-select" data-lang="ja"><img src="Japanese.png" alt="JAPAN"></a></li>
<div class="container">
    <h1>Use Google Translate with your Website</h1>
</div>



<script type="text/javascript">
    function googleTranslateElementInit() {
      new google.translate.TranslateElement({pageLanguage: 'en', layout: google.translate.TranslateElement.FloatPosition.TOP_LEFT}, 'google_translate_element');
    }

    function triggerHtmlEvent(element, eventName) {
      var event;
      if (document.createEvent) {
        event = document.createEvent('HTMLEvents');
        event.initEvent(eventName, true, true);
        element.dispatchEvent(event);
      } else {
        event = document.createEventObject();
        event.eventType = eventName;
        element.fireEvent('on' + event.eventType, event);
      }
    }

    jQuery('.lang-select').click(function() {
      var theLang = jQuery(this).attr('data-lang');
      jQuery('.goog-te-combo').val(theLang);

      //alert(jQuery(this).attr('href'));
      window.location = jQuery(this).attr('href');
      location.reload();

    });
</script>
<script type="text/javascript" src="https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
Exchange answered 26/12, 2018 at 12:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.