fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2011-05-12 08:17 am

[dw-free] jQuerify polls

[commit: http://hg.dwscoalition.org/dw-free/rev/91b163585ba8]

http://bugs.dwscoalition.org/show_bug.cgi?id=3660

Move poll JS over to jQuery. Improves handling of polls fetched via JS
(e.g., in cuts). Fixes a bug in pagination for no-JS mode.

Patch by [personal profile] fu.

Files modified:
  • cgi-bin/DW/BetaFeatures/journaljquery.pm
  • cgi-bin/LJ/Poll.pm
  • cgi-bin/LJ/Poll/Question.pm
  • cgi-bin/LJ/S2.pm
  • htdocs/js/jquery.ajaxtip.js
  • htdocs/js/jquery.cuttag-ajax.js
  • htdocs/js/jquery.poll.js
--------------------------------------------------------------------------------
diff -r 140d9d51b8df -r 91b163585ba8 cgi-bin/DW/BetaFeatures/journaljquery.pm
--- a/cgi-bin/DW/BetaFeatures/journaljquery.pm	Mon May 09 19:15:09 2011 +0800
+++ b/cgi-bin/DW/BetaFeatures/journaljquery.pm	Thu May 12 16:17:09 2011 +0800
@@ -24,12 +24,12 @@
         "Control strip injection for non-supporting journals",
         "Quick reply",
         "Thread expander",
+        "Same-page poll submission",
     );
 
     my @notimplemented = (
         "Contextual hover",
         "Media embed placeholder expansion",
-        "Same-page poll submission",
         "Icon browser",
         "Same-page comment tracking",
     );
diff -r 140d9d51b8df -r 91b163585ba8 cgi-bin/LJ/Poll.pm
--- a/cgi-bin/LJ/Poll.pm	Mon May 09 19:15:09 2011 +0800
+++ b/cgi-bin/LJ/Poll.pm	Thu May 12 16:17:09 2011 +0800
@@ -870,6 +870,9 @@
         LJ::Poll->clean_poll(\$text);
         $ret .= $text;
         $ret .= '<div>' . $q->answers_as_html($self->journalid, $self->isanon, $page, $pagesize) . '</div>';
+
+        my $pages    = $q->answers_pages($self->journalid, $pagesize);
+        $ret .= '<div>' . $q->paging_bar_as_html($page, $pages, $pagesize, $self->journalid, $pollid, $qid, no_class => 1) . '</div>';
         return $ret;
     }
 
@@ -885,6 +888,7 @@
 
     my %preval;
 
+    $ret .= qq{<div id='poll-$pollid-container' class='poll-container'>};
     if ( $do_form ) {
         $sth = $self->journal->prepare( "SELECT pollqid, value FROM pollresult2 WHERE pollid=? AND userid=? AND journalid=?" );
         $sth->execute( $pollid, $remote->userid, $self->journalid );
@@ -894,7 +898,7 @@
         }
 
         my $url = LJ::create_url( "/poll/", host => $LJ::DOMAIN_WEB, viewing_style => 1, args => { id => $pollid } );
-        $ret .= "<div id='poll-$pollid-container'><form class='LJ_PollForm' action='$url' method='post'>";
+        $ret .= "<form class='LJ_PollForm' action='$url' method='post'>";
         $ret .= LJ::form_auth();
         $ret .= LJ::html_hidden('pollid', $pollid);
         $ret .= LJ::html_hidden('id', $pollid);    #for the ajax request
@@ -1170,8 +1174,9 @@
         $ret .= LJ::html_submit(
                                 'poll-submit',
                                 LJ::Lang::ml('poll.submit'),
-                                {class => 'LJ_PollSubmit'}) . "</form></div>\n";;
+                                {class => 'LJ_PollSubmit'}) . "</form>";
     }
+    $ret .= "</div>";
 
     return $ret;
 }
diff -r 140d9d51b8df -r 91b163585ba8 cgi-bin/LJ/Poll/Question.pm
--- a/cgi-bin/LJ/Poll/Question.pm	Mon May 09 19:15:09 2011 +0800
+++ b/cgi-bin/LJ/Poll/Question.pm	Thu May 12 16:17:09 2011 +0800
@@ -314,11 +314,13 @@
     my $pages =  shift      || 1;
     my $pagesize = shift    || 2000;
 
