Commit a5eef67a authored by Matthias Folz's avatar Matthias Folz
Browse files

added better ajax handling

parent ebfcebb0
Silk icon set 1.3
_________________________________________
Mark James
http://www.famfamfam.com/lab/icons/silk/
_________________________________________
This work is licensed under a
Creative Commons Attribution 2.5 License.
[ http://creativecommons.org/licenses/by/2.5/ ]
This means you may use it for any purpose,
and make any changes you like.
All I ask is that you include a link back
to this page in your credits.
Are you using this icon set? Send me an email
(including a link or picture if available) to
mjames@gmail.com
Any other questions about this icon set please
contact mjames@gmail.com
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>Vote</title>
<link href="css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<head>
<title>Vote</title>
<style>
</style>
<script src="js/client.js" crossorigin="anonymous"></script>
</head>
<body>
<div class="container-lg">
<table class="table table-striped">
<tbody id="content">
<link rel="icon" type="image/png" href="img/email_open.png" sizes="32x32">
<link href="css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style>
body{
transition: 0.3s;
}
body.loading {
transition: 0.3s;
filter: blur(4px);
}
img.modalIcon {
padding-bottom: 5px;
}
</style>
</head>
<body>
<div class="container-lg">
<table class="table table-striped">
<tbody id="content">
<tr class="table-primary">
<td>loading...</td>
</tr>
</tbody>
</table>
<div>
<script src="js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<script src="js/jquery-3.6.0.min.js" crossorigin="anonymous"></script>
<script>
const BASE = getBaseUrl();
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
renderCandidates(xhr.responseText);
}
}
xhr.open("GET", BASE+"/candidates", true);
xhr.send(null);
</script>
</body>
</tbody>
</table>
<div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Error</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="staticBackdropBody">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<script src="js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<script src="js/jquery-3.6.0.min.js" crossorigin="anonymous"></script>
<script src="js/client.js" crossorigin="anonymous"></script>
</body>
</html>
......@@ -2,6 +2,20 @@
var currentVotes = "";
const VOTE_CHARS = ["-", "0", "+"];
const BASE = getBaseUrl();
$(document).ready(function() {
initialize();
})
function initialize() {
$("body").addClass("loading");
$.get(BASE+"/candidates").done(function(data) {
renderCandidates(data);
}).fail(handleRequestError).always(function() {
$("body").removeClass("loading");
})
}
function setCharAt(str,index,chr) {
if(index > str.length-1) return str;
......@@ -39,25 +53,30 @@ function renderCandidates(responseText) {
}
function requestVotes(uuid) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
renderVotes(xhr.responseText);
}
}
xhr.open("GET", BASE+"/votes/"+uuid, true);
xhr.send(null);
$.get(BASE+"/votes/" + uuid).done(function(data) {
renderVotes(data)
}).fail(handleRequestError).always(function() {
$("body").removeClass("loading");
})
}
function transmit() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
window.location.reload(false);
}
}
xhr.open("POST", BASE+"/vote/"+getUuid(), true);
xhr.send(currentVotes);
function transmit(event) {
$("body").addClass("loading");
$.post(
BASE+"/vote/"+getUuid(),
currentVotes
).done(function() {
initialize()
openModal(
$("<img />", {
class: "modalIcon",
src: 'img/accept.png'
}).add($("<span/>", {text: "Success"})),
"votes registered"
)
}).fail(handleRequestError).always(function() {
$("body").removeClass("loading");
})
}
function onBtnClick(event) {
......@@ -106,6 +125,23 @@ function renderVotes(votes) {
$("button.transmit").on("click", transmit);
}
function handleRequestError(jqXHR, textStatus, errorThrown) {
openModal(
$("<img />", {
class: "modalIcon",
src: 'img/exclamation.png'
}).add($("<span/>", {text: "Got an Error"})),
jqXHR.responseText
)
}
function openModal(title,body) {
$("#staticBackdropLabel").html(title)
$("#staticBackdropBody").html(body)
new bootstrap.Modal($('#staticBackdrop')).show()
}
function getBaseUrl() {
let base = window.location.href;
let search = window.location.search;
......
......@@ -21,6 +21,7 @@ async fn main() -> tide::Result<()> {
app.at("/").serve_file("client/index.html");
app.at("/css").serve_dir("client/css/")?;
app.at("/js").serve_dir("client/js/")?;
app.at("/img").serve_dir("client/img/")?;
app.with(tide::utils::After(|mut res: tide::Response| async {
if res.error().is_some() {
......@@ -34,7 +35,7 @@ async fn main() -> tide::Result<()> {
}
async fn get_candidates(_req: Request<()>) -> tide::Result {
Ok(CANDIDATES_STR.as_str().into())
Ok(CANDIDATES_STR.as_str().trim_end().into())
}
async fn get_current_votes(uuid: &str) -> Option<String> {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment