JSP i servlety z wykorzystaniem AJAX

0

Witam,
napisałem prostą stronkę, w której przy pomocy comboboxa wybierana jest opcja i następnie po naciśnięciu przycisku wywoływany jest servlet, który wyciąga dane z bazy danych, a następnie przedstawia wynik na nowej stornie jsp. Teraz chciałbym to wszystko zrobić przy pomocy AJAXa, czyli aby wynik był wyświetlany na tej samej stronie. No i niestety nie wychodzi mi połączenie tego wszystkiego.

Skrypt AJAX:

<script type="text/javascript">
function createXMLHttpRequest() {
	if (window.XMLHttpRequest)
	  // code for IE7+, Firefox, Chrome, Opera, Safari
	  return new XMLHttpRequest();
	else if (window.ActiveXObject)
	  // code for IE6, IE5
	  return new ActiveXObject("Microsoft.XMLHTTP");
	else
	  alert("Your browser does not support XMLHTTP!");

	return null;
}

var xmlhttp = new createXMLHttpRequest();

function handler() {
	if (xmlhttp.readyState==4 && xmlhttp.status==200)
		document.getElementById("WYNIK").innerHTML=xmlhttp.responseText;
}

function ajaxExecute() {
	xmlhttp.onreadystatechange = handler;
	xmlhttp.open("POST","Servlet.do",true);
	xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	xmlhttp.send("form="+opcja);
}
</script>

HTML:

<body>
<div id="szablon">
	<div id="FORMULARZ">
		<form name="form" method="post" action="Servlet.do">
			<select name="opcja">
				<option>opcja1</option>
				<option>opcja2</option>
				<option>opcja3</option>
				<option>opcja4</option>	
			</select>
			<br/><br/>
			<input type="button" name="przycisk1" value="przycisk1" onclick="script:ajaxExecute()"/>
			<input type="button" name="przycisk2" value="przycisk2" onclick="script:ajaxExecute()"/>
		</form>
	</div>
	<div id="WYNIK">wynik zapytania</div>
</div>
</body>

Przy takim kodzie po naciśnięciu przycisków nic się nie dzieje. Gdy zmienię rodzaj przycisków z "button" na "submit" to wykonuje się wszystko z pominięciem AJAXa. Proszę o jakiekolwiek wskazówki. W servlecie nadal mam podaną do wyświetlania stronę jsp. Może tutaj powinno być podane coś innego?

1

Pierwsze co bym zmienił to onclick="ajaxExecute()"
Druga rzecz, to w metodzie doPost zrób jakieś logowanie na konsolę, wypisz otrzymane parametry.
Trzecia rzecz: zainstaluj firebug, będziesz widział jakie zapytania generuje twoja strona i czy w ogóle to robi.

0

Dzięki chodnik za wskazówki. Firebug okazał się być bardzo pomocny. Problem polegał na przekazywaniu parametrów do metody doPost oraz na deklaracji zmiennych w:

xmlhttp.send();

Z przekazaniem parametru z formularza sobie poradziłem, niestety nie wiem w jaki sposób wyłapać, czy przycisk1 ma wartość null (czyli, że wciśnięto przycisk2). Obecnie wygląda to tak:function ajaxExecute() {
var opcja = document.getElementById("kolumna");
var przycisk1 = document.getElementById("przycisk1");
xmlhttp.onreadystatechange = handler;
xmlhttp.open("POST","Servlet.do",true);
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.send("opcja="+opcja.value+"&przycisk1="+przycisk1.value);
}

Niestety teraz za każdym razem przekazywana jest wartość "przycisk1" nawet podczas wciśnięcia przycisku2, gdzie powinna być wysłana wartość null. Oczywiście wiem, że deklaracja jest tutaj błędna, jednak nie mam pomysłu jak to rozwiązać. Jedyne co przychodzi mi do głowy to podpięcie osobnych funkcji pod każdy z przycisków i przekazanie w nich odpowiedniego parametru przycisku.
1

Dla własnego i użytkownika dobra lepiej zaprzęgnąć jQuery do AJAXa, gdzie wywołanie żądania sprowadza się do (przykład):

$.ajax({
  url: 'ajax/test.html',
  success: function(data) {
    $('.result').html(data);
    alert('Load was performed.');
  }
});

jQuery rozwiązuje też problemy kompatybilności wywołań AJAXa pod różnymi przeglądarkami.

W Twoim przypadku po dodaniu jQuery:

function ajaxExecute() {
    $.ajax({
        url: 'Servlet.do',
        type: 'POST',
        data: 'opcja=' + $("#kolumna").val() + '&przycisk1=' + $("#przycisk1").val(),
        
        success: function(data) {
            // data to zwrócona odpowiedź serwera
        }
    });
}
0

Po zastosowaniu jQuery całość wykonuje się 'chyba' poprawnie, ale nie mam wyniku w div'ie, jedynie w konsoli firebuga się to ukazuje. I nadal nie został rozwiązany problem z odczytaniem przycisku.

