Source-Code von KISS-Vote 0.3

Aus Unibrennt Wiki (Archiv)
Zur Navigation springen Zur Suche springen

Zurück zu KISS-Vote

Den Source-Code wird eher nur ein Programmierer verstehen der schon mit Javascript zu tun hatte. Er steht auf jeden Fall offen zur Verfügung und Kritik ist erwünscht.


Der Kopf


<!DOCTYPE HTML>
<html>
<head>
<title>KISS-Vote ... keep it small and simple!</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>

Das sind typische Angaben ganz oben bei HTML-Dateien. Der DOCTYPE ist bewusst kurz gehalten. Der W3C-Validator nimmt das als HTML5-Angabe, was nicht ganz falsch ist. Es wird dem Browser also nicht im besonderen vorgeschrieben wie er das HTML-Dokument zu parsen hat. Der Browser wird also Standard-HTML-Parsing machen so wenig STRICT wie gerade möglich. Dies ist auch vollkommen ok.

Die Meta-Angabe zu UTF-8 wird eingelöst, die Datei kiss_vote.html ist als UTF8 ohne BOM gespeichert.

Sonst ist nur noch der Titel, auf weitere META-Angaben wurde der Würze der Kürze wegen verzichtet.

Die zentralen CSS-Angaben


<style type="text/css">

div.div_election_option 
{
  position:relative;
  border:2px outset black;
  padding:0.5% 0.5% 0.5% 1%; 
  margin:5px;
  height:46px;
}

div.div_election_option_title
{
  display:inline-block;
  width:12%;
  position:relative;
  float:left;
}
 
span.span_option_title
{
  font-size:32px;
  font-weight:bold;  
  white-space:nowrap;
}

span.span_option_sum
{
  position:absolute;
  left:0px;
  top:30px;
  font-size:12px;
  font-weight:bold;
}


div.div_election_button 
{
  float:right;
  display:inline-block;
  border:2px outset black;
  margin-left:1%;
  width:10%;
  height:40px;
  font-size:32px;
  text-align:center;
  font-weight:bold;
  cursor:pointer;
}

div.div_election_button:hover
{
  border-color:#333333;
}


div.div_election_vote
{
  margin-top:4px;
  display:inline-block;
  border:1px solid black;
  width:10%;
  height:36px;
  font-size:32px;
  font-weight:bold;
  text-align:center;
  float:left;
}

div.div_election_submit
{
  float:right;
  margin:30px;
  padding-top:5px;
  width:350px;
  height:40px;
  border: 3px outset black;
  font-size:28px;
  text-align:center;
  cursor:pointer;
  background-color:#89ee99;  
}

div.div_election_submit:hover
{
  border-style:inset;
}

div.div_pseudolink
{
  display:inline;
  color:blue;
  text-decoration:underline;
  cursor:pointer;
}

</style>

Das sind sogenannte CSS-Angaben (Cascading Style Sheet), oder einfach Style-Angaben. Mit ihrer Hilfe kann das Aussehen und optische Verhalten gleich von mehreren Elementen zugleich definiert werden. Man kann auf ziemlich ausgefeilte Art auf Mengen und Untermengen oder auch auf einzelne Elemente zugreifen.

CSS ist für jene die es kennen sehr einfach. Irgendwann hat man all die CSS-Angaben 'im Blut'. Irgendwie ist alles sauberes Englisch und ganz logisch.

Die genaue Interpretation des CSS sei dem geneignten Leser oblassen.

Von Head zu Body


</head>
<body>

Kopfbereich <head> wird zu gemacht und Körper-Bereich <html> wird aufgemacht. Tja, so ein HTML hat eben Kopf und Fuß. Diese Elemente sind absoluter Standard und echt auf jeder Homepage zu finden. :)

Ab jetzt kommt Javascript, da wirds haariger...


Der massive Javascript-Teil

Der Anfang


<script type='text/javascript'>
<!--
var num_option = 0;
var pwd = '';
var num_election = 0;

Der Bereich für JavaScript wird eröffnet und die einzigen drei globalen Variablen werden definiert.

  • num_option ... Sie Anzahl der Varianten welche zur Wahl stehen (wird am Anfang eingegeben)
  • pwd ... Das Passwort zum Weiter-und Freischalten der Bereiche (wird am Anfang eingegeben)
  • num_election ... Der Zähler,welcher die Anzahl der durchgeführten Wahlen hällt

Die Hilfsfunktion


function getElement(strID)
{
  return document.getElementById(strID);
}

