06. Using ajax (jQuery) to change text in jsp. Language selector. Change event

0. Introduction

In this blog, it will be seen:

1. Create a "select" for selecting the language

2. Use an icon with the flag of the language

3. Use the change event to trigger a jQuery ajax call to the server

4. Create a js module to store javascript utilities


The structure of the project is:


The result is:




1. Create a "select" for selecting the language

Here is the code (to be inserted in the index.jsp)

<select id="myLanguage" onchange="changeLanguage()">
  <option value="es">Español></option>
  <option value="ca">Valencià</option>
  <option value="en">English</option>
  <option value="fr">Francaise</option>
  <option value="de">Deustch</option>
  <option value="it">Italiano</option>
  <option value="ro">Românesc</option>
</select>

Important: The value is the 2 letters of the language!

2. Use an icon with the flag of the language

Important, the name of the icon file is the 2 letters of the language (in this case "es")

<img id="myLangIcon" src="icons/flags/es.png">

3. Use the change event to trigger a jQuery ajax call to the server

Here is the javascript script used to intercept the "change event"

<script>
  $('#myLanguage').change(function() { 
    //1. Get value of select
    const myLanguageVar= $('#myLanguage').val();
			
    //2. Get icon file
    const iconVar= ''.concat('icons/flags/', myLanguageVar, '.png');
    $('#myLangIcon').attr("src",iconVar); //change icon
	    	  		
    //3. Get the element to change
    const myFieldArrayVar=['consulta_csv','instruccions','indica_csv','descarrega']
	  			
    //4. Change Elements by "js/i18n.js"
    label18nElements("main", myLanguageVar, myFieldArrayVar);
  });
</script>

 $('#myLanguage') is the reference to the element used by jquery.

Note the "change" envent

The icon file path is obtained concatenating the folder path ("icon/flags") and the 2 letters of the language, followed by the extension (".png")

The array of strings "myFieldArrayVar" is the array of the "ids" of the elements to change the value. (Note that the id of the elements is the same as the key of the resource bundle file)

The function label18nElements is used to call the server using an ajax post and applying the i18n values to the elements.

4. Create a js module to store javascript utilities

Here is the file "webapp/js/i18n.js"

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/**
 * i18n utils module
 */
 
/**
 * Assing the value "value" to the html element whose id is "idElement"
 */ 
function assignValue(idElement, value) {
	var elem = $("#" + idElement);
	if (elem.is("input")) {
		elem.val(value);
	} else if (elem.is("div")) {
		elem.html(value);
	} else if (elem.is("p")) {
		elem.html(value);
	} else if (elem.is("h1")) {
		elem.html(value);
	}
} 

/**
 *  Uses my bundle wih the locale to translate an array of keys and fills components
 *  bundle is the resource bundle to use
 *  locale is the locale to apply
 *  key is the key to get the bundle and must ber the same as the component id !!
 *  The servlet to call the POST is "langServlet" 
 */
function label18nElements(myBundle, myLocale, myKeyArr) {
	
	$.post('langServlet', { 
		bundle: myBundle,
		locale: myLocale,
		keyArr: myKeyArr,
		},function(responseText) {
			const myTranslatedFields=responseText.split(";");
			let rLen=myTranslatedFields.length;
			for (let i = 0; i < rLen; i++) {
				//alert (i);
				assignValue(myKeyArr[i],myTranslatedFields[i]);	
			}
	});
	
}

The function assignValue uses jquery to assign the value "value" to the element whose id is "idElement". This funtions changes the "value" attribute if the control is of type "input", or changes the attribute "innerHtlm" if the element is of type "div", "p" or "h1"

The function label18nElements needs the bundle name "myBundle", the locale to translates "myLocale" and the array of keys to translate "myKeyArr".

The servlet "langServlet" is called using post ajax, and returs a csv string (of the translated elements) whose delimiter is the semicolon ";"

Aloop is used to assign the received values to the elements

5. The index.jsp file

