SOLVED

Re: Form Translation Next Steps

Go to solution
Michelle_Stunka
Level 2

I'm in the process of setting up forms to replace many current forms on our site. Each form has to be translated into at least 5 different languages so I'm trying to handle that with Sanford's translation code referenced on this thread: https://nation.marketo.com/message/94034#comment-94034

It's working great but I'm stumped on how to add additional fields to the translation map:

https://www.m-files.com/en/marketo-test-form

<div id="translateMap"><span style="display: none;">

{

"en": {

"LastName": {

"placeholder": "Testing-Name",

"submit": "Go Home"

}

},

"fr": {

"LastName": {

"placeholder": "Testing-Name",

"submit": "Go Bonjour"

}

}

}

</span></div>

Any ideas on how I can get the full form setup in this map?

1 ACCEPTED SOLUTION
SanfordWhiteman
Level 10 - Community Moderator

Each language is an object, and each field name is a property of that object (and is also an object itself).

So you extend it like so:

{

  "en": {

    "LastName": {

      "placeholder": "Testing-Name",

      "submit": "Go Home"

    },

    "FirstName": {

      "placeholder": "First"

    }

  },

  "fr": {

    "LastName": {

      "placeholder": "Testing-Name",

      "submit": "Go Bonjour"

    },

    "FirstName": {

      "placeholder": "Prénom"

    }

  }

}

The admittedly strange thing about this format, which I wouldn't do again but apparently was lazy about a couple of years ago, is that "submit" should've been a property right on the language. But it's not, so you have to use it as shown.

Please use the Advanced Editor's syntax highlighter in future when posting code:

https://s3.amazonaws.com/blog-images-teknkl-com/syntax_highlighter.gif

View solution in original post

11 REPLIES 11
SanfordWhiteman
Level 10 - Community Moderator

Each language is an object, and each field name is a property of that object (and is also an object itself).

So you extend it like so:

{

  "en": {

    "LastName": {

      "placeholder": "Testing-Name",

      "submit": "Go Home"

    },

    "FirstName": {

      "placeholder": "First"

    }

  },

  "fr": {

    "LastName": {

      "placeholder": "Testing-Name",

      "submit": "Go Bonjour"

    },

    "FirstName": {

      "placeholder": "Prénom"

    }

  }

}

The admittedly strange thing about this format, which I wouldn't do again but apparently was lazy about a couple of years ago, is that "submit" should've been a property right on the language. But it's not, so you have to use it as shown.

Please use the Advanced Editor's syntax highlighter in future when posting code:

https://s3.amazonaws.com/blog-images-teknkl-com/syntax_highlighter.gif

Ricardo_Bardaro
Level 1

Some of my fields are drop downs and I would like to also translate the  drop down options as well. 

Do you mind posting an example of the json for when you the field is a drop down with the drop down options? 

Thanks for posting this solution, this has all been very helpful so far. 

SanfordWhiteman
Level 10 - Community Moderator

At the point that you're translating option values as well, you need to move to something heavier hitting: the live form descriptor management as a demoed here and tipped off here.

lianef
Level 2

Hi @SanfordWhiteman

I am trying to use picklist values (option value) in our code that we are developing to translate form fields via a program token, it works great for form fields, however I'm unsure of the setup for the picklist values and div ids for the rich text portions.An important thing to note is we don't use munchkin code.  Any guidance here would be appreciated. Thank you

EX:
(function () {
var translations = {
"en":{
"FirstName":"First Name:",
"LastName":"Last Name:",
"Email":"Email Address:",
"Phone":"Phone Number:",
"Submit":"Submit",


for (var labelTranslation in translations[language]) {
//Identify each element and change placeholder, but only try to replace a placeholder, if the field exists
if ($("label[for='" + labelTranslation + "']").length) {
$("label[for='" + labelTranslation + "']").text(
translations[language][labelTranslation]
);
}
}

//Translate Submit Text
submitText = translations[language]["Submit"];
form.getFormElem().find("button.mktoButton").html(submitText);
});

// ]]>
})();
SanfordWhiteman
Level 10 - Community Moderator

