[JAVA EE] Liste Déroulantes Liées Servlet

Killkala 6 Messages postés lundi 2 octobre 2017Date d'inscription 18 octobre 2017 Dernière intervention - 2 oct. 2017 à 10:27 - Dernière réponse : KX 15089 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 14 décembre 2017 Dernière intervention
- 18 oct. 2017 à 19:20
Bonjour à tous !
Je sais que de nombreux sujet traite déjà de ma question, mais beaucoup sont en php et en java je ne trouve pas ma réponse.

J'ai déjà une partie de code construit. Et je pense que le problème vient de ma servlet car lorsque je rentre idSelect = (long) 1, il me ressort bien la zone 1 de ma liste. Mais du coup j'ai pas vraiment d'idée !
Je vous montre mon code : (j'ai enlever des grosses partie de mon code qui ne sont pas utile dans mon problème donc ne soyez pas étonné de certaines choses! Cela rend la lecture plus simple)

stationForm.jsp

<%@ page pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
	<head>
		<c:import url="/WEB-INF/includePart/header.jsp">
    		<c:param name="title" value="Nouvelle Station"></c:param>
    	</c:import>
	</head>
	<body>
	  	<div class="menuPerso">
    		<c:import url="/WEB-INF/includePart/menu.jsp"></c:import>
    	</div>
		 <form class="form-signin" method="post" action="<c:url value="/station" />">
        
                <h2 class="form-signin-heading">Nouvelle Station</h2>

				<label for="chantier" class="sr-only">Nom du Chantier</label>
                <select class="form-control" id="chantier_id" name="chantier_id" onchange = "listZone();" required autofocus >
                	<option id="chantier_id" value="">Chantier</option>
                	<c:forEach items="${arrayChantier}" var="chantier">
                		<option value="${chantier['chantier_id']}, ${chantier['chantier_name']}">${chantier['chantier_name']}</option>
					</c:forEach>
				</select>
				
				<span class="error">${form.errors['chantier_name']}</span>
				<br><br>
				
				<label for="zone" class="sr-only">Nom de la Zone</label>
           		<select class="form-control" id="zone_id" name="zone_id" required autofocus>
           		<option  id="zone_id" value="" >Zone</option>
            		<c:forEach items="${arrayZone}" var="zone">
                		<option value="${zone['zone_id']}">${zone['zone_name']}</option>
					</c:forEach>
				</select>			
				<span class="error">${form.errors['zone_name']}</span>
				<br><br>
                
                <p class="${empty form.errors ? 'succes' : 'error'}">${form.resultat}</p>
        </form>
        
	<script src="<c:url value="/JS/dynamicListForm.js" />"></script>
	</body>
</html>


dynamicListForm.js
function getXhr()
{
	 var xhr = null;
     
	 if(window.XMLHttpRequest) {
		 xhr = new XMLHttpRequest();
	 }
     else if(window.ActiveXObject) { 
    	 try {
    		 xhr = new ActiveXObject("Msxml2.XMLHTTP");
         } catch (e) {
         xhr = new ActiveXObject("Microsoft.XMLHTTP");
         }
     }
     else {
    	 alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest");
         xhr = false;
     }
     return xhr;
}
  

function listZone()
{
	var xhr = getXhr();

	xhr.onreadystatechange = function() {	
		if(xhr.readyState == 4){
			if (xhr.status == 200 || xhr.status == 0) {
				select = xhr.responseText;
		        document.getElementById('zone_id').innerHTML = select;
		    }
			else {
				alert('Erreur :' +xhr.status + ' '+xhr.statusText);
			}
		}
	};
	
	xhr.open("GET","/Auscultation/station",true);
	xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
	chantierSelect = document.getElementById('chantier_id');
	idParent = chantierSelect.options[chantierSelect.selectedIndex].value;	
	xhr.send(null);
}


AddStationServlet.java
package com.auscult.servlets;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.auscult.beans.Chantier;
import com.auscult.beans.Zone;
import com.auscult.forms.StationForm;
import com.auscult.forms.ZoneForm;
import com.auscult.dao.DaoChantier;
import com.auscult.dao.DaoUser;
import com.auscult.dao.DaoStation;
import com.auscult.dao.DAOFactory;
import com.auscult.dao.DaoZone;
import com.google.gson.Gson;

public class AddStationServlet extends HttpServlet {
	
	private static final long serialVersionUID = 1L;
	
	public static final String ATT_USER 		 = "user";
    public static final String ATT_FORM 		 = "form";
    public static final String CONF_DAO_FACTORY  = "daofactory";
    public static final String ATT_SESSION_USER  = "userSession";
    public static final String COOKIE_CONNECTION = "cookieConnection";
    
   
    public static final String VUE         = "/WEB-INF/admin/create/stationForm.jsp";
    public static final String HOME		   = "/station";
    
    public String chemin;
    public String station_dir;
    
    public String host;
	public String username;
	public String password;
	
	public String[] FTPtab  = new String [5];
	
    private DaoUser			daoUser;
    private DaoStation      daoStation;
    private DaoZone			daoZone;
    private DaoChantier		daoChantier;
    
    public void init() throws ServletException { 
    	
        this.daoStation = ( (DAOFactory) getServletContext().getAttribute( CONF_DAO_FACTORY ) ).getStationDao();
        this.daoChantier = ( (DAOFactory) getServletContext().getAttribute( CONF_DAO_FACTORY ) ).getChantierDao();
        this.daoZone = ( (DAOFactory) getServletContext().getAttribute( CONF_DAO_FACTORY ) ).getZoneDao();
        this.daoUser = ( (DAOFactory) getServletContext().getAttribute( CONF_DAO_FACTORY ) ).getUserDao();
    }
	
    public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException{
    	HttpSession session = request.getSession();
    	
    	Long idSelect = null;
    	if (request.getParameter("select")!= null){
			idSelect = Long.parseLong(request.getParameter( "select" ));
		}
    	
    	ArrayList<Chantier> arrayChantier = daoChantier.findAllChantier();
    	ArrayList<Zone> arrayZone = daoZone.findByChantier(idSelect);    	  	
		
		request.setAttribute("arrayChantier", arrayChantier);
		request.setAttribute("arrayZone", arrayZone);
    	
    	
        if ( session.getAttribute( ATT_SESSION_USER ) == null && getCookieValue(request, COOKIE_CONNECTION) == null) {
            response.sendRedirect( request.getContextPath() + HOME );
        } else {
        	if(session.getAttribute( ATT_SESSION_USER ) == null)
        	{
        		session.setAttribute(ATT_SESSION_USER, daoUser.find(Long.parseLong(getCookieValue(request, COOKIE_CONNECTION))));
        	}
        	
            this.getServletContext().getRequestDispatcher( VUE ).forward( request, response );
            
        }
      }
    
    
    private static String getCookieValue( HttpServletRequest request, String nom ) {
        Cookie[] cookies = request.getCookies();
        if ( cookies != null ) {
            for ( Cookie cookie : cookies ) {
                if ( cookie != null && nom.equals( cookie.getName() ) ) {
                    return cookie.getValue();
                }
            }
        }
        return null;
    }
  
}


DaoImplZone.java (si ca peut etre utile!)
package com.auscult.dao;

import java.sql.*;
import java.util.ArrayList;

import com.auscult.beans.Station;
import com.auscult.beans.Zone;

import static com.auscult.dao.DaoTools.*;

public class DaoImplZone implements DaoZone{
	private static final String SQL_SELECT_WHERE_CHANTIER_ID ="SELECT zone_id, zone_name, x1, y1, x2, y2, x3, y3, chantier_name, last_name "
																+ "FROM zone "
																+ "INNER JOIN chantier ON zone.FK_chantier_id = chantier.chantier_id "
																+ "INNER JOIN user ON chantier.FK_user_id = user.user_id WHERE chantier_id = ?";
	
	
	
	private DAOFactory          daoFactory;

    DaoImplZone( DAOFactory daoFactory ) {
        this.daoFactory = daoFactory;
    }
    
    
    @Override
    public ArrayList<Zone> findByChantier ( Long chantier_id ) throws DAOException {
    	System.out.println("verifie DaoImplZone findChantier");
    	Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        ArrayList<Zone> listZone = new ArrayList<Zone>();

        try {
           
            connexion = daoFactory.getConnection();
            preparedStatement = initPreparedRequest( connexion, SQL_SELECT_WHERE_CHANTIER_ID, false, chantier_id );
            resultSet = preparedStatement.executeQuery();
            while ( resultSet.next() ) {
            	listZone.add(map(resultSet));
            }
        } catch ( SQLException e ) {
        	System.out.println("error sql exception = " + e.getMessage());
            throw new DAOException( e );
        } finally {
            silentClose( resultSet, preparedStatement, connexion );
        }
        
        System.out.println("size"+listZone.size());
        return listZone;

    }
  
}



Lorsque je select un élément de ma liste, il ne retourne rien dans ma deuxieme list (à vrai dire je me suis inspiré de ce forum https://www.developpez.net/forums/d1371530/java/developpement-web-java/servlets-jsp/listes-deroulantes-liees/ surtout pour la servlet ^^)

Je vous remercie d'avance
Ca fait vraiment un moment que je suis bloqué et je manque de connaissance pour trouvé, so .. HELP MEEE, PLEASE !! ^^
(désolé pour les fautes d'orthographes, on me le reproche souvent!)
Afficher la suite 

11 réponses

Répondre au sujet
KX 15089 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 14 décembre 2017 Dernière intervention - 2 oct. 2017 à 18:17
0
Utile
Bonjour,

Je n'ai pas tout regardé, mais dans le JavaScript tu as :

xhr.open("GET","/Auscultation/station",true);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
chantierSelect = document.getElementById('chantier_id');
idParent = chantierSelect.options[chantierSelect.selectedIndex].value;	
xhr.send(null);

Comment se fait-il que tu ne te serves pas de idParent ?
C'est pourtant ça qui devrait permettre d'appeler le deuxième select...

Dans le code source de la page dont tu t'es inspiré tu avais :
sel = document.getElementById(parentSelect);
idParent = sel.options[sel.selectedIndex].value;
xhr.open("GET","/GTP/tache?action=ajouter&remplir="+enfantSelect+"&select="+idParent,true);
xhr.send(null);

Il y avait donc bien dans le GET une référence à l'idParent pour que le serveur s'y retrouve...
Commenter la réponse de KX
Killkala 6 Messages postés lundi 2 octobre 2017Date d'inscription 18 octobre 2017 Dernière intervention - 3 oct. 2017 à 09:50
0
Utile
8
Bonjour KX,

En effet, tes indications m'ont aidé cela a résolu le problème (il y avait aussi un autre soucis mais que j'ai pu résoudre rapidement)

Cela marche beaucoup mieux même si lent je trouve, peut-être une histoire de cache.
J'ai juste une dernière question, dans ma deuxième liste, ma première liste se réaffiche en plus. Une idée ?
C'est à dire :
Liste 2 -> Elements Liste1 + Elements Liste2
Je voudrai pouvoir enlever les éléments de la liste 1.

Voici le code modifié de ma JSP et mon JS

JSP
				
<label for="chantier" class="sr-only">Nom du Chantier</label>
                <select class="form-control" id="chantier_id" name="chantier_id" onchange = "listZone('chantier_id','zone_id')" required autofocus >
                	<option id="chantier_id" value="">Chantier</option>
                	<c:forEach items="${arrayChantier}" var="chantier">
                		<option value="${chantier['chantier_id']}">${chantier['chantier_name']}</option>
					</c:forEach> 
				</select>
				
				<span class="error">${form.errors['chantier_name']}</span>
				<br><br>
				
				<label for="zone" class="sr-only">Nom de la Zone</label>
           		<select class="form-control" id="zone_id" name="zone_id" required autofocus>
           		<option  id="zone_id" value="" >Zone</option>
           		<c:forEach items="${arrayZone}" var="zone">
                		<option value="${zone['zone_id']}">${zone['zone_name']}</option>
				</c:forEach>
				</select>			
				<span class="error">${form.errors['zone_name']}</span>
				<br><br>


JS
function listZone(parentSelect, childSelect)
{
	var xhr = getXhr();

	xhr.onreadystatechange = function() {	
		if(xhr.readyState == 4){
			if (xhr.status == 200 || xhr.status == 0) {
				select = xhr.responseText;
		        document.getElementById(childSelect).innerHTML = select;
		    }
			else {
				alert('Erreur :' +xhr.status + ' '+xhr.statusText);
			}
		}
	};
	
	chantierSelect = document.getElementById(parentSelect);
	idParent = chantierSelect.options[chantierSelect.selectedIndex].value;	
	xhr.open("GET","/Auscultation/station?action=ajouter&listZone="+childSelect+"&select="+idParent,true);
	xhr.send(null);
}


Merci d'avance
Killkala 6 Messages postés lundi 2 octobre 2017Date d'inscription 18 octobre 2017 Dernière intervention > KX 15089 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 14 décembre 2017 Dernière intervention - 12 oct. 2017 à 12:16
Bonjour KX,

Merci pour ton aide encore une fois! J'avoue avoir fait une petite pause sur ce problème qui me prenais beaucoup la tête, mais maintenant je n'ai plus le choix de le résoudre !

Alors côté Java je pense que tout se passe bien, il récupère bien la liste de Zones qui dépend de Chantier. J'ai appliqué tes conseils pour la servlet.

En faite la le problème c'est plutôt côté Ajax (j'avoue que c'est l'une des première fois que j'en fais et ce n'est pas simple!)
Dans mon fichier .JS, j'applique donc ce que tu m'as dis de cette façon :
if (xhr.status == 200 || xhr.status == 0) {	
				zones = eval(xhr.responseText); 
				console.log(zones);
		    }

Et dans ma console (sans parler de ma JSP dans un premier temps mais ca m'a donné le même résultat), ça m'affiche ça :
["com.auscult.beans.Zone@3055971a"]
Je ne comprend pas du tout ce résultat, surtout que les chiffres/lettres après l'@ changent à chaque fois
Moi je voudrai afficher l'Id (ou le nom peut importe ça reviens au même).
J'ai essayé "zones.zone_id" mais là il m'affiche "undefined"

J'espère que tu pourras m'aider !
Merci en tout cas :)
KX 15089 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 14 décembre 2017 Dernière intervention > Killkala 6 Messages postés lundi 2 octobre 2017Date d'inscription 18 octobre 2017 Dernière intervention - 12 oct. 2017 à 13:11
Sur le stream j'ai fait un
map(Zone::toString)
donc on appelle la méthode
toString()
sur les objets Zone.
Si tu obtiens
com.auscult.beans.Zone@3055971a
c'est parce que tu n'as pas redéfini la méthode toString dans ta classe, donc tu hérites le comportement par défaut de la classe Object.
Alors soit tu redéfinis la méthode toString pour ta classe Zone, soit tu changes le mapping pour appeler une autre méthode, par exemple si tu as une méthode
String getName()
tu peux faire
map(Zone::getName)
.
Killkala 6 Messages postés lundi 2 octobre 2017Date d'inscription 18 octobre 2017 Dernière intervention > KX 15089 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 14 décembre 2017 Dernière intervention - 17 oct. 2017 à 15:36
Bonjour KX,

Désolé, tu vas vraiment croire que je le fais exprès et surtout que je fais aucune recherche, mais c'est vraiment pas le cas
Juste la je bloque trop et j'en vois vraiment pas le bout ^^

Tout marche niquel côté Java/JS maintenant, dans ma console JS, ma liste s'affiche correctement !
Mais la c'est coté JSP, impossible de l'afficher cette liste (le pire c'est que quand ca ne s'affichait pas correctement coté JS, j'y étais arrivé mais à force de tout modifié bha impossible d'y arriver maintenant!)
J'ai regardé un peut cette histoire de DOM, mon problème est vraiment sur le select, il doit manquer une condition ou autre. J'ai testé plein de truc différent dans <option value ...> rien de très concluant, donc j'ai mis le dernier que j'ai testé (mais qui n'a pas marché pour autant)
Lors du clique sur ma première liste, la deuxième liste retourné est vide sur ma page html.

Mon code JSP :
<div class="form-group">
         <label for="chantier_id" class="col-sm-2 col-sm-2 control-label">Nom du Chantier<span class="requis"></span></label>
         <div class="col-sm-10">
         <select class="btn btn-default dropdown-toggle" id="chantier" name="chantier" onchange = "listZone('chantier','zone')" required autofocus >
             <option value="" disabled selected>Chantier</option>
             <c:forEach items="${arrayChantier}" var="chantier">
                  <option value="<c:out value="${chantier.chantier_id}"/>">${chantier.chantier_name} </option>
            </c:forEach>
       </select>
       <span class="error">${form.errors['chantier_id']}</span>
       </div>
</div>
                           
         <div class="form-group">
              <label for="zone_id" class="col-sm-2 col-sm-2 control-label">Nom de la Zone<span class="requis"></span></label>
                      <div class="col-sm-10">
                            <select class="form-control" id="zone" name="zone"  required autofocus>
                               <option id="zone" value="">Zone</option>
                               <c:forEach items="${zones}" var="zone">
                                     <option value="${zones}">${zones}</option>
                               </c:forEach>
                           </select> 
                          <span class="error">${form.errors['zone_name']}</span>
                      </div>
           </div>



Merci beaucoup !!!
KX 15089 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 14 décembre 2017 Dernière intervention > Killkala 6 Messages postés lundi 2 octobre 2017Date d'inscription 18 octobre 2017 Dernière intervention - 17 oct. 2017 à 22:16
Avec la manipulation du DOM, ta deuxième liste peut être vide au moment de générer la page avec la JSP, de toute façon au moment où tu choisis la valeur dans la première liste l'AJAX va venir modifier la deuxième liste donc sa valeur précédente n'a aucune importance alors autant la mettre vide dans la JSP.
Killkala 6 Messages postés lundi 2 octobre 2017Date d'inscription 18 octobre 2017 Dernière intervention > KX 15089 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 14 décembre 2017 Dernière intervention - 18 oct. 2017 à 08:35
Le problème c'est que justement, lors de la sélection de mon élément de la première liste, ma deuxième liste retourné est vide.
Je suis sur que c'est du à un problème HTML car, lorsque je l'affiche dans ma console JS, la liste est bien existante.
Je n'arrive pas à mettre de photo j'aurai pu mieux vous montrer
Commenter la réponse de Killkala
KX 15089 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 14 décembre 2017 Dernière intervention - 18 oct. 2017 à 19:20
0
Utile
Voici un exemple en pur HTML/JavaScript.

<select id="list1" onchange="list1changelist2();">
    <option value='a'>A</option>
    <option value='b'>B</option>
    <option value='c'>C</option>
</select>
<select id="list2"></div>
<script>
    function list1changelist2() {
        list1 = document.getElementById("list1");
        selected = list1.selectedOptions[0].value;
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function() {
            if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                list2 = document.getElementById("list2");
                list2.innerHTML = xmlHttp.response;
            }
        }
        xmlHttp.open("GET", "/data?id="+selected, true);
        xmlHttp.send(null);
    }

    list1changelist2(); // pour l'initialisation
</script>

À chaque fois que la liste 1 change de valeur dans le HTML on appelle la fonction du code JavaScript, celui-ci va lire le DOM pour récupérer la valeur sélectionnée, par exemple "a", "b" ou "c" et faire une requête HTTP GET sur ton serveur à l'URL /data?id=a, /data?id=b ou /data?id=c selon la valeur.

Voici ce que pourrait renvoyer l'URL /data selon la valeur de l'id (ce que tu devrais faire avec une deuxième JSP)

/data?id=a
<option>A1</option>
<option>A2</option>
<option>A3</option>

/data?id=b
<option>B4</option>
<option>B5</option>
<option>B6</option>

/data?id=c
<option>C7</option>
<option>C8</option>
<option>C9</option>

C'est ce contenu qui sera inséré dans la liste2 à chaque appel de la fonction (que l'on peut appeler une première fois au chargement de la page pour initialiser la première valeur).
Commenter la réponse de KX

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.