Here is the file:


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ page import = "java.io.*,java.util.Locale, java.util.ResourceBundle" %>        
<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
		<title>JSP-Bootstrap</title>

        <!-- jQuery -->
		<script src="http://code.jquery.com/jquery-latest.js"> </script>
		
		<!-- My library -->
		<script src="js/i18n.js"> </script>
		
		<!-- Bootstrap -->
		<meta name="viewport" content="width=device-width, initial-scale=1">
  		<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
  		<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
		
		
		
		<!-- <fmt:setBundle basename="messages"/> -->
	</head>

	<body>
    	<% 
    		Locale locale = request.getLocale();
    		ResourceBundle bundle = ResourceBundle.getBundle("i18n/main", locale);
    	%>
    	<!-- <div class="container-fluid p-5 bg-primary text-white text-center"> -->
    	<div class="container p-1 my-1">
    	
        	<!-- 
        	<h1>My First Bootstrap Page</h1>
        	<p>Resize this responsive page to see the effect!</p>
        	-->
        	<img id="logo" src="imgs/logotipo-tavernes-valldigna-01.jpg" width="80%" >
     	</div>
    	
    	<div class="container p-1 my-1 text-primary">
    		<p class="display-4" id="consulta_csv"><%=bundle.getString("consulta_csv") %></p>
    	</div>
    	
    	<div class="container p-1 my-1 h5 ">
    		<select id="myLanguage" onchange="changeLanguage()">
				<option value="es">Español></option>
    			<option value="ca">Valencià</option>
    			<option value="en">English</option>
    			<option value="fr">Francaise</option>
    			<option value="de">Deustch</option>
    			<option value="it">Italiano</option>
    			<option value="ro">Românesc</option>
			</select>
			
			<img id="myLangIcon" src="icons/flags/es.png">
			
		</div>	
    
		
    	
    	
    	
    	    	
    	<form action="dowloadServlet" method="post">
    		<div class="container p-1 my-1 mt-5 h6">
    			<div id="indica_csv" class="fw-light"><%=bundle.getString("indica_csv") %></div> 
    		</div>
    		
    		<div class="container p-1 my-1 h6 mt-3 ">
    			<input type="text" name="yourName" size="35"/>
    			<!-- <input id="descarrega" type="submit" value="Call Servlet" /> -->
    			<input id="descarrega" type="submit" value=<%=bundle.getString("descarrega") %> />
    		</div>	
   		</form>
    	
    	<div class="alert alert-success text-center mt-5" >
  			<p id="instruccions"><%=bundle.getString("instruccions") %></p>
		</div>
    	
    	<script>
    		$('#myLanguage').change(function() { //$('select').change(function() {
		
				//1. Get value of select
				const myLanguageVar= $('#myLanguage').val();
			
				//2. Get icon file
				const iconVar= ''.concat('icons/flags/', myLanguageVar, '.png');
	  			$('#myLangIcon').attr("src",iconVar); //change icon
	  		
	  			//3. Change text of div
	  			//$('#instruccions').html('Enter your name again:');
	  		
	  			//4. Get the element to change
	  			const myFieldArrayVar=['consulta_csv','instruccions','indica_csv','descarrega']
	  			
	  			//5. Change Elements by "js/i18n.js"
	  			label18nElements("main", myLanguageVar, myFieldArrayVar);
	 		});
		</script>

	</body>
</html>


6. The servlet file

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package ximojsp;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Locale;
import java.util.ResourceBundle;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class LangSerlet
 */
@WebServlet("/langServlet")
public class LangServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public LangServlet() {
		super();
		System.out.println("Creationg Servlet");

		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
	              throws ServletException, IOException {
//1. Get Locale String myLanguage = request.getParameter("locale"); Locale locale = new Locale(myLanguage); //2. Get Resource bundle String myBundle = request.getParameter("bundle").trim(); ResourceBundle bundle = ResourceBundle.getBundle("i18n/"+myBundle, locale); //3 Translate array String[] myFieldArray = request.getParameterValues("keyArr[]"); String[] translated=new String[myFieldArray.length]; for(int i=0; i<myFieldArray.length; i++) translated[i]=bundle.getString(myFieldArray[i]); //4. Test System.out.println("================================================"); System.out.println(myLanguage); for(int i=0; i<myFieldArray.length; i++) System.out.println(myFieldArray[i] +"-->"+translated[i]); System.out.println("================================================"); //4 Define response response.setContentType( "text/html; charset=UTF-8" ); PrintWriter out = response.getWriter(); //out.write(Arrays.toString(translated)); out.write(String.join(";",translated)); } //Stack overflow solution //@see https://stackoverflow.com/a/33056026 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }


7. The resource bundle main_es.properties


1
2
3
4
5
6
7
8
9
consulta_csv = Consult document by CVS

descarrega = Download the document

icon = icons/flags/en.png

indica_csv = Type the document's VSC (Verification Safe Code)

instruccions = Use Mozilla Firefox if smart card certificate is needed





Comentarios

Entradas populares de este blog

15 Typescript (3) json ..

10. Some Javascript & JQuery concepts

14 Typescript (2) with jquery, bootstrap and other module stuff