Implementing Google Translate with custom flag icons
Solution 1:
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>
Solution 2:
@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.
And for example; Croatian users will have this.
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;
});
});
Solution 3:
@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.