Es ist so lästig jedes Mal schreiben zu müssen document.getElementById('pla'). Und man braucht es oft, ja, ständig! Deswegen habe ich mir diese Hilfsfunktion angewöhnt die den folgenden JaScript-Code deutlich zu kürzen hilft.


Klick: Initalisierung bestätigt


function clickedInitSubmit()
{
  num_option = parseInt(getElement('input_num_options').value);
  if (num_option > 99) 
  {
    alert('Sie Variantenanzahl ist zu gross! Das zwingt den Browser in die Knie!');
    getElement('input_num_options').focus();
    return false;
  }
  if (num_option > 1)
  {
    getElement('div_init_election').style.display = 'none';
  
    createOptions();
  
    pwd = getElement('input_password_init').value;
    if (pwd.length > 0) 
    {
      getElement('div_pwd').style.display = 'block';
      getElement('input_password_election').focus();
    }
    else 
    {
      getElement('div_election').style.display = 'block';
    }
  }
  return false;
}

Die Variantenanzahl (num_option) wird ausgelesen. Wenn sie nicht größer 1 ist wird gleich gar nix gemacht. Wenn Sie größer als 99 ist dann wird eine Luxus-Fehlermeldung ausgegeben. Luxus deshalb weil sie eigentlich nicht notwendig ist. Nachdem ich aber durch Test-Eingabe von 1000 meinen Browser und fast das ganze System abgeschossen hatte hab ich mich zu dieser Fehlermeldung geneigt gesehen.

Der ganze Init-Bereich (div_init_election) wird unsichtbar gemacht.

Die Varianten-Maske wird aufgebaut (siehe Funktion createOptions())

Das Passwort wird ausgelesen. Wenn ein Passwort eingegeben wurde dann welchsle ins Passwort-Fenster,sonst direkt zum Abstimmungs-Fenster.

Zuletzt noch das return false. Dieses ist wichtig bei Ereignissen durch submit-Buttons die mit JavaScript abgefangen werden da sonst das Formular zurückgesetzt wird.

Klick: Passwort-Eingabe


function clickedPassword()
{
  if (getElement('input_password_election').value == pwd)
  {
    getElement('div_pwd').style.display='none';
    getElement('div_election').style.display='block';  
  }
  return false;
}

Das Eingabefeld wird ausgelesen und mit dem gespeicherten Passwort verglichen. Ziemlich unspektakulär. Bei richtiger Eingabe wird zum Abstimmungs-Fenster gewechselt.

Das Anlegen der Varianten-Reihen


function createOptions()
{
  divOuter = getElement('div_election_option_frame');
  divOption = divOuter.getElementsByTagName('div')[0];

  for (number = 1; number <= num_option; number++)
  { 
    newOption = divOption.cloneNode(true);
    divOuter.appendChild(newOption);

    newOption.setAttribute('id', 'div_option_' + number);
    newOption.setAttribute('var_sum', '0'); 

    divElementArray = newOption.getElementsByTagName('div')
  
    spanElementArray = divElementArray[0].getElementsByTagName('span');
    
    spanElementArray[0].firstChild.nodeValue = 'Nr. ' + number;
    spanElementArray[1].setAttribute('id', 'span_option_sum_' + number);
 
    divElementArray[1].setAttribute('id', 'div_vote_' + number); 

    for (value = 5; value >= 0; value--)
    {
      divElementArray[7 - value].setAttribute('id', 'div_button_' + value + '_' + number);
      divElementArray[7 - value].setAttribute('var_value', value);
      divElementArray[7 - value].setAttribute('var_number', number);
      divElementArray[7 - value].onclick = function(){clickedOptionButton(this.getAttribute('var_value'), this.getAttribute('var_number'));};
      divElementArray[7 - value].setAttribute('var_bgcolor', divElementArray[7 - value].style.backgroundColor);
    }
    newOption.style.display='block';
  }
}

Diese Funktion ist ganz zentral. Sie kopiert das, im unteren HTML vordefinierte, DOM-Element mit der ID 'div_election_option'. (Das erste div-Element unter dem Element 'div_election_option_frame')

Dann fügt die Funktion in der FOR-Schleife nacheinander eine Variante nach der anderen hinzu. Jede Variante wird dann noch mit den richtigen Werten ausgestattet und fertig. Diese Varianten-Initialisierung mag kompliziert ausschauen ist aber ganz einfach.

  • Die äußere FOR-Schleife durchläuft die Varianten von 1 bis num_option.
  • Die innere FOR-Schleife durchläuft die Buttons 0 bis 5.