-    my ($jid, $pollid, $pollqid) = @_;
+    my ($jid, $pollid, $pollqid, %opts) = @_;
 
     my $href_opts = sub {
         my $page = shift;
-        return  " class='LJ_PollAnswerLink'".
+        # FIXME: this is a quick hack to disable the paging JS on /poll/index since it doesn't work
+        # better fix will await another look at that whole area
+        return  ( $opts{no_class} ? "" : " class='LJ_PollAnswerLink'" ) .
                 " lj_pollid='$pollid'".
                 " lj_qid='$pollqid'".
                 " lj_posterid='$jid'".
diff -r 140d9d51b8df -r 91b163585ba8 cgi-bin/LJ/S2.pm
--- a/cgi-bin/LJ/S2.pm	Mon May 09 19:15:09 2011 +0800
+++ b/cgi-bin/LJ/S2.pm	Thu May 12 16:17:09 2011 +0800
@@ -191,7 +191,14 @@
         # used if we're using our jquery library
         LJ::need_res( { group => "jquery" }, qw(
                         js/md5.js
+
+                        js/jquery.ajaxtip.js
+                        js/tooltip.js
+                        js/tooltip.dynamic.js
+                        stc/ajaxtip.css
+
                         js/login-jquery.js
+                        js/jquery.poll.js
                     ) );
     }
 
diff -r 140d9d51b8df -r 91b163585ba8 htdocs/js/jquery.ajaxtip.js
--- a/htdocs/js/jquery.ajaxtip.js	Mon May 09 19:15:09 2011 +0800
+++ b/htdocs/js/jquery.ajaxtip.js	Thu May 12 16:17:09 2011 +0800
@@ -25,6 +25,7 @@
                 delay: 1500,
                 events: {
                     def: "ajaxstart"+ns+",ajaxresult"+ns,
+                    widget: "ajaxstart"+ns+",ajaxresult"+ns,
                     tooltip: "mouseover,mouseleave"
                 },
                 position: "bottom center",
@@ -49,6 +50,13 @@
         if(this.options.content)
             this.element.data("tooltip").show()
     },
+    _endpointurl : function( action ) {
+        // if we are on a journal subdomain then our url will be
+        // /journalname/__rpc_action instead of /__rpc_action
+        return Site.currentJournal
+            ? "/" + Site.currentJournal + "/__rpc_" + action
+            : "/__rpc_" + action;
+    },
     widget: function() {
         return this.element.data("tooltip").getTip();
     },
@@ -70,12 +78,13 @@
 
         $.ajax({
             type: "POST",
-            url : opts.url,
+            url : opts.endpoint ? self._endpointurl( opts.endpoint) : opts.url,
             data: opts.data,
 
             dataType: "json",
             complete: function() {
-                self.element.data("tooltip").inprogress = false;
+                var tip = self.element.data("tooltip");
+                if ( tip ) tip.inprogress = false;
             },
             success: opts.success,
             error: opts.error
diff -r 140d9d51b8df -r 91b163585ba8 htdocs/js/jquery.cuttag-ajax.js
--- a/htdocs/js/jquery.cuttag-ajax.js	Mon May 09 19:15:09 2011 +0800
+++ b/htdocs/js/jquery.cuttag-ajax.js	Thu May 12 16:17:09 2011 +0800
@@ -131,6 +131,7 @@
             self.element.addClass("cuttag-open");
             self._setArrow("/expand.gif", self.config.text.collapse);
 
+            replaceDiv.trigger( "updatedcontent.entry" );
             $.dw.cuttag.initLinks(replaceDiv);
         }
     }
