Translations

Documentation of Form.io Translations

Introduction

The Form.io Platform uses the i18Next system as the mechanism for performing all of the translations within the JavaScript Renderer and Builder. We recommend reading up on that documentation to understand all of the mechanisms that are available to perform translations within your application and forms rendered by Form.io. The Form.io Renderer exposes the i18next platform within the i18next variable within the renderer, and all options for this library can be introduced through the i18n configuration variable. For example, the following illustrates how the i18next framework can be initialized and accessed within the Form.io renderer.

Formio.createForm(document.getElementById('formio'), 'https://examples.form.io/example', {
    i18n: {...} // These options are passed to the i18Next framework
}).then((form) => {
    console.log(form.i18next); // Exposes the i18Next framework instance.
    
    form.language = 'es'; // Changes the language of the i18Next framework.
});

Once you have these, the documentation for the i18Next framework applies. The following provides some examples of how you can render a form with internationalization.

Rendering Translations

In order to provide translations to the renderer, you can introduce these translations using the i18n configurations. There are also a few methods within the Form.io Renderer that can be used to change the language dynamically. For example, you can provide the following HTML code to introduce some buttons within your application that will trigger a language change like so.

<link rel="stylesheet" href="https://cdn.form.io/formiojs/formio.full.min.css">
<script src="https://cdn.form.io/formiojs/formio.full.min.js"></script>
<div class="btn-group">
  <button type="button" class="btn btn-primary" onclick="setLanguage('sp')">Español</button>
  <button type="button" class="btn btn-primary" onclick="setLanguage('en')">English</button>
  <button type="button" class="btn btn-primary" onclick="setLanguage('ch')">中文</button>
</div>
<div id="formio"></div>

Once you do this, you can then provide the following code to define the form, provide the translations, and then dynamically change those translations when the buttons have been clicked. The code will look as follows.

Formio.createForm(document.getElementById('formio'), {
  components: [
    {
      type: 'textfield',
      key: 'firstName',
      label: 'First Name',
      placeholder: 'Enter your first name',
      input: true
    },
    {
      type: 'textfield',
      key: 'lastName',
      label: 'Last Name',
      placeholder: 'Enter your last name',
      input: true
    },
    {
      type: 'survey',
      key: 'questions',
      label: 'Survey',
      values: [
        {
          label: 'Great',
          value: 'great'
        },
        {
          label: 'Good',
          value: 'good'
        },
        {
          label: 'Poor',
          value: 'poor'
        }
      ],
      questions: [
        {
          label: 'How would you rate the Form.io platform?',
          value: 'howWouldYouRateTheFormIoPlatform'
        },
        {
          label: 'How was Customer Support?',
          value: 'howWasCustomerSupport'
        },
        {
          label: 'Overall Experience?',
          value: 'overallExperience'
        }
      ]
    },
    {
      type: 'button',
      action: 'submit',
      label: 'Submit',
      theme: 'primary'
    }
  ]
}, {
  language: 'sp',
  i18n: {
    sp: {
      'First Name': 'Nombre de pila',
      'Last Name': 'Apellido',
      'Enter your first name': 'Ponga su primer nombre',
      'Enter your last name': 'Introduce tu apellido',
      'How would you rate the Form.io platform?': '¿Cómo calificaría la plataforma Form.io?',
      'How was Customer Support?': '¿Cómo fue el servicio de atención al cliente?',
      'Overall Experience?': '¿Experiencia general?',
      Survey: 'Encuesta',
      Excellent: 'Excelente',
      Great: 'Estupendo',
      Good: 'Bueno',
      Average: 'Promedio',
      Poor: 'Pobre',
      'Submit': 'Enviar',
      complete: 'Presentación Completa',
    },
    ch: {
      'First Name': '名字',
      'Last Name': '姓',
      'Enter your first name': '输入你的名字',
      'Enter your last name': '输入你的姓氏',
      'How would you rate the Form.io platform?': '你如何评价Form.io平台?',
      'How was Customer Support?': '客户支持如何?',
      'Overall Experience?': '总体体验?',
       Survey: '调查',
      Excellent: '优秀',
      Great: '大',
      Good: '好',
      Average: '平均',
      Poor: '错',
      'Submit': '提交',
      complete: '提交完成',
    }
  }
}).then(function(form) {
  window.setLanguage = function(lang) {
    form.language = lang;
  };
});

This code within a JSFiddle will work as follows.

Dynamic Translations using Resources

While the example above is very helpful, the only caveat is that it is not dynamic and requires an application change in order to introduce new translations. What would be better is if we can make the translations dynamic using Form.io Resources so that any non-developer can contribute to the translation process. This can be achieved using the following method.

Create a Language Resource

The first step is to create a Language resource within your Project, called Language. Within this resource, we will add the following fields.

  • A Select Field for the Language Code. For the DataSource, use "Values" and provide the language as the Label, and the lang-code as the value like the following illustrates.

  • A DataMap component, which contains a Translation TextField like the following illustrates.

This resource will look like the following.

Now press Create Resource button to create the new Resource.

Once this is created, you will then create a new submission for each translation like the following illustrates for Español.

Create the submission to add the "language". This is what will be used to manage all of the translations so you can now input the rest of your language translations the same way until you have multiple to choose from.

Language Resource "Read All Submissions" Access

For most applications, the end user will be authenticated when they are switching between languages, but in some cases, the user will be anonymous. As with any resource, you will now need to ensure that the proper Role has access to the Read All Submissions permission within the Access section of the Language form.

Dynamic Language Controller

Now that we have our language resource form, and have established the correct access, we can now write the logic that will perform the dynamic language translations. The form controller that establishes a dynamic language is pretty simple. We just need to send an API call to the form resource submission API (where we should have "read all" submission access) to fetch the submission that is associated with the language that was chosen. We also should implement some in-memory cache so that we do not need to re-fetch the submissions as the user clicks between different languages. We will just need to put most of the logic within the window.setLanguage method used above. Here is what our Form Controller will look like.

var languages = {en: true};
window.setLanguage = function(lang) {
  // If we already have loaded the language, then just set it with the sdk.
  if (languages[lang]) {
  	return form.language = lang;
  }
  
  // Fetch the language from the Resource.
  Formio.fetch('https://formiodata.form.io/language/submission?data.language=' + lang).then(function(resp) {
	  return resp.json();
  }).then(function(result) {
    // Ensure future sets will use the cached language.
  	languages[lang] = true;
  
    // Add this language.
    form.addLanguage(lang, result[0].data.translations);
    
    // Set this language.
    form.language = lang;
  });
};

Here is a JSFiddle demonstrating this dynamic loading system working.

Last updated