Alle Buttons eine Variante zurücksetzen


function setAllOptionButtonsOutset(number)
{
  for (value = 0; value <= 5; value++)
  {
    divButton = getElement('div_button_' + value + '_' + number)
    with (divButton.style)
    {
      borderStyle = 'outset';
      backgroundColor = divButton.getAttribute('var_bgcolor');  
    }
  }
}


Hier werden die Styles von allen Buttons auf den Grundzustand zurückgebracht.


Klick: Wenn der User einen Button (0 bis 5) drückt.


function clickedOptionButton(value, number)
{
  setAllOptionButtonsOutset(number);
    
  divVote = getElement('div_vote_' + number);
  divVote.firstChild.nodeValue = value;

  divButton=getElement('div_button_' + value + '_' + number);

  with (divVote.style)
  {
    color = divButton.style.color;
    backgroundColor = divButton.getAttribute('var_bgcolor');
  }  

  with (divButton.style)
  {
    backgroundColor = '#FFFFFF'; 
    borderStyle = 'none'; 
  }
}

Der Wert des Buttons (value) und die Nummer der Variante (number) werden gleich an die Funktion übergeben.

  • Erstmal werden alle Buttons dieser Variante auf den Grundzustand gebracht.
  • Dann wird der der Zahlenwert in die linke Box bei der Variante (div_vote)geschrieben.
  • Dann wird der gedrückte Button als Objekt geholt (divButton) und das Aussehen des 'div_vote' wird angepasst. Schrift-Farbe und Hintergrundfarbe.
  • Zuletzt wird noch der gedrückte Button graphisch angepasst. (Hintergrung weiß und Rahmen weg)


Die Abstimmungs-Maske auf den Grundzustand zurückbringen


function initButtonsForNewElection()
{
  for (number = 1; number <= num_option; number++)
  {
    setAllOptionButtonsOutset(number);
    divVote = getElement('div_vote_' + number);
    divVote.style.color = '#000000';
    divVote.style.backgroundColor = '#FFFFFF';
    divVote.firstChild.nodeValue = '0';
  }  
}

Auch eine sehr einfache Funktion. Es werden einfach alle Varianten in der FOR-Schleife durchlaufen und alle Buttons der Variante werden auf den Grundzustand gesetzt. (setAllOptionButtonsOutset())

Dann wird das 'div_vote'-Element ermittelt und auf den Grundzustand gesetzt. D.h.:

  • Schriftfarbe auf Schwarz.
  • Hintergrundfarbe auf Weiß
  • Text auf 0

Klick: Die Abstimmung einer WählerIn ist abgeschlossen


function clickedElectionSubmit()
{
  check = confirm('Sind Sie wirklich fertig und bereit zum speichern?');
  if (check != true) return;

  for (number = 1; number <= num_option; number++)
  { 
    divOption = getElement('div_option_' + number);
    divVote = getElement('div_vote_' + number);
    newSum = parseInt(divVote.firstChild.nodeValue) + parseInt(divOption.getAttribute('var_sum'));
    divOption.setAttribute('var_sum', newSum);
    spanOptionTitleSum = getElement('span_option_sum_' + number);
    spanOptionTitleSum.firstChild.nodeValue = 'Summe: ' + newSum;
  }  

  initButtonsForNewElection();

  if (isResultVisible()) clickedToggleResult();
  
  num_election++;
  getElement('h2_num_election').firstChild.nodeValue = 'Wahl-Nr.: ' + (num_election + 1);
  
  if (pwd.length > 0) 
  {    
    getElement('input_password_election').value = '';
    getElement('div_pwd').style.display = 'block';
    getElement('div_election').style.display = 'none';
    getElement('input_password_election').focus();
  }
  
}

Diese Funktion wird aufgerufen wenn der User den großen Button rechts unten geklickt hat. Die Abstimmung ist also fertig (für die WählerIn, die nächste ist dran.)

Zuerst ein Check. (Nachfrage, sind sie sicher?)

Dann werden alle Varianten in der FOR-Schleife durchlaufen:

  • Das umschließende
    jeder Variante wird als Objekt geholt. (div_option)
  • Das 'div_vote'-Objekt wird geholt. (Hier steht die vergebenen Einwandspunkte drinnen.)
  • Die neue Summe wird berechnet aus der alten Summe (div_option) und dem neuen Wert (div_vote)
  • Die neue Summe wird ins 'div_option' geschrieben. (var_sum)
  • Die Summenanzeige fürs Ergebnis (möglicherweise gerade unsichtbar) wird geholt. (span_option_sum)
  • Der Text der Summenanzeige wird aktualisiert.

