Newscoop 3 Cookbook

Using polls with AJAX

In this chapter you will find an advanced way to use the polls provided with Newscoop. Using AJAX and jQuery, the user interaction becomes smooth, and no visible page reload is required to add a vote and display the poll results. Any modern jQuery version does the trick, and needs to be called in the header of the page. You can find the documentation of the original templates on the Sourcefabric website, in the wiki.

First, we will need to list the current Poll, in our case, the latest one. When loading the page, no poll action has happened yet (meaning: voting) so we display the poll. And most importantly, a DIV container should be defined, which will be used to send and receive data via AJAX.

{{list_polls length="1" order="bynumber desc"}}
{{if !$gimme->poll_action->defined}}
  <p class="title">Poll of the day</p>
  <p class="poll-question">{{$gimme->poll->question}}</p>
  <div id="poll" class="poll">
{{/if}}
...

Next we need to check if the poll is still open to votes, and if no data is sent yet. We do not use a submit_button, as the data will be sent by an AJAX call.

{{if $gimme->poll->is_votable && !$gimme->poll_action->defined}}
 {{poll_form template="poll.tpl" submit_button=false}}
  {{list_poll_answers order="byOrder asc"}}
    {{pollanswer_edit}}{{$gimme->pollanswer->answer}}<br />
  {{/list_poll_answers}}
 <input type="submit" id="submit_poll" class="button" value="I think so!" />
 {{/poll_form}}
...

The same template is used to provide output, if the data was sent by the user.

{{else}}
  <p>Voted: {{$gimme->poll->votes}}</p>
  {{list_poll_answers order="byOrder asc"}}
    <div class="answer">{{$gimme->pollanswer->percentage|string_format:"%d"}}%: {{ $gimme->pollanswer->answer }}
      <div style="width:{{$gimme->pollanswer->percentage|string_format:"%d"}}%;background:#5d4040;">&nbsp;</div>
    </div>
  {{/list_poll_answers}}
{{/if}}

And finally: the closing tag.

...
{{if !$gimme->poll_action->defined}}
  </div>
{{/if}}
{{/list_polls}}

The jQuery part of the code is pretty small. We use $.post to parse the form data, send it via AJAX to the server, and place the resulting output where it should be (<div id="poll">).

$(document).ready(function(){
  $('#submit_poll').click(function(){
    $.post(
      $('form[name=poll]').attr("action"),
      $('form[name=poll]').serialize(),
      function(data){$('#poll').html(data);
    });
    return false;
  });
});

Below you can see the entire template poll.tpl, which you can include in your page.

{{list_polls length="1" order="bynumber desc"}}
{{if !$gimme->poll_action->defined}}
  <p class="title">Poll of the day</p>
  <p class="poll-question">{{$gimme->poll->question}}</p>
  <div id="poll" class="poll">
{{/if}}
{{if $gimme->poll->is_votable && !$gimme->poll_action->defined}}
  {{poll_form template="poll.tpl" submit_button=false}}
  {{list_poll_answers order="byOrder asc"}}
    {{pollanswer_edit}}{{$gimme->pollanswer->answer}}<br />
  {{/list_poll_answers}}
  <input type="submit" id="submit_poll" class="button" value="I think so!" />
  {{/poll_form}}
{{else}}
  <p>Voted: {{$gimme->poll->votes}}</p>
  {{list_poll_answers order="byOrder asc"}}
    <div class="answer">{{$gimme->pollanswer->percentage|string_format:"%d"}}%: {{ $gimme->pollanswer->answer }}
      <div style="width:{{$gimme->pollanswer->percentage|string_format:"%d"}}%;background:#5d4040;">&nbsp;</div>
    </div>
  {{/list_poll_answers}}
{{/if}}
{{if !$gimme->poll_action->defined}}
  </div>
{{/if}}
{{/list_polls}}

<script type="text/javascript">
$(document).ready(function(){
  $('#submit_poll').click(function(){
    $.post(
      $('form[name=poll]').attr("action"),
      $('form[name=poll]').serialize(),
      function(data){$('#poll').html(data);
    });
    return false;
  });
});
</script>