Hi,

  • Please edit your post to use the syntax highlighter (Insert/Edit code sample on the toolbar) so the code is readable.
  • Munchkin isn’t relevant at all to how forms are rendered.
  • Also not sure what you’re asking. It looks like you’re trying to do translations in the live HTML, i.e. after the form is initially rendered. I don’t recommend doing it that way. Instead, translate the form descriptor object, as noted above.
lianef
Level 2
function unchecked() {
  var opt = document.getElementById("Opt_In__c");
  opt.checked = false;
  var check = opt.parentElement.parentElement.parentElement.parentElement;
  check.style.display = "block";
  var text =
    document.getElementById("optin text").parentElement.parentElement
      .parentElement.parentElement;
  text.style.display = "none";
}
function checked() {
  var opt = document.getElementById("Opt_In__c");
  opt.checked = true;
  var check = opt.parentElement.parentElement.parentElement.parentElement;
  check.style.display = "block";
  var text =
    document.getElementById("optin text").parentElement.parentElement
      .parentElement.parentElement;
  text.style.display = "none";
}
function hide() {
  var opt = document.getElementById("Opt_In__c");
  opt.checked = true;
  var check = opt.parentElement.parentElement.parentElement.parentElement;
  check.style.display = "none";
  var text =
    document.getElementById("optin text").parentElement.parentElement
      .parentElement.parentElement;
  text.style.display = "block";
}
// <![CDATA[
//Define all translations categorised by language, then field.
//Note that the last value in each language object does not have a
//trailing comma. The same after/between language objects.
//The label names (e.g. 'FirstName') must match the HTML ID of the field.
(function () {
    var translations = {
        "en":{
           "FirstName":"First Name:",
           "LastName":"Last Name:",
           "Email":"Email Address:",
           "Phone":"Phone Number:",
           "Company":"Business Name:",
           "User_Provided_Company_Name__c":"Business Name:",
           "Title":"Job Title:",
           "CountryCode":"Country:",
           "StateCode":"Your State?",
           "City":"City:",
           "OptIn":"Opt In:",
           "Submit":"Submit",
        },
        "en2":{
           "FirstName":"First Name2:",
           "LastName":"Last Name2:",
           "Email":"Email Address2:",
           "Phone":"Phone Number2:",
           "Company":"Business Name2:",
           "Title":"Job Title2:",
           "CountryCode":"Country2:",
           "StateCode":"Your State2?",
           "City":"City2:",
           "OptIn":"Opt In2:",
           "Submit":"Submit2",
        },
        "en3":{
           "FirstName":"First Name3:",
           "LastName":"Last Name3:",
           "Email":"Email Address3:",
           "Phone":"Phone Number3:",
           "Company":"Business Name3:",
           "Title":"Job Title3:",
           "CountryCode":"Country3:",
           "StateCode":"Your State3?",
           "City":"City3:",
           "OptIn":"Opt In3:",
           "Submit":"Submit3",
       }
     };

  //Script that waits for the form to load. This version ONLY WORKS ON MARKETO LPs.
  //On your company website, you need another script. See http://developers.marketo.com/javascript-api/forms/
  MktoForms2.onFormRender(function (form) {
    var url = new URL(window.location.href);
    var privacy = url.searchParams.get("pref");
    var opt = document.getElementById("Opt_In__c");
    var check = opt.parentElement.parentElement.parentElement.parentElement;
    var text =
      document.getElementById("optin text").parentElement.parentElement
        .parentElement.parentElement;
    text.style.display = "none";
    check.style.display = "none";
    if (privacy === "K" || privacy === "N") {
      hide();
    } else if (privacy === "P") {
      checked();
    } else if (privacy === "U") {
      unchecked();
    } else {
      var select = document.getElementById("CountryCode");
      select.addEventListener("change", (e) => {
        var hideCountries = [
          "MO",
          "IN",
          "BO",
          "DM",
          "DO",
          "EC",
          "SV",
          "HN",
          "JM",
          "PY",
          "TT",
          "US",
          "BH",
          "BW",
          "BI",
          "CM",
          "CF",
          "TD",
          "CG",
          "CI",
          "GQ",
          "ER",
          "GA",
          "GM",
          "GN",
          "KE",
          "LS",
          "LY",
          "MW",
          "ML",
          "MR",
          "NE",
          "OM",
          "QA",
          "RW",
          "SC",
          "TZ",
          "TG",
          "UG",
          "YE",
          "ZM",
          "ZW",
        ];
        var precheckedCountries = [
          "AF",
          "AS",
          "BD",
          "BT",
          "BN",
          "KH",
          "CX",
          "CC",
          "CK",
          "FJ",
          "PF",
          "GU",
          "HK",
          "ID",
          "KI",
          "LA",
          "MH",
          "FM",
          "MM",
          "NR",
          "NP",
          "NC",
          "NU",
          "NF",
          "MP",
          "PW",
          "PG",
          "PN",
          "WS",
          "SB",
          "LK",
          "TH",
          "TL",
          "TK",
          "TO",
          "TV",
          "UM",
          "VU",
          "WF",
          "AX",
          "DZ",
          "AD",
        ];
        var uncheckedCountries = [
          "AU",
          "CN",
          "JP",
          "MY",
          "MN",
          "NZ",
          "PK",
          "PH",
          "SG",
          "KR",
          "TW",
          "VN",
          "AR",
          "BR",
          "CO",
          "CR",
          "PE",
          "UY",
          "VE",
          "CA",
          "AL",
          "AO",
          "AM",
          "AT",
          "AZ",
          "BY",
          "BE",
          "BJ",
          "BA",
          "BG",
          "BF",
          "HR",
          "CY",
          "CZ",
          "DK",
          "EE",
          "FI",
          "FR",
          "GE",
          "DE",
          "GH",
          "GR",
        ];
        if (hideCountries.includes(select.value)) {
          hide();
        } else if (uncheckedCountries.includes(select.value)) {
          unchecked();
        } else if (precheckedCountries.includes(select.value)) {
          checked();
        }
      });
    }
    //Form language. This should change automatically by language version. Change between fr, de and en to see difference

    var submitText = "Submit";
    //var explicitText = translations['en']['Explicit_Opt_in_text']; //default explicitText value

    //Go through all the form label translations in the defined language
    for (var labelTranslation in translations[language]) {
      //Identify each element and change placeholder, but only try to replace a placeholder, if the field exists
      if ($("label[for='" + labelTranslation + "']").length) {
        $("label[for='" + labelTranslation + "']").text(
          translations[language][labelTranslation]
        );
      }
    }

    //Translate Checkbox value
    if (document.getElementsByName("Explicit_Opt_in__c").length) {
      var elements = document.getElementsByName("Explicit_Opt_in__c");
      var id = elements[0].getAttribute("id");
      $("label[for='" + id + "']").text(
        translations[language]["Explicit_Opt_in_text"]
      );
    }

    //Translate Submit Text
    submitText = translations[language]["Submit"];
    form.getFormElem().find("button.mktoButton").html(submitText);
  });

  // ]]>
})();
lianef
Level 2
  • We are switching to using global forms but need for them to be localized per program so we had thought this would be a helpful way to do so with the program token indicating the language for the program. We've added to <script>var language = "{{my.program_language}}"</script> to indicate the language choice.
  • I am trying to figure out how to get the picklist value translations into the code like we did with Submit button at the bottom.
  • Would you still recommend not using Javascript for this?

@SanfordWhiteman wasn't sure if I was supposed to tag you or not so I just did. thank you 🙂

Ricardo_Bardaro
Level 1

Thanks for those links. 

I got everything working except for one thing. Have you found a way to translate the Submit Button?

Thanks again for all the help. 

SanfordWhiteman
Level 10 - Community Moderator

For that you need to patch the core (top-level) parts of the form descriptor. I added demo code to the same CodePen.

Michelle_Stunka
Level 2

Thanks Sanford! I tried something similar but when I add in what you sent, it stops working altogether: https://www.m-files.com/en/marketo-test-form (code is hidden in the privacy policy text)

That's why I was getting completely stumped why it would work for one field but not multiple.

Michelle_Stunka
Level 2

Nevermind! I missed a curly bracket at the very end. Amazing how one character can make all the difference!

Thanks for your help!