Dann werden die ganzen Buttons initialisiert. (Das Abstimmungsfenster sieht dann wieder frisch aus.)

Wenn das Ergebniss sichtbar ist wird es auf Unsichtbar geschalten.

Die Anzahl der durchgeführten Wahlen wird erhöht. (num_election)

Die Text-Anzeige der Anzahl der Wahlen wird angepasst. (h2_num_election)

Wenn ein Passwort gesetzt wurde...

  • Der Wert des Passwort-Eingabefeldes (input_password_election) wird gelöscht. (Man muss es ja neu eingeben)
  • Das ganze Passwort-Fenster (div_pwd) wird angezeigt. Style auf Sichtbar geschalten
  • Das Abstimmungs-Fenster wird auf Unsichtbar geschalten.
  • Das Passwort-Eingabefeld (input_password_election) bekommt den Fokus. (Ist praktischer zum Schnell-Tippen.)

Ist das Ergebnis gerade sichtbar?


function isResultVisible()
{
  return (getElement('span_option_sum_1').style.display != 'none');
}

Um abzufragen ob das Ergebnis sichtbar ist wird einfach das Summenfeld der ersten Option auf Sichtbarkeit geprüft. Da mindestens 2 Optionen vorhanden sein müssen (nach dem Init) frunktioniert diese Funktion auf jeden Fall.

Ergebnis anzeigen bzw. verbergen


function clickedToggleResult()
{
  divToggleResultText = getElement('div_toogle_result').firstChild;
  
  if (isResultVisible()) 
  {
    valDisplay = 'none';
    divToggleResultText.nodeValue = 'Ergebnis anzeigen';
  }
  else
  {
    if (pwd.length > 0)
    {
      valCheck = prompt('Bitte das Passwort', '');
      if (valCheck != pwd) return;
    }

    valDisplay = 'inline';
   
    divToggleResultText.nodeValue = 'Ergebnis verbergen';
  
    divResultParent = getElement('div_toogle_result_list_parent');
    divResult = getElement('div_toogle_result_list');
    if (divResult)
    {
      divResultParent.removeChild(divResult);
    }
    divResult = document.createElement('div');
    divResult.setAttribute('id', 'div_toogle_result_list');  
    divResultParent.appendChild(divResult);

    divResult.appendChild(document.createTextNode('Es gab insgesamt ' + num_election + ' Wahlen.'));
  
    elementUl = document.createElement('ul');
    divResult.appendChild(elementUl);

    algArray = new Array();
    for (number = 1; number <= num_option; number++)
    {
      sum = parseInt(getElement('div_option_' + number).getAttribute('var_sum'));
      algArray.push((sum * 1000) + number);
    }
  
    algArray.sort(function(a, b){ return a - b; });
  
    for (i = 0; i < algArray.length; ++i)
    {
      number = parseInt(algArray[i]) % 1000;
      value = parseInt(parseInt(algArray[i]) / 1000);
      elementLi = document.createElement('li');
      elementUl.appendChild(elementLi);
      average = 0;
      if (num_election > 0) average = (Math.round((value * 100) / num_election) / 100);
      textLi = document.createTextNode('Nr.: ' + number + ' ... Punkte: ' + value + ' ... Durchschnitt: ' + average);
      elementLi.appendChild(textLi);
    }  
  }
  
  getElement('div_toogle_result_list').style.display = valDisplay;
  
  for (number = 1; number <= num_option; number++)
  {
    getElement('span_option_sum_' + number).style.display = valDisplay;
  }
}

Dies ist wahrscheinlich die kritischste Funktion.

WICHTIG: Die Anzeige der Summen-Anzeige direkt bei den Nummern der Varianten ('Nr. 1' usw.) ist von dieser Funktion auf keiner Weise beieinflusst. D.h. diese Summen können als Rückcheck genommen werden zum hier generierten Ergebnis.

Hier wird also die Ergebnisliste generiert. Erfasst, sortiert und ausgegeben.