1

Dodałeś includowanie jQuery w nagłówku dokumentu, tak?

Co do obsługi przycisków to powinno się to robić inaczej. Jak już ktoś wcześniej wspomniał, na pewno nie przez onSubmit w HTMLu. Natomiast taki sposób jest dobry:

  1. Dopisujesz formularzowi id="ajaxFormularz"
  2. Przyciski robisz tak:
<input type="submit" name="przycisk1" value="przycisk1"/>
$("#ajaxFormularz").submit(function()
{
  // tutaj ten $.ajax..

  return false;
});

Najważniejszym elementem jest tutaj return false - spowoduje, że event (czyli wysłanie formularza) nie będzie dalej przekazywany (do wysłania)
4) W ajaxowym success umieszczasz:

$("#WYNIK").text(data);

Taka rozsypanka wyszła, ale poradzisz sobie.

0

jQuery dodałem do nagłówka. Gdy zrobiłem to tak jak napisałeś, to teraz wyskakuje błąd, gdyż do servletu przekazywana jest wartość null z comboboxa. Co do przycisków to w servlecie mam zrobione, że jeżeli przycisk1==null (czyli wciśnięty przycisk2), to wykonuje się jedno, w przeciwnym wypadku (wciśnięty przycisk1) wykonuje się coś innego. Ten sposób podany przez Ciebie obsługi przycisków będzie współgrał z moim warunkiem w servlecie?

1

Moja wina, trochę Twojego kodu nie doczytałem, w zasadzie to nawet nie wiem skąd bierzesz ten element od ID = "kolumna". Otóż combo boxowi najlepiej nadać ID żeby łatwo było odczytać jego wartość. Przyciski można też zorganizować w inny sposób; użyć dwóch z tym samym name lecz inną wartością:

<select id="opcjaSelect" name="opcja">
	<option>opcja1</option>
	<option>opcja2</option>
	<option>opcja3</option>
	<option>opcja4</option>        
</select>

<br/><br/>
<input type="submit" name="przycisk" value="przycisk1" />
<input type="submit" name="przycisk" value="przycisk2" />
</html>

Kolejny problem pojawia się, gdy chcesz mieć przekazaną zmienną "przycisk" z dwoma innymi wartościami: przycisk1 lub przycisk2. W sumie to najprościej zrobić to tak:

$("#ajaxFormularz> input[type=submit]").click(function() {   // dla każdego inputu o typie submit w #ajaxFormularz
    var wartoscPrzycisku = $(this).val();
    
    $.ajax({
        url: 'Servlet.do',
        type: 'POST',
        data: 'opcja=' + $("#opcjaSelect").val() + '&przycisk=' + wartoscPrzycisku,
 
        success: function(data) {
            $("#WYNIK").text(data);
        }
    });
    
    return false;
});

Wtedy w serwlecie odbierasz atrybuty opcja oraz przycisk z odpowiednimi wartościami.

0

Dzięki za pomoc. Jednak teraz wynik wyświetla mi się na nowej stronie, jakby z pominiętym AJAXem. I jeszcze odczytanie wartości przycisku w serwlecie coś mi nie wychodzi:

String przycisk = request.getParameter("przycisk");
if (przycisk=="przycisk1") lista = DAO.getInstance().powt(kolumna);
else lista = DAO.getInstance().unik(kolumna);
System.out.print(przycisk);

W takim wypadku za każdym razem wykonuje się operacja w 'else', dodam, że System.out.print(przycisk); poprawnie wyświetla w konsoli wartość przycisku. Jednak coś z tym porównaniem w ifie jest chyba nie tak.

0

Tak, bo w Javie napisy porównuje się za pomocą metody equals (lub equalsIgnoreCase), tj. przycisk.equals("przycisk1")

0

No tak. Ale gafa. Ale nadal wynik wyświetla się na nowej stronie, jakby AJAX był pominięty.

0

Spróbuj zamienić function() na function(event) i zamiast return false daj event.preventDefault();

0

Niestety nadal to samo.

0

No to ja już straciłem pomysły. Jeżeli request dochodzi do serwera to spróbuj wywalić action="Servlet.do" z forma. Może nic nie zrobi, albo napisz action="#"

0

Po wywaleniu action z forma nic się nie wykonuje. Gdy zmieniłem typ przycisku na 'button' oraz tutaj typ również zmieniłem

$("#formAjax>input[type=button]").click(function(event)

to po naciśnięciu przycisku nie ma w ogóle żadnej reakcji. Może coś w tym przechwytywaniu przycisków jest nie tak?

0

U mnie na takim schemacie działa:
http://jsfiddle.net/L3nAx/1/

Może spróbuj na takim schemacie:

$('#ajaxFormularz> input[type="submit"]').click(function() {

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.