Text translation algorithm

Asked

Viewed 3,473 times

3

I’m a beginner in JS I’ve studied up to the part of loops, then I stopped to review everything I saw and do some exercises.

I made an algorithm that translates to English, Spanish and Portuguese a table with tidal times.

The algorithm reads a model function with parameters > below there is another function that will be called in the event onclick, this function calls the model function by changing the parameters according to the current language

The problem is that it became very extensive, so I only did up to the part that translates the Title, Button and Prompt to choose the language... come on:

JAVASCRIPT

//funcao modelo
function traducao(langarray1,langarray2,lang1,lang2,tabletitle1,tabletitle2,buttonvalue1,buttonvalue2,chooselang,errormsg){
        document.getElementById("tabelatitle"); //pega a tag <h1> do titulo da tabela

        translan = new Array(langarray1,langarray2); // variaveis do idioma que aparece no texto do prompt como string  
        transtext = prompt(chooselang + translan[0] + ", " + translan[1]); // Prompt para escolher o idioma

        if(transtext == lang1){ // escolha do idioma == idioma 1
            tabelatitle.innerHTML = tabletitle1; // traduzir o <h1> para idioma escolhido
            document.getElementById("botao").innerHTML = buttonvalue1; // traduzir o botao para o idioma escolhido

        }
        else if(transtext == lang2){ // se escolha do idioma == idioma 2
            tabelatitle.innerHTML = tabletitle2; // traduzir <h1> para idioma escolhido
            document.getElementById("botao").innerHTML = buttonvalue2; // traduzir o botao para o idioma escolhido
        }
        else{ // se deixar vazio ou escolha invalida, apresentar msg de erro
            alert(errormsg);
        }
    }

//executar traducao() com condicoes
function traduzir(){    
        document.getElementById("tabelatitle");

        //pt - se idioma current = pt > apresentar opções de traduzir para ingles ou espanhol no prompt. e se escolher uma das duas > traduz titulo, botão e texto do prompt.
        if(tabelatitle.innerHTML == "Tabela de horários da Maré"){ //
            return traducao("Ingles","Espanhol","Ingles","Espanhol","Sea hours table","Tabla de horarios de las mareas","Translate","Traducir","Escolha um idioma: ","Você precisa escolher um idioma");
        }

        //en - se o idioma current for ingles - apresentar opções de traduzir para Portugues e Espanhol > e se escolher uma das duas > traduz titulo, botão e texto do prompt.
        else if(tabelatitle.innerHTML == "The tide times table"){
            return traducao("Spanish","Portuguese","Spanish","Portuguese","Tabla de horarios de las mareas","Tabela de horários da Maré","Traducir","Traduzir", "Choose a language: ","You need to choose a language");

        //es - se o idioma current for espanhol - apresentar opções de traduzir para Portugues e Ingles > e se escolher uma das duas > traduz titulo, botão e texto do prompt.
        }
        else{
            return traducao("Inglés","Portugués","Inglés","Portugués","The tide times table","Tabela de horários da Maré","Translate","Traduzir", "Eligir un idioma","Usted tiene que elegir un idioma");
        }
    }

Table HTML (if you want to test)

 <h1 id="tabelatitle">Tabela de horários da Maré</h1>
           <table class="tg">
              <tr>
                <th class="tg-xdyu">Dia</th>
                <th class="tg-031e">Manhã</th>
                <th class="tg-031e">Tarde</th>
                <th class="tg-031e">Noite</th>
              </tr>
              <tr>
                <td class="tg-031e" id="segunda">Segunda-Feira</td>
                <td class="tg-031e">Calmo</td>
                <td class="tg-031e">Agitado</td>
                <td class="tg-031e">Agitado</td>
              </tr>
              <tr>
                <td class="tg-031e">Terça-Feira</td>
                <td class="tg-031e">Normal</td>
                <td class="tg-031e">Calmo</td>
                <td class="tg-031e">Normal</td>
              </tr>
              <tr>
                <td class="tg-031e">Quarta-Feira</td>
                <td class="tg-031e">Agitado</td>
                <td class="tg-031e">Agitado</td>
                <td class="tg-031e">Agitado</td>
              </tr>
              <tr>
                <td class="tg-031e">Quinta-Feira</td>
                <td class="tg-031e">Calmo</td>
                <td class="tg-031e">Normal</td>
                <td class="tg-031e">Agitado</td>
              </tr>
              <tr>
                <td class="tg-031e">Sexta-Feira</td>
                <td class="tg-031e">Normal</td>
                <td class="tg-031e">Normal</td>
                <td class="tg-031e">Normal</td>
              </tr>
              <tr>
                <td class="tg-031e">Sábado</td>
                <td class="tg-031e">Calmo</td>
                <td class="tg-031e">Normal</td>
                <td class="tg-031e">Agitado</td>
              </tr>
              <tr>
                <td class="tg-031e">Domingo</td>
                <td class="tg-031e">Calmo</td>
                <td class="tg-031e">Calmo</td>
                <td class="tg-031e">Calmo</td>
              </tr>
            </table>
            <button onclick="traduzir()" id="botao">Traduzir</button>

The table needs to be translated in full after the user performs the function.

