SELF-Treffen in Mannheim 2025

SELFHTML wird 30 Jahre alt!
Die Mitgliederversammlung findet am 24.05.2025 um 10:00 statt. Alle Mitglieder und Interessierte sind herzlich eingeladen.
Davor und danach gibt es Gelegenheiten zum gemütlichen Beisammensein. → Veranstaltungs-Ankündigung.

Beispiel:Verkettete Auswahllisten.html

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Verkettete Auswahllisten Beispiel</title>

<script>
/**
* An dieser Stelle erfolgen die Festlegungen der möglichen Termine und
* somit auch der möglichen Pfade.
* Dies sollte vielleicht in eine eigene Ressource, etwa "terminAuswahl.js"
* ausgelagert werden.
**/

var terminAuswahl = {
  'professor' : {
    'p23' : ['p23', 'Albers, Alfred'],
    'p24' : ['p24', 'Braun, Berta'],
    'p25' : ['p25', 'Drachenzaun, Doris'],
    'p26' : ['p26', 'Müller, Stephan'],
    'p27' : ['p27', 'Meier, Manfred']
  },

  'lesung' : {
    'p23' : [
      ['l55', 'Katzen in der freien Wildbahn'],
      ['l56', 'Katzen im Gefängnis'],
      ['l56', 'Katzen in Australien']
    ],

    'p24' : [
      ['l65', 'Hunde im Himmel'],
      ['l66', 'Hunde in der Hölle'],
      ['l66', 'Höllenhunde']
    ],

    'p25' : [
      ['l75', 'Wirtschaftskram I'],
      ['l76', 'Wirtschaftskram II'],
      ['l76', 'Wirtschaftskram III']
    ],

    'p26' : [
      ['l85', 'Technologie in der Steinzeit'],
      ['l86', 'Technologie in der Bronzezeit'],
      ['l86', 'Technologie heute']
    ],

    'p27' : [
      ['l95', 'Althochdeutsch'],
      ['l96', 'Mittelhochdeutsch'],
      ['l96', 'Deutsch für Angefangene']
    ]
  },

  'termin' : {

    'l55' : [
      ['t123', 'freitags 10 - 12'],
      ['t124', 'sonntags 18 - 20']
    ],
    'l56' : [
      ['t125', 'montags 12 - 14'],
      ['t126', 'dienstags 8 - 10']
    ],
    'l57' : [
      ['t127', 'dienstags 10 - 12'],
      ['t128', 'mittwochs 13 - 15']
    ],

    'l65' : [
      ['t133', 'freitags 10 - 12'],
      ['t134', 'sonntags 18 - 20']
    ],
    'l66' : [
      ['t135', 'montags 12 - 14'],
      ['t136', 'dienstags 8 - 10']
    ],
    'l67' : [
      ['t137', 'dienstags 10 - 12'],
      ['t138', 'mittwochs 13 - 15']
    ],

    'l75' : [
      ['t143', 'freitags 10 - 12'],
      ['t144', 'sonntags 18 - 20']
    ],
    'l76' : [
      ['t145', 'montags 12 - 14'],
      ['t146', 'dienstags 8 - 10']
    ],
    'l77' : [
      ['t147', 'dienstags 10 - 12'],
      ['t148', 'mittwochs 13 - 15']
    ],

    'l85' : [
      ['t153', 'freitags 10 - 12'],
      ['t154', 'sonntags 18 - 20']
    ],
    'l86' : [
      ['t155', 'montags 12 - 14'],
      ['t156', 'dienstags 8 - 10']
    ],
    'l87' : [
      ['t157', 'dienstags 10 - 12'],
      ['t158', 'mittwochs 13 - 15']
    ],

    'l95' : [
      ['t163', 'freitags 10 - 12'],
      ['t164', 'sonntags 18 - 20']
    ],
    'l96' : [
      ['t165', 'montags 12 - 14'],
      ['t166', 'dienstags 8 - 10']
    ],
    'l97' : [
      ['t167', 'dienstags 10 - 12'],
      ['t168', 'mittwochs 13 - 15']
    ]
  }
};
/**
* Ende terminAuswahl.js
**/
</script>
<script>
/**
 * LinkedSelection ist ein Klasse zur Steuerung dynamisch verketteter Auswahllisten
 * @param inputSelects ein Array mit den IDs der Auswahllisten in hierarchischer Reihenfolge
 *						Bsp: [ 'select1', 'select2', 'select3' ]
 * @param callback Funktion, welche beim Abschließen (und Ändern) der Auswahl aufgerufen werden soll
 * @param data das Daten-Objekt in JSON
 *						Bsp: { 'select1':['wert1','text1'], 'select2':['wert5','text5'] }
 *
 * sollte ebenfalls ausgelagert werden, etwa "LinkedSelection.js"
 * 
 **/
 
function LinkedSelection( inputSelects, callback, data )
{
	var self = this;				/* um aus EventHandlern auf diese Instanz zugreifen zu können */
	var selects = new Array();		/* Liste der verketteten Auswahllisten */

	/**
	 * Die Funktion changeHandler wird dem onchange-Handler jeder Auswahlliste zugewiesen.
	 * Wenn eine gültige Auswahl getroffen wurde, soll entweder die als nächste
	 * Auswahlliste (nextSelect) bekannte Auswahlliste mit Daten befüllt werden,
	 * oder die Callback-Funktion ausgeführt werden.
	 **/
	var changeHandler = function()
	{
		var value = this.selectedValue();

		// Auf die nächste Auswahlliste folgende Auswahllisten müssen wieder
		// in den default-Zustand versetzt werden
		if( typeof(this.nextSelect) == 'object' )
		{
			for( var i = this.nextSelect.selectID + 1; i < selects.length; i++ )
				selects[i].replaceOptions( new Array() );
		}

		// Abbrechen, wenn ein Dummy-Wert ausgewählt wurde
		if( value == '--' )
		{
			if( this.selectID < selects.length )
				selects[ this.selectID +1 ].replaceOptions( new Array() );

			return;
		}

		if( typeof(this.nextSelect) == 'object' )
		{
			/*
			 * nextSelect ist eine Auswahlliste
			 */

			// Wenn keine Daten zur gemachten Auswahl zur Verfügung stehen,
			// müssen wir sicherstellen, dass wir auf keine nicht vorhandenen Objekte zugreifen.
			if( !data[ this.nextSelect.id ][ value ] )
			{
				if( !data[ this.nextSelect.id ] )
					data[ this.nextSelect.id ] = {};

				data[ this.nextSelect.id ][ value ] = new Array();
			}

			// Neue Optionen in der nächsten Auswahlliste setzen
			this.nextSelect.replaceOptions( data[ this.nextSelect.id ][ value ] );

			// Wenn die Auswahlstrecke nicht beendet ist, muss die Callback-Funktion
			// dennoch aufgerufen werden, damit entsprechend auf Änderungen
			// reagiert werden kann.
			callback( new Array() );
		}
		else
		{
			/*
			 * Die Auswahlstrecke ist absolviert
			 */

			// Wahlen der einzelnen Listen in ein Array schreiben um
			// dieses an die Callback-Funktion zu übergeben.
			var selected = new Array();
			for( var i = 0; i < selects.length; i++ )
			{
				selected.push( { 'id' : selects[i].id,
								 'value': selects[i].selectedValue(),
								 'text' : selects[i].selectedText() } );
			}
			callback( selected );
		}
	};

	/**
	 * replaceOptions ersetzt die aktuellen Optionen der Auswahlliste durch
	 * die im Array newOptions gelieferten Daten. Wenn ein leeres Array übergeben
	 * wird, wird die default-Option "--" gesetzt.
	 * @param newOptions ein Array mit den neuen Optionen
	 *					  Bsp: [ ['value1','text1'], ['value2','text2'], ]
	 **/
	var replaceOptions = function( newOptions )
	{
		/*
		 * Diese Funktion setzt bewusst DOM-Methoden ein und verzichtet
		 * auf die vom Options-Objekt gegebenen Möglichkeiten.
		 */

		// alte Optionen der Auswahlliste löschen
		var opts = this.getElementsByTagName( 'option' );
		while( opts.length > 0 )
			this.removeChild( opts[0] );

		// wenn keine neuen Optionen übergeben wurden, default-Option setzen
		// andernfalls "Bitte wählen" voranstellen
		if( newOptions.length == 0)
			this.addOption( '--', '------' );
		else
			this.addOption( '--', 'Bitte wählen:' );

		// neue Optionen in die Auswahlliste schreiben
		for( var i = 0; i < newOptions.length; i++ )
			this.addOption( newOptions[i][0], newOptions[i][1] );
	};

	/*
	 * Fügt der Auswahlliste eine neue Option hinzu
	 * @param value Wert der neuen Option
	 * @param text Name der neuen Option
	 */
	var addOption = function( value, text )
	{
		var opt = document.createElement( 'option' );
		opt.value = value;
		opt.appendChild( document.createTextNode( text ) );
		this.appendChild( opt );
	};

	/**
	 * holt den Wert der aktuell gewählten Option
	 * @returns den Value der aktuell gewählten Option
	 **/
	var selectedValue = function()
	{
		return this.options[ this.selectedIndex ].value;
	};

	/**
	 * holt den Text (Name) der aktuell gewählten Option
	 * @returns den Text der aktuell gewählten Option
	 **/
	var selectedText = function()
	{
		return this.options[ this.selectedIndex ].text;
	};

	/**
	 * Selektiere die Option mit dem Wert value, wenn keine Option mit dem Wert
	 * value existiert, wird die Auswahl nicht geändert.
	 * @param value der Wert den eine Option haben muss, um ausgewählt zu werden.
	 **/
	var selectByValue = function( value )
	{
		for( var i = 0; i < this.options.length; i++ )
		{
			if( this.options[i].value == value )
				this.selectedIndex = i;
		}
	}

	/**
	 * Initialisiere den Manager für verkettete Auswahllisten.
	 * Findet Auswahllisten anhand der (per inputSelects) bekannten IDs.
	 * Bestückt die Auswahllisten mit den nötigen Funktionen und Event-Handlern
	 **/
	this.init = function()
	{
		// bestücke bestehende selects
		for( var i = 0; i < inputSelects.length; i++ )
		{
			var t = document.getElementById( inputSelects[i] );

			// ignoriere falsche IDs
			if(!t)
				continue;

			// neue Funktionen und Event-Handler zuweisen und in selects registrieren
			t.replaceOptions = replaceOptions;
			t.addOption = addOption;
			t.selectedValue = selectedValue;
			t.selectedText = selectedText;
			t.selectByValue = selectByValue;
			t.selectID = selects.length;
			t.onchange = changeHandler;
			selects.push( t );

			// registriere Auswahlliste als nextSelect bei der vorhergehenden
			if( selects.length > 1 )
				selects[ selects.length-2 ].nextSelect = t;
		}
	};

	// initialisieren!
	this.init();
}

