Thursday, August 30, 2018

Language translator in JavaScript

Hi Folks,

I got a requirement to translate SharePoint list form to multiple languages. I tested with translating from English to Portuguese and German. We can add further languages later. I took use of the link to implement the translation. It is good but I faced issues in translating the text in buttons as for buttons, it is of 'input' type and we need to translate the values stored in those input controls. Also, I've to use a SharePoint list which will have the translations based on respective word in list form. So I've to make changes to the translate.js file referred in the above link to extend the functionality.

Please see below for original and translated form.
Original Form

Translated Form


The JavaScript written in the page is mentioned here:
<script type="text/javascript" src="../../SiteAssets/Scripts/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="../../SiteAssets/Scripts/jquery.translate.js"></script>
<script type="text/javascript" src="../../SiteAssets/Scripts/Dictionary.js"></script>
<script type="text/javascript">

$(function() {

$(".js-category").find("label").each(function(){
var text = $(this).text();
$(this).empty().append( $("<span></span>").addClass("trn").text(text) );
});
$(".js-category").find("select option").each(function(){
$(this).addClass("trn");
});
$(".js-category2").find("label").each(function(){
var text = $(this).text();
$(this).empty().append($("<span></span>").addClass("trn").text(text));
});
$(".js-category3").find("label").each(function(){
var text = $(this).text();
$(this).empty().append( $("<span></span>").addClass("trn").text(text));
});
$(".btnSaveCancl").find("input[type=button]").each(function(){
$(this).addClass("trn");
})
$("nobr").each(function(){
var text = $(this).text();
$(this).empty().append($("<span></span>").addClass("trn").text(text));
//alert(text);
});

});
</script>




The link suggested to add <span class="trn">Your_Text</span> to translate the text. It could able to translate the field labels but not the text which is generated dynamically in my SharePoint fields. So I had to add class to the td's and add JavaScript to add the span dynamically. Please check below.


The jquery.translate.js file referred externally is mentioned below.
/**
 * @file jquery.translate.js
 * @brief jQuery plugin to translate text in the client side.
 * @author Manuel Fernandes
 * @site
 * @version 0.9
 * @license MIT license <http://www.opensource.org/licenses/MIT>
 *
 * translate.js is a jQuery plugin to translate text in the client side.
 *
 */

(function($){
  $.fn.translate = function(options) {

    var that = this; //a reference to ourselves
    var settings = {
      css: "trn",
      lang: "en"/*,
      t: {
        "translate": {
          pt: "tradução",
          br: "tradução"
        }
      }*/
    };
    settings = $.extend(settings, options || {});
    if (settings.css.lastIndexOf(".", 0) !== 0)   //doesn't start with '.'
      settings.css = "." + settings.css;
       
    var t = settings.t;

    //public methods
    this.lang = function(l) {
      if (l) {
        settings.lang = l;
        this.translate(settings);  //translate everything
      }
        
      return settings.lang;
    };


    this.get = function(index) {
      var res = index;
 var _l = settings.lang;
      try {
        //res = t[index][settings.lang]; //takes object
        
        for(var item in t[index]){ //takes array of objects
        if( t[index][item].hasOwnProperty(_l) ){ 
        res = t[index][item][_l];
        break;
        }
        }     
      }
      catch (err) {
        //not found, return index
        return index;
      }
      
      if (res)
        return res;
      else
        return index;
    };

    this.g = this.get;


    
    //main
    this.find(settings.css).each(function(i) {
      var $this = $(this);

      var trn_key = $this.attr("data-trn-key");
      if (!trn_key) {
        trn_key = ($this.is('input') && $this.attr('type')==='button') ? $this.val() : $this.html();
        $this.attr("data-trn-key", trn_key);   //store key for next time
      }
if($this.is('input') && $this.attr('type')==='button'){
$this.val(that.get(trn_key));
}
else{
 $this.html(that.get(trn_key));
}
    
    });
    
    
return this;

  };
})(jQuery);



For button, I had to modify the code with these steps.

This helped me to create a basic prototype for translation.

I created Dictionary.js to read translations from a SharePoint list and perform translation to the SharePoint list form.

var dict = '{';
var _t;
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', RetrieveListItems);

function RetrieveListItems(){
var clientContext = SP.ClientContext.get_current();
var oList = clientContext.get_web().get_lists().getByTitle('Translation');
var caml = new SP.CamlQuery();
caml.set_viewXml("<View />");
listItemCollection = oList.getItems(caml);
clientContext.load(listItemCollection);
clientContext.executeQueryAsync(onRequestSucceeded, onRequestFailed);
}

function onRequestSucceeded(){
var count = listItemCollection.get_count();
//alert(count);
var listEnumerator = listItemCollection.getEnumerator();
while(listEnumerator.moveNext()){
var listItem = listEnumerator.get_current();
var key = listItem.get_item('Title');
var val = listItem.get_item('Value');
var ger = listItem.get_item('German');
//alert(key+' , '+val);
var item_dict = '"'+key+'":[{"pt":"'+val+'"},{"en":"'+key+'"},{"ge":"'+ger+'"}],';
dict = dict + item_dict;
//alert(dict);
}
dict = dict.substring(0, dict.length-1) + '}';
var newList = JSON.parse(dict);
_t = $('body').translate({t: newList});
console.log(dict);
 $(".lang_selector").click(function(ev) {
 
    var lang = $(this).attr("data-value");
    //alert(lang);
    _t.lang(lang);

    console.log(lang);
    ev.preventDefault();
  });

}

function onRequestFailed(sender, args){
alert('Error: ' + args.get_message());
}



The new jQuery.translate.js takes an array of objects unlike the previous object as we couldn't able to create dynamic dictionary and had to create string array in specific format. Then we parse it as JSON and transferred the object array for translation.




Thanks,
Kunal

No comments:

Post a Comment