Was passiert...

  • Das 'div_toogle_result' wird ausgelesen um später den neuen Text zu bekommen.
  • Wenn das Ergebnis gerade sichtbar ist...
    • Die Variable valDisplay wird auf unsichtbar ('none') gesetzt. (Anwendung kommt später)
    • Der 'div_toogle_result'-Text wird auf "Ergebnis anzeigen" gesetzt.
  • Wenn das Ergebnis gerade unsichtbar ist...
    • Wenn ein Passwort vergeben wurde: Passwort-Abfrage und return bei Falscheingabe.
    • Die Variable valDisplay wird auf sichtbar ('inline') gesetzt. (Anwendung kommt später)
    • Der 'div_toogle_result'-Text wird auf "Ergebnis verbergen" gesetzt.
    • Das umgebende Element (Parent) des Ergbnis-div-Elementes wird geholt. (div_toogle_result_list_parent)
    • Das Ergebis-div-element wird geholt. (div_toogle_result_list)
    • Wenn das 'div_toogle_result_list'-Element existiert, dann lösche es.
    • Erzeuge ein neues Div-element
    • Setzte die id auf 'div_toogle_result_list'.
    • Füge es beim Parent (div_toogle_result_list_parent) hinzu.
    • Erzeuge ein Text-Element mit der Anzahl der Wahlen und füge es dem 'div_toogle_result_list' hinzu.
    • Erzeuge ein ul-element.
    • Füge das ul-Element dem 'div_toogle_result_list' hinzu.
    • Lege ein neues Array an (algArray)
    • Durchlaufe die Varianten in einer FOR-Schleife
      • Hole die Ergebnis-Einwandspunkte-Summe 'var_sum' von 'div_option' der Variante
      • Schreibe ins Array die Summe * 1000 + Variantennummer. Siehe hierzu das untere Kapitel.
    • Sortiere das Array aufsteigend. (mit eigener Sortierfunktion, ist bei JavaScript so)
    • Durchlaufe das Array von der kleinsten Punktesumme zur größten mit FOR-Schleife
      • Ermittle die Varianten-Nummer durch Module (%)
      • Ermittle die Punkte-Summe durch Division und Rundung
      • Erzeuge ein li-Element
      • Füge das li-Element beim ul-Element als Kind ein
      • Setze die später auszugebene Variable für den Durchschnitt auf 0. (Damit sie sicher definiert ist.)
      • Wenn die Anzahl der Wahlen (num_election) größer 0 ist rechne den Punkte-Durchschnitt (Summe/Anzahl) mit Rundung auf 2 Kommastellen. (Dafür gibt es keinen Parameter bei Math.round() und deshalb der Trick mit der Multiplikation mit 100 = 2 Kommstallen)
      • Erzeuge ein Text-Element mit dem Listentext Bsp: "Nr.: 3 ... Punkte: 7 ... Durchschnitt: 1.75"
      • Füge das Text-Element dem li-Element hinzu.
  • Setze die Sichtbarkeit des Ergebnis-Bereiches (div_toogle_result_list) auf den vorher gesetzten Wert (valDisplay)
  • Durchlaufe alle Varianten mit FOR ...
    • Setze die Sichtbarkeit der Summenanzeige innerhalb des Abstimmungsfensters (span_option_sum) auf die Variable (valDisplay).


Uf, das wars dann ... das Ergebnis ist als HTML-Liste sichtar.


Erklärung: Summe und Variantennummer in einem Wert?? (algArray)

Wir müssen die ganzen Varianten nach ihrern Einwandspunkt-Summen ordnen. Im einfachen Javascript stehen nur normale Arrays zur Verfügung. Es reicht aber nicht aus, nur die Punkte-Werte ins Array einzutragen und zu sortieren, denn so würde man ja die Zuordnung zu den zugeörigen Varianten-Nummern verlieren.

