If you have used Stack Overflow for a while, you surely have used the function of vote up and down of the question and answer. I notice Stack Overflow uses <a>
anchor. But I don't know how to POST the data to server. I think it's JavaScript associated with this <a>
, but I can't find it. How can I implement it?
The regular methods of voting in such bodies are a voice vote, a rising vote, and a show of hands. Additional forms of voting include a recorded vote and balloting. The assembly could decide on the voting method by adopting a motion on it. Different legislatures may have their voting methods.
Add voting buttons Create an email message or reply to or forward a message that you received. On the Options tab, in the Tracking group, click Use Voting Buttons. Use when you need an authorization for an action.
Yes, JavaScript is involved. There are two parts: Hooking up a handler for the click events on the voting "buttons", and sending data to the server.
Hooking up the events is well-covered elsewhere and I won't go into it here. (For instance, I cover it in this answer.)
Sending the data to the server, you can use ajax. On any browser that isn't completely obsolete, you can use XMLHttpRequest
:
var xhr = new XMLHttpRequest();
xhr.open("POST", "/path/to/server/destination");
xhr.onreadystatechange = handleStateChange;
xhr.send("id=" + encodeURIComponent(id) +
"&user=" + encodeURIComponent(userId) +
"&vote=up");
function handleStateChange() {
if (xhr.readyState === 4) {
// POST complete
if (xhr.status === 200) {
// POST complete and we have response, check it
if (xhr.responseText !== "ok") { // Or whatever you want it to be
// Report problem
}
} else {
// Ajax failed, handle/report problem
}
}
}
On more up-to-date browsers you can use fetch
:
var body = new FormData();
body.append("id", id);
body.append("user", userId);
body.append("vote", "up");
fetch("/path/to/server/destination", {
method: "POST",
body: body
})
.then(function(res) {
if (!res.ok) {
throw new Error("HTTP error " + res.status);
}
return res.text(); // or `res.json()` if you return JSON
})
.then(function(data) {
if (data !== "ok") { // Or whatever
// Report problem
}
})
.catch(function(error) {
// Ajax failed, handle/report problem
});
Just for fun, here's a complete example:
HTML:
<div class="article" data-itemid="427">
<a href="voteup" class="vote up" >Up</a>
<a href="votedown" class="vote down">Down</a>
<!-- ...the contents of the item... -->
</div>
JavaScript:
document.addEventListener("click", function(event) {
// Regardless of the below, we handle the event, so "consume" it
event.stopPropagation();
event.preventDefault();
// Get the anchor element
var voteLink = event.target.closest("a.vote");
if (!voteLink) {
// Didn't find one, bail
return;
}
// See if the vote has already been done or is in progress
if (voteLink.classList.contains("done") || voteLink.classList.contains("inprogress")) {
// Ignore the click, possibly tell the user why
return;
}
// Get the vote type
var voteType = voteLink.classList.contains("up") ? "up" : "down";
// Get the item we"re voting on
var item = voteLink.closest(".article");
// Get its ID
var itemId = item.getAttribute("data-itemid");
// If we didn"t get an ID...
if (!itemId) {
// ...report error
return;
}
// Mark "in progress" and initiate the vote; action continues
// in our callbacks below
voteLink.classList.add("inprogress");
var body = new FormData();
body.append("itemId", itemId);
body.append("voteType", voteType);
fetch("savevote", {
method: "POST",
body: body
})
.then(function(res) {
if (!res.ok) {
throw new Error("HTTP error " + res.status);
}
return res.text(); // or `res.json()` if you return JSON
})
.then(function(data) {
if (data === "ok") { // Or whatever
voteLink.classList.add("done");
} else {
// Report an error to the user, the server couldn"t record the vote
}
})
.catch(function(error) {
// Ajax failed, handle/report problem
})
.finally(function() {
// Not in progress anymore
voteLink.classList.remove("inprogress");
});
});
Some notes:
href
on the links (which StackOverflow doesn't have), so that if JavaScript is disabled, we can fall back to going to a page where we let the user vote using a form submission or something. Also, links with href
are treated specially by browsers (tab targets, etc.), so this is useful for accessibility. (To really do that, I'd probably have to put the article ID in the href
as well.)data-
attribute.closest
function starts with the element and examines that element to see if it fits the given CSS selector, then if not looks at its parent, then its parent, etc., until it finds a match. So the vote buttons are associated with the article by containment; the article being voted on contains the voting buttons.closest
check with a contains
check to ensure that the element the handler is attached to contains the element that was found (in case it was found in an ancestor element instead). That would be !voteLink || !this.contains(voteLink)
above (instead of just !voteLink
).Check out Ajax.
You can use jquery to do it. Just apply click eventlisteners on the up/down arrow which will send the data to your server using ajax.
The script on your server will validate the incoming data and update count in the DB. Then you can send a response back giving the updated count of ups/downs
Note : You'll also have to take into account that a user can only like or dislike once. You can either handle it at server side / or for simplicity store it in cookie.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With