I have a Django form in which I use the Jquery Validation Plugin to validate. My form needs to appear in multiple languages and I allow the user to change the form language on the click of a button (one button for each possible language). There is a separate script to load for each language to allow for built-in validation messages to show up in that language. For example, if I want default validation messages from this plugin to be in Russian, I would load the "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_ru.min.js"
script.
My questions are as follows:
Maybe there's some way to have a specific space in the header that is reserved for these scripts and I can just replace or remove what's in that space based on what button the user clicks?
The js code that I have so far in order for the proper script to be loaded based on a button click is this:
window.onload = function() {
document.getElementsByClassName('btn-outline-secondary').setAttribute('onclick', "ChangeValidationLanguage()");
};
function ChangeValidationLanguage(element) {
var head = document.getElementsByTagName('head')[0];
var js = document.createElement("script");
js.type = "text/javascript";
if (element.id === '#form_ru') {
js.src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_ru.min.js";
}
else if (element.id === '#form_fr'){
js.src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_fr.min.js";
}
else if (element.id === '#form_es'){
js.src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_es.min.js";
}
else if (element.id === '#form_he'){
js.src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_he.min.js";
}
// else{ //if (element.id === '#form_en')
// js.src = ""
// }
head.appendChild(js);
}
My buttons in html look like this:
<div class="language-buttons">
<form action="/i18n/setlang/" method="post" id="form_en" style="display:inline!important;">
<input type="hidden" name="csrfmiddlewaretoken" value="...">
<input name="next" type="hidden" value="" />
<input name="language" type="hidden" value="en" />
</form>
<a><button class="btn-outline-secondary" type="submit" form="form_en" value="Submit">English </button></a>
<form action="/i18n/setlang/" method="post" id="form_ru" style="display:inline!important;">
<input type="hidden" name="csrfmiddlewaretoken" value="...">
<input name="next" type="hidden" value="" />
<input name="language" type="hidden" value="ru" />
</form>
<a><button class="btn-outline-secondary" type="submit" form="form_ru" value="Submit">Русский </button></a>
<form action="/i18n/setlang/" method="post" id="form_fr" style="display:inline!important;">
<input type="hidden" name="csrfmiddlewaretoken" value="...">
<input name="next" type="hidden" value="" />
<input name="language" type="hidden" value="fr" />
</form>
<a><button class="btn-outline-secondary" type="submit" form="form_fr" value="Submit">français </button></a>
<form action="/i18n/setlang/" method="post" id="form_es" style="display:inline!important;">
<input type="hidden" name="csrfmiddlewaretoken" value="...">
<input name="next" type="hidden" value="" />
<input name="language" type="hidden" value="es" />
</form>
<a><button class="btn-outline-secondary" type="submit" form="form_es" value="Submit">español </button></a>
<form action="/i18n/setlang/" method="post" id="form_he" style="display:inline!important;">
<input type="hidden" name="csrfmiddlewaretoken" value="...">
<input name="next" type="hidden" value="" />
<input name="language" type="hidden" value="he" />
</form>
<a><button class="btn-outline-secondary" type="submit" form="form_he" value="Submit">עברית </button></a>
</div>
Thank you!
Ok. Instead of using Javascript(since Sparky above advised against it), I did the following:
Step 1: In my views.py I created a function to give return the proper language script based on a given language code:
def getLangScript(language_code='en'):
if language_code == 'ru':
lang_script = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_ru.min.js"
elif language_code == 'fr':
lang_script = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_fr.min.js"
elif language_code == 'es':
lang_script = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_es.min.js"
elif language_code == 'he':
lang_script = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_he.min.js"
else:
lang_script = ""
return lang_script
Step 2: I changed my views to accept a language code as a parameter, with English being the default in case no parameter is passed. I call my above function to get the proper script, and then pass that script in to the context so I have access to it in my template:
def post_list(request, language_code='en'):
.
.
.
lang_script = getLangScript(language_code)
return render(request, 'template.html', {'form': form, 'lang_script': lang_script})
Step 3: I changed my path in urls.py to accept a url parameter, which will be the language code (i.e. 'en' for English):
urlpatterns = [
.
.
.
path('test/<str:language_code>/', views.post_list, name='post_list'),
]
Step 4: In my template, I added <script src="{{ lang_script }}"></script>
where I wanted the script to be loaded that would cause my validations to appear in a different language (I have access to it from my context).
Step 5: (Here is the exciting part!) In the input element with the name "next", I passed in the url that I want it to redirect to WITH the language.code parameter. Based on this parameter that will be passed to the view, the view will call my getLangScript function, figure out which script to load, and then pass that script to the template as a context variable. See below.
<div class="language-buttons">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<form action="{% url 'set_language' %}" method="post" id="form_{{ language.code }}" style="display:inline!important;">
{% csrf_token %}
<input name="next" type="hidden" value="{% url 'post_list' language.code%}" />
<input name="language" type="hidden" value="{{ language.code }}" />
</form>
<a><button class="btn-outline-secondary" type="submit" form="form_{{ language.code }}" value="Submit">{{ language.name_local}} </button></a>
{% endfor %}
</div>
In this way, when the user clicks the button, the proper script will be loaded into the DOM and the validation messages from jquery language plugin will show up in the correct language!!
If anyone has further comments about whether this was a wise way to do this or if there are better ways, I would be interested.