[JSF] Warnen beim Verlassen der Seite mit ungespeicherten Änderungen

Das sieht schon mal ganz gut aus, vielen Dank! Werde es morgen auf der Arbeit dann mal selbst ausprobieren.
 
@Sentoo,

Deine Lösung finde ich sehr gut, habe aber noch folgende Frage: Bei mir kann das Flag "changed" unter IE (Ver. 8) beim Submit (a4j:commandButton) auf false nicht gesetzt werden, und IE meldet Script-Error auch noch :-( (!), während unter der beliebten FF alles wunderbar läuft und ich zweifele an dem JS-Event oncomplete, den IE wahrscheinlich nicht kapiert hat !
Hast Du denselben Fall auch?

Danke im Voraus


Moinsen,

habe gestern und heute damit ein wenig rum gespielt und gesucht. Das beste was ich ans Laufen bekomme habe ist folgendes
Code:
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<html>
<head>
<title>Warn for unsaved changes</title>
</head>
<body>
<f:view>
	<a4j:form>
		<h:outputLabel id="label_name" value="Name" for="in_name" />
		<h:inputText id="in_name" value="#{bean.name}"
			onchange="storeChange(true, this)" />
		<br />

		<h:outputLabel id="label_email" value="E-Mail" for="in_email" />
		<h:inputText id="in_email" value="#{bean.email}"
			onchange="storeChange(true, this)" />
		<br />
		<a4j:commandButton oncomplete="javascript:changed=false"
			value="Speichern" />
	</a4j:form>
</f:view>
</body>

<script language="javascript" type="text/javascript">
	// flag um zu merken, dass etwas geändert wurde.
	var changed = false;
	/*
	Speichert im changed flag, ob eine Eingabe vom Nutzer gemacht wurde. 
	Anschließend wird der Aufruf dieser Methode aus dem entsprechenden Attribut
	des input elements entfernt, um unnötige Aufrufe zu sparen.
	*/
	function storeChange(aChanged, aElement) {
		changed = aChanged;
		aElement.setAttribute('onchange', '');
	}
	/*
	Falls das changed flag angibt, dass es ungespeicherte Eingaben gibt, wird
	eine Warnung ausgegeben, ob die Seite verlassen werden soll. Das erfolgt
	über einen Standardmechanismus. Deswegen ist der Text der zurückgegeben
	wird in einem Textblock des Browser eingebettet. Der Haken daran ist, dass
	dabei die Spracheinstellungen des Anwenders respektiert werden. Es kann also
	sein, dass englischer Text von der deutschen Standardwarnung umrahmt ist.
	*/
	window.onbeforeunload=function unloadAlert() {
		if(changed) {
			// wird Text zurückgegeben, wird dieser in der Standardwarnung eingebettet.
			// ehrlicherweise wird alles was diese Methode zurückgibt als String geparst.
			return 'Sie haben nicht gespeicherte Eingaben auf dieser Seite. Wenn Sie OK clicken gehen diese Informationen verloren.';
		}
		// ausser null.
		return null;
	}
</script>
</html>

Allerdings erschlägt das wohl zu viel. Nämlich auch diese Fälle


Wenn Du so etwas machen möchtest, musst Du tatsächlich einen eigenen Navigation Handler realisieren. Zu dem müsstest Du das JavaScript-Flag transportieren, was vielleicht über a4j:jsFunction ginge. Müsste ich nochmal drüber nachdenken.
 
Hallo & Willkommen Wahid,

mit dem IE 8 kenne ich mich noch nicht groß aus. Die Firma für die wir entwickeln setzt auf den IE6 oder FF 3.X.

Was ich Dir raten kann ist leider nur folgendes:
Besorg Dir die IE Developer Tools, die sind Kostenfrei: Discovering Internet Explorer Developer Tools

Wenn ich solche Probleme mit dem FF habe schaue ich mir das im FireBug an. Das gibt es für den IE 6 nicht. Deswegen kann ich Dir nicht viel zu deinem Problem sagen, ausser, dass Du mit den Developer Tools für den IE auch Java Script debuggen kannst. Damit kannst Du Dein Problem einkreisen.
 
Hallo Sentoo,

läuft bei dir das Script unter IE6 problemlos? Habe gerade ein Standalone Version geholt (http://www.my-debugbar.com/wiki/IETester/HomePage) und hat auch nicht funktioniert. Leider mit dem Debuggen von Javascript in IE Web Developper kenne ich mich nicht so gut wie genug aus. Falls Dir spontan was einfällt, wäre ich sehr dankbar für Deinen Vorschlag.


Hallo & Willkommen Wahid,

mit dem IE 8 kenne ich mich noch nicht groß aus. Die Firma für die wir entwickeln setzt auf den IE6 oder FF 3.X.

Was ich Dir raten kann ist leider nur folgendes:
Besorg Dir die IE Developer Tools, die sind Kostenfrei: Discovering Internet Explorer Developer Tools

Wenn ich solche Probleme mit dem FF habe schaue ich mir das im FireBug an. Das gibt es für den IE 6 nicht. Deswegen kann ich Dir nicht viel zu deinem Problem sagen, ausser, dass Du mit den Developer Tools für den IE auch Java Script debuggen kannst. Damit kannst Du Dein Problem einkreisen.
 
Hi Sentoo,
Ich habe probiert und probiert, aber scheinbar dass IE das JS bei oncomplete nicht kapiert, was kannst Du mir raten um dieses Problem zu lösen? Danke im Voraus
 
Hi,

hatte vorläufig wieder Zeit um auf dem JS weiterzuarbeiten, und habe wie im folgenden das Problem gelöst (inkl. Internationalisierung der ausgegebener Meldung):
Code:
// flag um zu merken, dass etwas geändert wurde.
var changed = false;

/*
 * Ab hier wird das Output-Message für den Info-Dialog anhand der default
 * Browsersprache (bei Firefox) bzw. der Systemsprache internationalisiert
 */
var locale = (navigator.userLanguage) ? navigator.userLanguage
		: (navigator.language) ? navigator.language : 'en';

// Lese die ersten zwei Buchstaben des Sprachcodes ein
var msg;
var languageCode = locale.substr(0, 2);
switch (languageCode) {
case "de":
	msg = "Sie haben nicht gespeicherte Eingaben auf dieser Seite. Wenn Sie OK clicken gehen die %C4nderungen verloren.";
	break;
case "en":
	msg = "You have unsaved changes on the page. If you click on OK, the changes will be lost.";
	break;
default:
	msg = "You have unsaved changes on the page. If you click on OK, the changes will be lost.";
}

/*
 * Wird aufgerufen um den Server-seitigen Boolean "changed" bei "onchange"
 * Events auf true zu setzen
 */
function setDirtyFlag() {
	changed = true;
}
/* Wird aufgerufen bei "oncomplete"-Events bei Save-Buttons sowie Compute-Buttons */
function releaseDirtyFlag() {
	changed = false;
}
/*
 * Falls das dirty flag "changed" angibt, dass es ungespeicherte Eingaben gibt, wird
 * eine Bestätigungsmeldung ausgegeben, bevor dass die Zielseite geladen wird, ob die Seite verlassen werden soll.
 */

window.onbeforeunload = function unloadAlert() {

	if (changed) {
		if (window.event)
			window.event.returnValue = unescape(msg);
		else
			return unescape(msg);
	}
};

N.B : Die Funktionen "setDirtyFlag" und "releaseDirtyFlag()" sind JS-spezifische Funktionen, daher dürfen nicht anders benannt werden !

Viel Spaß !
 
Zurück