Since I was only able to do this by assigning ID and condition to EACH word of the table and thus the algorithm becomes tiresome, extensive and unprofessional, let’s see:

   if(transtext == lang1){ // escolha do idioma == idioma 1
            tabelatitle.innerHTML = tabletitle1; // traduzir o <h1> para idioma   escolhido
            document.getElementById("botao").innerHTML = buttonvalue1; // traduzir o botao para o idioma escolhido

            if(document.getElementById("segunda").innerHTML = parametroadequadoaoidiomaemquestao;
            if(document.getElementById("terca").innerHTML = parametroadequadoaoidiomaemquestao;
            etc..... (todas as palavras, incluindo, dias da semana, tempo do mar, tarde   noite etc

   else if(transtext == lang1){ // escolha do idioma == idioma 1
            tabelatitle.innerHTML = tabletitle1; // traduzir o <h1> para idioma   escolhido
            document.getElementById("botao").innerHTML = buttonvalue1; // traduzir o botao para o idioma escolhido

            if(document.getElementById("segunda").innerHTML = parametroadequadoaoidiomaemquestao;
            if(document.getElementById("terca").innerHTML = parametroadequadoaoidiomaemquestao;
            etc..... (todas as palavras, incluindo, dias da semana, tempo do mar, tarde   noite etc

I tried to use GetElementByTagsName to condition all words in the table <th> to respect the condition of moving innerHTML without having to assign id to each, but it didn’t work.

You could do it using loops or something else?

1 answer

6

Before answering your main question (which is related to DOM manipulation), I would like to give you some general ideas for refactoring your code, so that it is easier to manage. OK?

First of all, I suggest using a standardized object with all the texts of each language, because this way it is quite confusing (many parameters for function, repeated texts, etc):

var idiomas = {
    pt:{
        pt:"Português", en:"Inglês", es:"Espanhol", alt:["en","es"],
        titulo:"Tabela de horários da Maré",
        traduzir:"Traduzir",
        escolha:"Escolha um idioma: ", escolhaErro:"Você precisa escolher um idioma",
        cabecalhos:["Dia", "Manhã", "Tarde", "Noite"],
        diasSemana:["Segunda-Feira","Terça-Feira","Quarta-Feira","Quinta-Feira",
                    "Sexta-Feira","Sábado","Domingo"],
        calmo:"Calmo", normal:"Normal", agitado:"Agitado"
    },
    en:{
        pt:"Portuguese", en:"English", es:"Spanish", alt:["es","pt"],
        ...
    es:{
        pt:"Portugués", en:"Inglés", es:"Español", alt:["en","pt"],
        ...
};

This way, the supported language set is not "carved in stone", and even simplifies the rest of the program. The function traduzir for example, it would look like this:

function traduzir() {
    var tabelatitle = document.getElementById("tabelatitle"); // Não é bom acessar 
                                                              // implicitamente pelo id
    for ( var idioma in idiomas )
        if ( idiomas.hasOwnProperty(idioma) )
            if ( tabelatitle.innerHTML == idiomas[idioma].titulo ) {
                // Só precisa informar qual o idioma atual e quais as alternativas
                traducao(idiomas[idioma], idiomas[idioma].alt);
                break;
            }
}

And the function traducao can extract all necessary parts of that past list. Example (still assuming only two alternatives, in practice you will want to iterate over the parameter alternativas):

function traducao(atual, alternativas) {
    var langarray1 = atual[alternativas[0]], langarray2 = atual[alternativas[1]], 
        lang1 = atual[alternativas[0]], lang2 = atual[alternativas[1]],
        tabletitle1 = idiomas[alternativas[0]].titulo, tabletitle2 = idiomas[alternativas[1]].titulo,
        buttonvalue1 = idiomas[alternativas[0]].traduzir, buttonvalue2 = idiomas[alternativas[0]].traduzir,
        chooselang = atual.escolha, errormsg = atual.escolhaErro;
    ...

Example in jsFiddle. Done this, it becomes easier to replace your chain ifs by a loop:

var translan = [];
for ( var i = 0 ; i < alternativas.length ; i++ )
    translan[i] = atual[alternativas[i]];
var transtext = prompt(chooselang + translan.join(", "));

var idiomaEscolhido = null;
for ( var i = 0 ; i < alternativas.length ; i++ ) {
    if ( transtext == atual[alternativas[i]] ) {
        idiomaEscolhido = idiomas[alternativas[i]];

        tabelatitle.innerHTML = idiomaEscolhido.titulo;
        document.getElementById("botao").innerHTML = idiomaEscolhido.traduzir;

        break;
    }
}
if ( idiomaEscolhido === null )
    alert(errormsg);

Updated example. Note that your code has been reduced to only about 30 lines! :)

(P.S. At all times use var before the variables, otherwise they will turn global...)

Finally, to the center of the question: how to iterate over the rows and columns of the table using a loop. There is a fairly easy medium - using document.querySelector and document.querySelectorAll - that is widely supported in current browsers. With it you can easily select the first column of each row of your table (unfortunately there is no support for :eq, so that the way will be to select only the same lines):

var linhas = document.querySelectorAll("table.tg tr");

Assuming that the first column of each row [except the first] is a day of the week, and your language file has the days of the week in an array, it’s easy to translate them one by one:

for ( var i = 1 ; i < linhas.length ; i++ )
    linhas[i].getElementsByTagName("td")[0].innerHTML = idiomaEscolhido.diasSemana[i-1];

Final example. Just missed translating most of the fields (translated some of the English, for demonstration, but left most without translating, in particular from Spanish - which I do not know) and do the rest of the translations - header line, and other table fields. I believe that with the example given you can use both the querySelectorAll as to the getElementsByTagName to do the rest, but if you still have doubts just ask.

  • 3

    Whoever you are, I can’t thank you enough, old man. You explained a lot and reworked it in ways that I haven’t even studied yet, I still don’t understand more than 40% but it looks fantastic. I will continue to reread your answer until I understand everything. Thank you very much!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.