</script>
<script>
/**
 * Diese Callback-Funktion soll beim Abschliessen der Auswahlstrecke und beim
 * Ändern der Auswahl in einer der Auswahllisten aufgerufen werden.
 * @param selected ein Array mit den Daten der jeweiligen Auswahllisten
 *                 (leer, wenn Strecke nicht abgeschlossen)
 **/
function ergebnisZeigen( selected )
{
	if( selected.length )
	{
		/*
		 * Auswahlstrecke wurde beendet
		 */

		// Visualisierung der Auswahlstrecke
		var sel = '';
		var val = '';
		var txt = '';
		for( var i = 0; i < selected.length; i++ )
		{
			sel += ( i>0 ? ' &rarr; ' : '') + selected[i].id;
			val += ( i>0 ? ' &rarr; ' : '') + selected[i].value;
			txt += ( i>0 ? ' &rarr; ' : '') + selected[i].text;
		}
		var output = '<h3>Gewählte Strecke:<'+'/h3><h4>IDs der Auswahllisten<'+'/h4><p>' + sel +
			'<'+'/p><h4>Werte der gewählten Optionen<'+'/h4><p>' + val +
			'<'+'/p><h4>Texte (Namen) der gewählten Optionen<'+'/h4><p>' + txt + '<'+'/p>';
	}
	else
	{
		/*
		 * Auswahlstrecke wurde noch nicht beendet
		 */

		// Hinweis zur Auswahl in der nächsten Auswahlliste
		var output = '<p>Wählen Sie eine Option aus der nächsten Auswahlliste.<'+'/p>';
	}
	var ergebnisObj = document.getElementById( 'ergebnis' ).innerHTML = output;
};

window.onload = function()
{
	var vk = new LinkedSelection( [ 'professor', 'lesung', 'termin' ], ergebnisZeigen, terminAuswahl );
}

</script>

</head>
<body>

<h1>Beispiel 1</h1>

<p>Bitte wählen Sie in der folgenden Auswahlliste einen Professor</p>

<p>
<label id="professorLabel" for="professor">Professor:</label>
<select id="professor">
  <option value="--">Bitte wählen:</option>
  <option value="p23">Albers, Alfred</option>
  <option value="p24">Braun, Berta</option>
  <option value="p25">Drachenzaun, Doris</option>
  <option value="p26">Müller, Stephan</option>
  <option value="p27">Meier, Manfred</option>
</select>

<label id="lesungLabel" for="lesung">Lesung:</label>
<select id="lesung">
  <option value="--">------</option>
</select>

<label id="lesungTermin" for="termin">Termin:</label>
<select id="termin">
  <option value="--">------</option>
</select>
</p>

<div id="ergebnis"></div>

</body>
</html>