[dw-free] AJAXify polls
[commit: http://hg.dwscoalition.org/dw-free/rev/677ac59981c5]
http://bugs.dwscoalition.org/show_bug.cgi?id=1590
Submit poll results without reloading the page.
Patch by
jportela.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=1590
Submit poll results without reloading the page.
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Files modified:
- cgi-bin/LJ/Poll.pm
- cgi-bin/ljdefaults.pl
- htdocs/js/livejournal.js
- htdocs/tools/endpoints/pollvote.bml
-------------------------------------------------------------------------------- diff -r 1feed31d5892 -r 677ac59981c5 cgi-bin/LJ/Poll.pm --- a/cgi-bin/LJ/Poll.pm Tue Sep 07 10:56:35 2010 +0800 +++ b/cgi-bin/LJ/Poll.pm Tue Sep 07 11:08:22 2010 +0800 @@ -881,9 +881,10 @@ sub render { $preval{$qid} = $value; } - $ret .= "<form action='$LJ::SITEROOT/poll/?id=$pollid' method='post'>"; + $ret .= "<div id='poll-$pollid-container'><form class='LJ_PollForm' action='$LJ::SITEROOT/poll/?id=$pollid' method='post'>"; $ret .= LJ::form_auth(); $ret .= LJ::html_hidden('pollid', $pollid); + $ret .= LJ::html_hidden('id', $pollid); #for the ajax request } $ret .= "<b><a href='$LJ::SITEROOT/poll/?id=$pollid'>" . LJ::Lang::ml('poll.pollnum', { 'num' => $pollid }) . "</a></b> "; @@ -1120,7 +1121,7 @@ sub render { $ret .= LJ::html_submit( 'poll-submit', LJ::Lang::ml('poll.submit'), - {class => 'LJ_PollSubmit'}) . "</form>\n";; + {class => 'LJ_PollSubmit'}) . "</form></div>\n";; } return $ret; diff -r 1feed31d5892 -r 677ac59981c5 cgi-bin/ljdefaults.pl --- a/cgi-bin/ljdefaults.pl Tue Sep 07 10:56:35 2010 +0800 +++ b/cgi-bin/ljdefaults.pl Tue Sep 07 11:08:22 2010 +0800 @@ -272,6 +272,7 @@ no strict "vars"; trans_save => "tools/endpoints/trans_save.bml", dirsearch => "tools/endpoints/directorysearch.bml", poll => "tools/endpoints/poll.bml", + pollvote => "tools/endpoints/pollvote.bml", jobstatus => "tools/endpoints/jobstatus.bml", widget => "tools/endpoints/widget.bml", multisearch => "tools/endpoints/multisearch.bml", diff -r 1feed31d5892 -r 677ac59981c5 htdocs/js/livejournal.js --- a/htdocs/js/livejournal.js Tue Sep 07 10:56:35 2010 +0800 +++ b/htdocs/js/livejournal.js Tue Sep 07 11:08:22 2010 +0800 @@ -200,6 +200,107 @@ LiveJournal.initPolls = function () { Array.prototype.forEach.call(pollLinks, function (pollLink) { DOM.addEventListener(pollLink, "click", LiveJournal.pollAnswerLinkClicked.bindEventListener(pollLink)); }); + + var pollButtons = DOM.getElementsByTagAndClassName(document, 'input', "LJ_PollSubmit") || []; + + // attaches a click handler to all poll submit buttons + Array.prototype.forEach.call(pollButtons, function (pollButton) { + DOM.addEventListener(pollButton, "click", LiveJournal.pollButtonClicked.bindEventListener(pollButton)); + }); + + var pollForms = DOM.getElementsByTagAndClassName(document, 'form', "LJ_PollForm") || []; + + // attach submit handlers to each poll form + Array.prototype.forEach.call(pollForms, function (pollForm) { + DOM.addEventListener(pollForm, "submit", LiveJournal.pollFormSubmitted.bindEventListener(pollForm)); + }); +}; + +LiveJournal.pollButtonClicked = function (e) { + // shows the hourglass. The submit event wouldn't update the coordinates, so the click event + // had to be used for this + if (!PollPages.hourglass) { + var coords = DOM.getAbsoluteCursorPosition(e); + PollPages.hourglass = new Hourglass(); + PollPages.hourglass.init(); + PollPages.hourglass.hourglass_at(coords.x, coords.y+25); // 25 is added to the y axis, otherwise the button would cover it + PollPages.e = e; + } + + return true; +}; + +LiveJournal.pollFormSubmitted = function (e) { + Event.stop(e); + + var formObject = LiveJournal.getFormObject(this); //gets the form ready for serialization + + var opts = { + "url" : LiveJournal.getAjaxUrl("pollvote"), + "method" : "POST", + "data" : HTTPReq.formEncoded(formObject), + "onData" : LiveJournal.pollVoteSubmitted, + "onError": LiveJournal.pollVoteSubmitted + }; + + HTTPReq.getJSON(opts); + + return false; +}; + +LiveJournal.pollVoteSubmitted = function (results) { + if (! results) return false; + + if (PollPages.hourglass) { + PollPages.hourglass.hide(); + PollPages.hourglass = null; + } + + if (results.error) return LiveJournal.ajaxError(results.error); + + resultsDiv = document.getElementById("poll-"+results.pollid+"-container"); + + resultsDiv.innerHTML = results.results_html; + + LiveJournal.initPolls(); +}; + +LiveJournal.getFormObject = function (form) { + + var inputs = form.getElementsByTagName("input"); + + var formObject = new Object(); + + for (var i = 0; i < inputs.length; i++) { + var obj = inputs[i]; + + if (obj.type == "checkbox") { + if (!formObject[obj.name]) { + formObject[obj.name] = new Array(); + } + if (obj.checked) + formObject[obj.name].push(obj.value); + } + else if (obj.type == "radio") { + if (obj.checked) { + formObject[obj.name] = obj.value; + } + } + else + { + formObject[obj.name] = obj.value; + } + } + + var selects = form.getElementsByTagName("select"); + + for (var i = 0; i < selects.length; i++) { + var sel = selects[i]; + formObject[sel.name] = sel.options[sel.selectedIndex].value; + } + + return formObject; + }; // invocant is the pollLink from above diff -r 1feed31d5892 -r 677ac59981c5 htdocs/tools/endpoints/pollvote.bml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htdocs/tools/endpoints/pollvote.bml Tue Sep 07 11:08:22 2010 +0800 @@ -0,0 +1,89 @@ +<?_c +# +# /tools/endpoints/pollvote.bml +# +# Submits a poll vote using AJAX, rendering the results +# +# Authors: +# Joao Portela <agnorpt@gmail.com> +# +# Copyright (c) 2010 by Dreamwidth Studios, LLC. +# +# This program is free software; you may redistribute it and/or modify it under +# the same terms as Perl itself. For a copy of the license, please reference +# 'perldoc perlartistic' or 'perldoc perlgpl'. +# +_c?> +<?_code # -*-bml-*- +{ + use strict; + use vars qw(%POST); + use JSON; + + my $ret = {}; + + my $err = sub { + my $msg = shift; + return JSON::objToJson({ + error => "Error: $msg", + }); + }; + + BML::set_content_type('text/javascript; charset=utf-8'); + BML::finish(); + BML::noparse(); + + foreach (values %POST) { + s/\0/,/g; + } + + my $remote = LJ::get_remote(); + + my $pollid = $POST{pollid} or return $err->("No pollid"); + + my $poll = LJ::Poll->new($pollid); + + unless ($poll && $poll->valid) { + return $err->("Poll not found"); + } + + my $u = $poll->journal; + + # load the item being shown + my $entry = $poll->entry; + unless ($entry) { + return $err->("Post was deleted"); + } + + unless ($entry->visible_to($remote)) { + return $err->("You don't have the permissions to view this poll"); + } + + unless (LJ::did_post()) { + return $err->("Post is required"); + } + + unless (LJ::check_form_auth()) { + return $err->("Form is invalid"); + } + + my $error; + LJ::Poll->process_submission(\%POST, \$error); + if ($error) { + return $err->($error); + } + + $ret->{results_html} = $poll->render(mode => "results"); + + $ret = { + %$ret, + pollid => $pollid + }; + + sleep(1.5) if $LJ::IS_DEV_SERVER; + + return LJ::js_dumper($ret); +} + +_code?> + --------------------------------------------------------------------------------
no subject
no subject
no subject
no subject
no subject