diff -r 140d9d51b8df -r 91b163585ba8 htdocs/js/jquery.poll.js
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/js/jquery.poll.js	Thu May 12 16:17:09 2011 +0800
@@ -0,0 +1,133 @@
+(function($){
+
+$.widget("dw.dynamicpoll", {
+    _init: function() {
+        this._initForm();
+        this._initResults();
+    },
+    _initResults: function() {
+        var self = this;
+        var $results = self.element.children(":not(form.LJ_PollForm)");
+        if ( $results.length == 0 ) return;
+
+        $results.find("a.LJ_PollAnswerLink").click(function(e){
+            e.stopPropagation();
+            e.preventDefault();
+
+            var $clicked = $(this);
+            var pollid = $clicked.attr("lj_pollid");
+            var pollqid = $clicked.attr("lj_qid");
+
+            if ( ! pollid || ! pollqid ) return;
+
+            $clicked
+            .ajaxtip({namespace: "pollanswer"})
+            .ajaxtip("load", {
+                endpoint: "poll",
+                data: {
+                    pollid  : pollid,
+                    pollqid : pollqid,
+                    page    : $clicked.attr("lj_page"),
+                    pagesize: $clicked.attr("lj_pagesize"),
+                    action  : "get_answers"
+                },
+                success: function( data, status, jqxhr ) {
+                    if ( data.error ) {
+                        $clicked.ajaxtip( "error", data.error )
+                    } else {
+                        var pollid = data.pollid;
+                        var pollqid = data.pollqid;
+                        if ( ! pollid || ! pollqid ) {
+                            $clicked.ajaxtip( "error", "Error fetching poll results." );
+                        } else {
+                            $clicked.ajaxtip( "cancel" );
+
+                            var page = data.page;
+
+                            var $pageEle;
+                            var $answerEle;
+
+                            if ( page ) {
+                                $pageEle = $clicked.closest("div.lj_pollanswer_paging");
+                                $answerEle = $pageEle.prev("div.lj_pollanswer");
+                            } else {
+                                $pageEle = $("<div class='lj_pollanswer_paging'></div>");
+                                $answerEle = $("<div class='lj_pollanswer'></div>");
+
+                                $clicked.after($answerEle,$pageEle).remove();
+                            }
+                            $pageEle.html( data.paging_html || "" );
+                            $answerEle.html( data.answer_html || "(No answers)" );
+
+                            $pageEle.trigger( "updatedcontent.poll" );
+                            $answerEle.trigger( "updatedcontent.poll" );
+                        }
+                    }
+
+                    self._trigger( "complete" );
+                },
+                error: function( jqxhr, status, error ) {
+                    $clicked.ajaxtip( "error", "Error contacting server. " + error);
+                    self._trigger( "complete" );
+                }
+            });
+        });
+    },
+    _initForm: function() {
+        var self = this;
+        var $poll = self.element.children("form.LJ_PollForm");
+        if ( $poll.length == 0 ) return;
+
+        $poll.find("input.LJ_PollSubmit").click(function(e){
+            e.preventDefault();
+            e.stopPropagation();
+
+            var $submit = $(this);
+            $submit.ajaxtip({namespace: "pollsubmit"})
+                .ajaxtip("load", {
+                    endpoint: "pollvote",
+                    data: $poll.serialize(),
+                    success: function( data, status, jqxhr ) {
+                        if ( data.error ) {
+                            $submit.ajaxtip( "error", data.error )
+                        } else {
+                            $submit.ajaxtip( "cancel" );
+                            var resultsEle = $(data.results_html);
+                            self.element.empty().append(resultsEle);
+
+                            resultsEle.trigger( "updatedcontent.poll" );
+                        }
+                        self._trigger( "complete" );
+                    },
+                    error: function( jqxhr, status, error ) {
+                        $submit.ajaxtip( "error", "Error contacting server. " + error);
+                        self._trigger( "complete" );
+                    }
+                });
+        });
+
+        $poll.find(".LJ_PollClearLink").click(function(e){
+            e.stopPropagation();
+            e.preventDefault();
+
+            $poll.find("input").each(function(){
+                if ( this.type == "text" )
+                    this.value = "";
+                else if ( this.type == "radio" || this.type == "checkbox" )
+                    this.checked = false;
+                // don't touch hidden and submit
+            });
+            $poll.find("select").each(function() { this.selectedIndex = 0 });
+        });
+    }
+});
+
+})(jQuery);
+
+jQuery(document).ready(function($){
+    $(".poll-container").dynamicpoll()
+    $(document.body).delegate("*", "updatedcontent.entry.poll", function(e) {
+        e.stopPropagation();
+        $(this).find(".poll-container").andSelf().dynamicpoll();
+    });
+});
--------------------------------------------------------------------------------