You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@steve.apache.org by hu...@apache.org on 2015/03/25 00:26:33 UTC

svn commit: r1669022 - in /steve/trunk/pysteve/www/htdocs: ballot_dh.html css/steve_interactive.css js/steve_dh.js js/steve_rest.js

Author: humbedooh
Date: Tue Mar 24 23:26:33 2015
New Revision: 1669022

URL: http://svn.apache.org/r1669022
Log:
Add D'Hondt vote page

Added:
    steve/trunk/pysteve/www/htdocs/ballot_dh.html
    steve/trunk/pysteve/www/htdocs/js/steve_dh.js
Modified:
    steve/trunk/pysteve/www/htdocs/css/steve_interactive.css
    steve/trunk/pysteve/www/htdocs/js/steve_rest.js

Added: steve/trunk/pysteve/www/htdocs/ballot_dh.html
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/www/htdocs/ballot_dh.html?rev=1669022&view=auto
==============================================================================
--- steve/trunk/pysteve/www/htdocs/ballot_dh.html (added)
+++ steve/trunk/pysteve/www/htdocs/ballot_dh.html Tue Mar 24 23:26:33 2015
@@ -0,0 +1,39 @@
+ <!DOCTYPE HTML>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="css/steve_interactive.css">
+<link rel="stylesheet" href="css/jquery-ui.css">
+<script src="js/steve_rest.js" type="text/javascript"></script>
+<script src="js/steve_dh.js" type="text/javascript"></script>
+<script src="js/jquery.js" type="text/javascript"></script>
+<script src="js/jquery-ui.js" type="text/javascript"></script>
+<title>Apache STeVe: D'Hondt vote</title>
+
+</head>
+<body onload="window.setTimeout(loadIssue, 500, null, null, null, displayIssueDH);">
+    <div id="popups"></div>
+    <p style="text-align: center;">
+        <img src="/images/steve_logo.png"/>
+    </p>
+    <a href="javascript:void(location.href='election.html' + document.location.search);">Back to election front page</a>
+<div class="formbox">
+    <p>
+        This is a standard D'Hondt (Jefferson) based vote with <span id="cnum">N</span> candidates and
+    <span id="snum">N</span> seats available. Select the candidate/party you would like to vote for and click <kbd>Cast vote</kbd> to cast your vote.
+    You can change your vote as often as you like, should you reconsider your choice.
+    </p>
+<div id="preloaderWrapper">
+    <img src="/images/steve_spinner.gif"/>
+    <div id="preloader">
+        Loading issue, please wait...
+    </div>
+</div>
+</div>
+<p style="font-size: 12px; font-style: italic; text-align: center;">
+    Powered by <a href="https://steve.apache.org/">Apache STeVe</a>.
+    Copyright 2015, the Apache Software Foundation.
+    Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>
+</p>
+</body>
+</html>
\ No newline at end of file

Modified: steve/trunk/pysteve/www/htdocs/css/steve_interactive.css
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/www/htdocs/css/steve_interactive.css?rev=1669022&r1=1669021&r2=1669022&view=diff
==============================================================================
--- steve/trunk/pysteve/www/htdocs/css/steve_interactive.css (original)
+++ steve/trunk/pysteve/www/htdocs/css/steve_interactive.css Tue Mar 24 23:26:33 2015
@@ -345,6 +345,30 @@ pre {
     -khtml-user-drag: element;
 }
 