Mit Sicherheit gibt es Zig Methoden dieses Problem anders zu lösen. Einige wären...

  • Ein Strukt oder Objekt ins Array schreiben und den Sortieralgorithmus entsprechend anpassen
  • Einfach nur die Punkte eintragen und sortieren und dann die Varianten nach Punkte rückermitteln (Weil ja jede Variante eine andere Punktesumme haben kann. Wenn 2 Varianten die selben Punkte haben ist ihre Reihenfolge eh egal.

Ich hab mich zum Reinrechnen entschieden. Hier wird einfach die Varianten-Nummer in die hochmultiplizierte Punktezahl eingerechnet so dass die numerische Sortierung die Varianten-Ziffern nur dann berücksichtigt wird wenn die Punkte-Anzahl gleich ist.

Es darf ja nur max. 99 Varianten geben aber es kann bis zu 500 Punkte pro Variante und mehr geben.

Wenn wir von 32 Bit-Integern ausgehen mit 31 Bit positiven Wertebereich, also max. 2147483648, und wir multiplizieren die Punkten-Summen mit 1000, dann darf die maximale Punkte-Summe nicht ca. 2000000 übersteigen. (Das geht sich aus.)

Nachher wird einfach über den Modulo (%) Operator der Rest aus der Division durch 1000 ermittelt, das ist die Varianten-Nummer (theoretisch bis 999 möglich, praktisch auf 99 beschränkt)

Über die Division und Rundung wird die zugehörige Einwands-Punkte-Summe ermittelt. Es ist also ein Reinrechnen, Sortieren und Rausrechnen.

Skript-Ende


//-->
</script>

So sieht eben ein ordentliches HTML-Skript-Ende aus.

Der HTML-Teil

Titel


<h1>KISS-Vote ... keep it small and simple!</h1>

Kurz und bündig. Ein H1-Titel. Kann sein dass man den besser weg tun würde um Platz am Monitor zu sparen.


Das große DIV für die Initialisierung 'div_init_election'


<div id='div_init_election'>

<h2>Inititalisierung</h2>

<form onsubmit="return clickedInitSubmit();">
<br/>
Variantenanzahl (max. 99)
<br/>
<input id='input_num_options' type='text' size='24'/>
<br/>
<br/>
Passwort
<br/>
<input id='input_password_init' type='password' size='24'/>
<br/>

<br/>
<input type='submit' value='Wahl starten!'/>
</form>

<br/>
<br/>
Es muss kein Passwort angegeben werden. 
<br/>
Nehmen Sie etwas, das schnell einzugeben und leicht zu merken ist.
<br/>
Sie werden jedes Mal aus Neue aufgefordert ein Passwort zu vergeben. 
</div> <!-- id='div_init_election' -->


Das große DIV für die Passwort-Eingabe vor jeder einzelnen Abstimmung 'div_pwd'


<div id='div_pwd' style='display:none;'>
<h2>Passwort eingeben</h2>

<form onsubmit="return clickedPassword();">
<br/>
Passwort:
<input id='input_password_election' type='password' size='16'/>
<br/>
<br/>
<input type='submit'/>
</form>
</div> <!-- id='div_pwd' -->


Das große DIV für das Abstimmungsfenster selbst 'div_election'


<div id='div_election' style='display:none;'>

<h2 id='h2_num_election'>Wahl-Nr.: 1</h2>

<div id='div_election_option_frame'>

<div class='div_election_option' style='display:none;'>
<div class='div_election_option_title'>
<span class='span_option_title'>Nr. 0</span>
<span class='span_option_sum' style='display:none;'>Summe: 0</span>
</div>
<div class='div_election_vote' style=''>0</div>
<div class='div_election_button' style='background-color:#d33837;color:#68080f;'>5</div>
<div class='div_election_button' style='background-color:#f28151;color:#a8581b;'>4</div>
<div class='div_election_button' style='background-color:#f9c056;color:#a8891b;'>3</div>

<div class='div_election_button' style='background-color:#f7f956;color:#a8a21b;'>2</div>
<div class='div_election_button' style='background-color:#dbf251;color:#6f7c16;'>1</div>
<div class='div_election_button' style='background-color:#89d239;color:#167c2e;'>0</div>
</div>

</div>

<div class='div_election_submit' onclick="clickedElectionSubmit();">
Ok, fertig und speichern!
</div>

<div id='div_election_info' style='margin-top:30px;'>
Jeder Variante geben Sie 0 bis 5 Einwands-Punkte. Wenn Sie keinen Einwand zu einer Variante haben dann geben Sie 0 Punkte.
<br/>

<br/>
<div id='div_toogle_result' class='div_pseudolink' onclick='clickedToggleResult();'>Ergebnis anzeigen</div>
<br/>
<br/>
<div id='div_toogle_result_list_parent'>
<div id='div_toogle_result_list' style='display:none;'>Kein Ergebnis vorhanden</div>
</div>
</div>


</div> <!-- id='div_election' -->

Endlich bei den Füßen angelangt


<br/>

<br/>
<br/>
<br/>
<br/>
<br/>
Dieses Programm ist zur freien Verwendung bestimmt und Open Source. Es besteht ausschliesslich aus diesem HTML-File. Alles (=) Liebe!

<script type='text/javascript'>
<!--
getElement('input_num_options').focus();
//-->
</script>


</body>
</html>