+.ballotbox_clist_DH {
+    border: 1px dotted #666;
+    padding: 4px;
+    max-width: 410px;
+    min-height: 25px;
+    cursor: pointer;
+    font-family: monospace;
+    font-size: 16px;
+    background: linear-gradient(to bottom, #f8f8f8 0%,#dddddd 100%);
+    -khtml-user-drag: element;
+}
+
+.ballotbox_clist_selectedDH {
+    border: 1px dotted #666;
+    padding: 4px;
+    max-width: 410px;
+    min-height: 25px;
+    cursor: pointer;
+    font-family: monospace;
+    font-size: 16px;
+    background: linear-gradient(to bottom, #a8f8a8 0%,#adddad 100%);
+    -khtml-user-drag: element;
+}
+
 .statement_marker {
     border: 1px dotted #666;
     padding: 4px;

Added: steve/trunk/pysteve/www/htdocs/js/steve_dh.js
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/www/htdocs/js/steve_dh.js?rev=1669022&view=auto
==============================================================================
--- steve/trunk/pysteve/www/htdocs/js/steve_dh.js (added)
+++ steve/trunk/pysteve/www/htdocs/js/steve_dh.js Tue Mar 24 23:26:33 2015
@@ -0,0 +1,203 @@
+var step = -1
+var election_data;
+var vote_DH = null;
+
+var candidates;
+var chars;
+
+// A little shuffle, so we don't all get the same order at first
+function shuffleCandidates() {
+    for (var i = 0; i < candidates.length; i++) {
+        
+        // Pick some numbers
+        var sid = parseInt(Math.random()*candidates.length-0.01);
+        var did = parseInt(Math.random()*candidates.length-0.01);
+        
+        // Splice!
+        if (sid >= 0 && did >= 0) {
+            candidates.splice(did, 0, candidates.splice(sid, 1)[0])
+            chars.splice(did, 0, chars.splice(sid, 1)[0])
+        }
+    }
+}
+
+function loadIssue(election, issue, uid, callback) {
+	
+	var messages = ["Herding cats...", "Shaving yaks...", "Shooing some cows away...", "Fetching election data...", "Loading issues..."]
+	if (!election || !uid) {
+		var l = document.location.search.substr(1).split("/");
+		election = l[0];
+		issue = l.length > 1 ? l[l.length-2] : "";
+		uid = l.length > 2 ? l[l.length-1] : "";
+	}
+	if (step == -1) {
+		getJSON("/steve/voter/view/" + election + "/" + issue + "?uid=" + uid, [election, issue, uid], callback)
+	}
+	
+	var obj = document.getElementById('preloader');
+	step++;
+	if (!election_data && obj) {
+		if (step % 2 == 1) obj.innerHTML = messages[parseInt(Math.random()*messages.length-0.01)]
+	} else if (obj && (step % 2 == 1)) {
+		obj.innerHTML = "Ready..!"
+	}
+	if (step % 2 == 1) {
+		obj.style.transform = "translate(0,0)"
+	} else if (obj) {
+		obj.style.transform = "translate(0,-500%)"
+	}
+	if (!election_data|| (step % 2 == 0) ) {
+		window.setTimeout(loadElection, 750, election, uid, callback);
+	}
+}
+
+
+function drawCandidatesDH() {
+    var box = document.getElementById('candidates')
+    box.innerHTML = "<h3>Candidates:</h3>"
+    for (i in candidates) {
+        var name = candidates[i]
+        var char = chars[i]
+        // Add element and set drag'n'drop + data
+        var li = document.createElement('li')
+        var outer = document.createElement('div')
+        var inner = document.createElement('span')
+        inner.style.fontFamily = "monospace"
+        inner.innerHTML = char + ": " + name;
+        inner.setAttribute("ondrop", "dropCandidate(event, true)")
+        outer.setAttribute("class", "ballotbox_clist_DH")
+        if (char == vote_DH) {
+            outer.setAttribute("class", "ballotbox_clist_selectedDH")
+        }
+        outer.setAttribute("id", name)
+        outer.setAttribute("onclick", "vote_DH = '"+char+"'; drawCandidatesDH();")
+        outer.appendChild(inner)
+        outer.setAttribute("title", "Click to select "  + name + " as your preference")
+        li.appendChild(outer)
+        // Does the candidate have a statement? if so, put it on there
+        if (statements[char]) {
+            var statement = document.createElement('div')
+            statement.setAttribute("class", "statement_marker")
+            statement.setAttribute("title", "Click to read " + name + "'s statement")
+            statement.innerHTML = "<a href='#statement_"+char+"'>Statement</a>"
+
+            li.appendChild(statement)
+            
+            var popup = document.createElement("div")
+            popup.setAttribute("class", "modal")
+            popup.setAttribute("id", "statement_" + char)
+            popup.setAttribute("aria-hidden", "true")
+            
+            var popupd = document.createElement("div")
+            popupd.setAttribute("class", "modal-dialog")
+            popup.appendChild(popupd)
+            
+            var popuph = document.createElement("div")
+            popuph.setAttribute("class", "modal-header")
+            popuph.innerHTML = '<h2>Statement from ' + name + '</h2><a href="#close" class="btn-close" aria-hidden="true">×</a>'
+            
+            var popupb = document.createElement("div")
+            popupb.setAttribute("class", "modal-body")
+            popupb.innerHTML = '<pre>' + (statements[char] ? statements[char] : "This candidate has not prepared a statement") +'</pre>'
+            
+            var popupf = document.createElement("div")
+            popupf.setAttribute("class", "modal-footer")
+            popupf.innerHTML = '<a href="#close" class="btn">Close statement</a>'
+            
+            popupd.appendChild(popuph)
+            popupd.appendChild(popupb)
+            popupd.appendChild(popupf)
+            
+            document.getElementsByTagName('body')[0].appendChild(popup)
+        }/* else {
+            var statement = document.createElement('div')
+            statement.setAttribute("class", "statement_marker")
+            statement.style = "background: linear-gradient(to bottom, #e2e2e2 0%,#dbdbdb 50%,#d1d1d1 51%,#fefefe 100%) !important;"
+            statement.style.color = "#666";
+            statement.innerHTML = "<i>No statement</i>"
+
+            outer.appendChild(statement)
+        }*/
+        box.appendChild(li)
+        
+    }
+}
+
+function displayIssueDH(code, response, state) {
+    chars = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']  // Corresponding STV letters, in same order as nominees
+    election_data = response
+    if (code != 200) {
+        document.getElementById('preloaderWrapper').innerHTML = "<h1>Could not load issue:</h1><h2>" + response.message + "</h2>";
+    } else {
+        candidates = []
+        statements = {}
+        var m = response.issue.type.match(/(\d+)/);
+        if (m) {
+            seats = parseInt(m[1])
+        }
+        for (c in response.issue.candidates) {
+            var candidate = response.issue.candidates[c];
+            candidates.push(candidate.name);
+            statements[chars[c]] = candidate.statement;
+        }
+        document.getElementById('cnum').innerHTML = candidates.length
+        document.getElementById('snum').innerHTML = seats        
+        while (chars.length > candidates.length) chars.splice(-1,1)
+        
+        
+        var obj = document.getElementById('preloaderWrapper')
+        obj.innerHTML = ""
+        obj.setAttribute("style", "min-width: 100%; min-height: 400px;")
+        obj.setAttribute("id", "votebox")
+        
+        
+        var l = document.createElement('ol')
+        l.setAttribute("id", "candidates")
+        obj.appendChild(l)
+        
+        shuffleCandidates();
+        drawCandidatesDH();
+        
+        
+        var vote = document.createElement('input')
+        vote.setAttribute("type", "button")
+        vote.setAttribute("class", "btn-green")
+        vote.setAttribute("value", "Cast vote")
+        vote.setAttribute("onclick", "castVoteDH();")
+        
+        
+        obj.appendChild(vote)
+        
+        document.getElementById('title').innerHTML = response.issue.title
+        document.title = response.issue.title + " - Apache STeVe"
+        
+    }
+    
+}
+
+function castVoteDH() {
+    var l = document.location.search.substr(1).split("/");
+    election = l[0];
+    issue = l.length > 1 ? l[l.length-2] : "";
+    uid = l.length > 2 ? l[l.length-1] : "";
+    if (vote_DH) {
+        postREST("/steve/voter/vote/" + election + "/" + issue, {
+            uid: uid,
+            vote: vote_DH
+        },
+        undefined,
+        DHVoteCallback,
+        null)
+    } else {
+        alert("Please select a preference first!")
+    }
+    
+}
+
+function DHVoteCallback(code, response, state) {
+    if (code != 200) {
+        alert(response.message)
+    } else {
+        document.getElementById('votebox').innerHTML = "<h2>Your vote has been registered!</h2><p style='text-align:center;'><big>Should you reconsider, you can always reload this page and vote again.<br/><br/><a href=\"javascript:void(location.href='election.html'+document.location.search);\">Back to election front page</a></big></p>"
+    }
+}
\ No newline at end of file

Modified: steve/trunk/pysteve/www/htdocs/js/steve_rest.js
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/www/htdocs/js/steve_rest.js?rev=1669022&r1=1669021&r2=1669022&view=diff
==============================================================================
--- steve/trunk/pysteve/www/htdocs/js/steve_rest.js (original)
+++ steve/trunk/pysteve/www/htdocs/js/steve_rest.js Tue Mar 24 23:26:33 2015
@@ -414,6 +414,31 @@ function renderEditIssue(code, response,
 			div.appendChild(btn)
 			obj.appendChild(div)
 			renderEditCandidates()
+		} else if (edit_i.type.match(/^dh/)) {
+			
+			// base data
+			obj.innerHTML = "<h3>Editing a D'Hondt (" + edit_i.type.toUpperCase() + ") issue</h3>"
+			obj.appendChild(keyvaluepair("id", "Issue ID:", "text", edit_i.id, true))
+			obj.appendChild(keyvaluepair("ititle", "Issue title:", "text", edit_i.title))
+			obj.appendChild(keyvaluepair("description", "Description (optinal):", "textarea", edit_i.description))
+			obj.appendChild(document.createElement('hr'))
+			
+			// candidates
+			var cobj = document.createElement('div')
+			cobj.setAttribute("id", "candidateList")
+			cobj.setAttribute("class", "candidateEditList")
+			obj.appendChild(cobj)
+			
+			var div = document.createElement('div')
+			div.setAttribute("class", "keyvaluepair")
+			var btn = document.createElement('input')
+			btn.setAttribute("type", "button")
+			btn.setAttribute("class", "btn-green")
+			btn.setAttribute("value", "Save changes")
+			btn.setAttribute("onclick", "saveSTV();")
+			div.appendChild(btn)
+			obj.appendChild(div)
+			renderEditCandidates()
 		}
 	} else {
 		alert(response.message)