BUMMZACK

Home

 

Snippet Documentation: EasyPoll 0.3.3

EasyPoll is a Module/Snippet combination for the MODx Content Management Framework

Resource Site: http://modxcms.com/EasyPoll-1873.html
Forum thread for support/feedback: http://modxcms.com/forums/index.php?topic=22981

Contents

Installation

First, you should install the EasyPoll Module for MODx. Please read the Module Documentation (also to be found in modules/EasyPoll) for installation instructions.

In the MODx Manager, create a new Snippet by navigating to: Resources > Manage Resources > Snippets. Click on "New snippet". You may use any name for the Snippet, although i encourage you to enter "EasyPoll" as Snippet name. Enter "Version 0.3.2" into the Description field.

Copy the contents of snippets/EasyPoll/snippet.php and paste them into the "Snippet code" Textarea (replace the existing content).

Dependencies

  • MODx 0.9.5, 0.9.6
    these are the versions this snippet was developed for. might work with other versions as well. Not tested though.
  • MooTools with XHR module only required when using AJAX functionality. mootools.net
  • PHP 5 or higher
  • MySQL 4.1 or higher
  • EasyPoll Module must be installed

License

The EasyPoll Module, Snippet and all included Classes/Files are licensed under the GNU General Public License, version 2. Please read the license.txt that is bundled with this software or visit: www.gnu.org/licenses/gpl-2.0.html

List of parameters

&pollid

Poll ID to be used. If not set, the snippet will choose the most recent Poll (must be active and fully translated)!
You are encouraged to omit this parameter, since it opens the possibility for you to administrate polls in the manager and have them automatically updated on your site.
defaults to false

&lang

The language to use for snippet translations. There must me a translation file for this language in the EasyPoll/lang Folder. Currently available languages: English, German, Dutch, French, Italian
defaults to 'en'

&easylang

The language for poll questions and answers (as set up in EasyPoll Module).
defaults to the &lang param

&onevote

Boolean indicating if a user is allowed to vote just once.
defaults to false

&useip

Boolean indicating if we should log the users ip to allow just one vote.
defaults to false

&ovtime

Cookie expiration time (in seconds).
defaults to one week (608400)

&noajax

Allows to disable AJAX request sending. If set to true, all added JavaScript functionality will be turned off. This is usually not required, since the Snippet also works on Browsers without JavaScript, even when this option isn't set. Only use this if you want to disable JavaScript functionality even on Browsers that would support it.
defaults to false

&css

Additional Stylesheet to load.
defaults to none/false

&accuracy

accuracy of percentage rounding. this specifies the number of digits after the decimal point.
defaults to 1

&votesorting

sorting order of the votes. This only has a effect on the vote results and archive output, not on the voting options. Options will always appear as configured in the EasyPoll Module. Valid options are: Sorting, Votes, Sorting ASC, Sorting DESC, Votes ASC, Votes DESC.
defaults to Sorting ASC

&archive

Create a poll archive instead of the regular output. Setting this parameter to true will render some of the other
parameters useless. These parameters have no meaning when setting archive to true: &pollid, &onevote, &useip, &ovtime, &tplVoteOuter, &tplVote, &tplError, &identifier, &jscallback, &noajax
The customjs parameter can be used to include JavaScript code to create special effects.
defaults to false

&skipfirst

This parameter is only effective in archive mode. If set to true, the first poll from the poll list (the one that is usually active) will be excluded from output. This way you can exclude a currently running poll from the archive output.
defaults to false

&tplVoteOuter

Outer container template for votes. Look at the Templates section for parameter details.
Default:

<div class="pollvotes">
    <h3>[+question+]</h3>
    <ul>[+choices+]</ul>
    [+submit+] [+results+]
 </div>

&tplVote

Template for a single voting option.
Default:

<li>[+select+] [+answer+]</li>

&tplResultOuter

Outer container template for results.
Default:

<div class="pollresults">
     <h3>[+question+]</h3>
     <ul>[+choices+]</ul>
     <p>[+totaltext+]: [+totalvotes+]</p>
 </div>

&tplResult

Template for a single result.
Default:

<li>
     <strong>[+answer+]</strong> ([+votes+] / [+percent+]%)
     <div class="easypoll_bar">
        <div class="easypoll_inner" style="width:[+percent_int+]%"></div>
     </div>
 </li>

&tplError

Template that is used to display a error message.
Default:

<div class="easypoll_error">[+message+]</div>

&identifier

The element identifier that is used for the JS commands. Change this to something unique every time, if you plan to use multiple polls on one page. Otherwise this can be left at its default value.
defaults to "easypoll"

&nojs

Boolean. Suppress inclusion of mootools. Use this if mootools is already included.
defaults to false

&customjs

Include a custom javascript code (eg. your custom callback function definiton). This can be a path to a JS File or a script wrapped in <script> tags. You can specify a chunk as well, use @CHUNK <chunkname> for this purpose.
Please note: If you're not using <script> Tags, your Chunk content will be interpreted as file path, not as actual JavaScript code.
defaults to none

&jscallback

This can be any javascript function name. It will be called first when the AJAX loading starts and a second time when loading is complete.
You'll get 2 parameters for that function. The first one is the response. The response is false when loading has just started and contains the loaded HTML if loading is done.
The second parameter is the id of the poll element. This is the same as specified in &identifier and will help you to route the responses to the correct poll if you're using multiple polls on one page.
defaults to "EasyPoll_DefaultCallback" which is defined in EasyPoll/script/EasyPollAjax.js

&showexception

If set to true, even "invisible" exceptions like the one occurring if no poll was found will be shown!
This is useful and recommended for testing, should not be used in production environment though.
defaults to false

Templates

Important: Only Chunks are currently supported as Templates!

Template Placeholders

Templates allow you to customize the appearance of your Polls. If these static templates aren't flexible enough for your needs, please have a look at the Template Functions section.


tplVoteOuter

The wrapper template for the vote display. Should at least contain the question, choices and the submit button.
Please note that tplVoteOuter is always wrapped in a div with id="<&identifier>" and class="easypoll", no matter what you put in your Template. This is to ensure functionality of the poll snippet.

[+question+] = the title/question of the poll.
[+choices+] = the vote options/choices.
[+submit+] = the submit button will be injected there. Don't forget this or the user won't be able to vote.
[+results+] = button to show results. Not mandatory, since results will be shown upon voting.


tplResultOuter

The wrapper template for the results display. Should at least contain the question and choices placeholder.

[+question+] = the title/question of the poll.
[+totalvotes+] = the total amount of votes that were cast for this poll.
[+totaltext+] = the text. eg. "Total votes" in english.
[+choices+] = the choice results.


tplVote

This is the template for a single voting option. You should use both placeholders here.

[+select+] = the radio button. Don't forget this or the user won't be able to vote at all!
[+answer+] = the answer. Don't forget this. Please :)


tplResult

The template for a single result.

[+answer+] = the answer.
[+percent+] = the percent value of this result (without %, accuracy according to &accuracy param).
[+percent_int+] = integer value of the percentage. Can be used for CSS styling. eg. width:[+percent_int+]%;
[+votes+] = the number of votes that went in for this question/option.


tplError

Template for a error message, that might be returned by the EasyPoll Snippet.

[+message+] = The error message.


Template Functions

Template Functions give you full control over your EasyPoll output. Instead of using chunks, you can define a php function that creates the output. You can mix Template Functions and regular Chunk-Templates.
Example: Imagine you want a poll result, where the color of the bar changes with the amount of votes that were cast. That's where chunk based templates stop and template functions start to shine.

Usage

If you already have a function defined somewhere in the global php scope, simply set one of the Template Parameters to: @FUNCTION <YourFunctionName>
If you want to define the function directly in a chunk, use @FUNCTIONCHUNK <ChunkWithFunctionName>. The Chunk content will then be parsed by the snippet. The first function to be found inside the chunk will be used as template function.

Please note, that every function must have at least 1 parameter. This parameter will be a associative array with the keys named like the placeholders. Eg. A function for tplResult will get a array with the keys answer, percent, percent_int, and votes. As second Parameter, the template identifier will be given (eg. tplResult). This allows you to write just one function and handle all calls within this single function (by using a switch statement on the second parameter). The function must return the composed String output for the requested Template!

For a detailed example of a Template Function, read the Template Function usage example.

Usage examples

Basics

The most basic way of calling the Snippet is the following:

[!EasyPoll!]

Usually you'll need some more parameters though. For testing it is recommended to display all exceptions for debugging. Here's an example to test a specific poll (in this case, the poll with id 1):

[!EasyPoll? &pollid=`1` &showexception=`1`!]

On to a more complex example. Now we want the Poll to be shown in a specific Language and load a custom Stylesheet (in this example, the poll.css that comes with the Snippet) for it. Since we already include mootools in our page, we can prevent the snippet from loading it a second time with the &nojs parameter. We prevent the User from voting multiple times by setting the &onevote and &useip Parameters.

[!EasyPoll? &lang=`de` &onevote=`1` &useip=`1` &nojs=`1` &css=`assets/snippets/EasyPoll/poll.css`!]

If you want to display multiple Polls on one page, you have to set the &identifier Parameter to a unique value for every poll. Here's an example that will allow you to have 2 polls on one single Page. Since we want two different polls to be displayed, we call them explcitly by specifying the pollid for each of them. The first poll will only be votable once, the second one doesn't have this limitation. To prevent multiple inclusions of mootools, we set &nojs to true on one of the Snippet calls.

[!EasyPoll? &pollid=`1` &identifier=`MyPoll_1` &onevote=`1` &useip=`1`!]
<!-- some site content? -->  
[!EasyPoll? &pollid=`2` &identifier=`MyPoll_2` &nojs=`1`!]  

Poll Archive

You're creating polls regularly and want to have an archive of older polls on your Website? Easy!
In the following example, we're generating a list of old polls and skip the first one on the list with the &skipfirst parameter (since this is our currently running poll). Please note, that this will output the polls with the default Templates if not specified otherwise.

[!EasyPoll? &archive=`1` &skipfirst=`1`!]

JavaScript Callback

Simply replacing the Voting-Screen with the Results is not good enough? Fancy something flashy? Here are two examples where we make use of the custom JavaScript Callback functions.

Easy, for Testing

To get started, we want to test if the JavaScript Callback actually works. Create a new Chunk in MODx, name it CallbackTest and fill it with the following Code:

<script type="text/javascript">
<!--
var MyCallback = function(response, id){
    if(response == false){
        alert('hey, i just sent something');
        $(id + "submit").disabled = true;
    } else {
        alert('hey, i just received something');
        $(id).setHTML(response);
    }
}
-->
</script>
 

Now, place the following Snippet call in one of your Documents:

[!EasyPoll? &customjs=`@CHUNK CallbackTest` &jscallback=`MyCallback`!]

This will load the JavaScript Code from the CallbackTest Chunk into your HTML Page and use the MyCallback function for callbacks.

If you vote, you should get a JavaScript alert saying "hey, i just sent something", shortly followed by another alert, saying "hey, i just received something".
This isn't exactly useful, but hopefully it shows how the JS Callbacks work. For a more sophisticated example, please read the next section.

Adding some mootools effects

In the following example we will use the mootools Effects to slide in the results after voting. Please make sure, you're using a mootools version that has the Fx.Style built in (docs.mootools.net/Effects/Fx-Style.js).

I suggest you put the following Code into a separate JavaScript File for easier editing/maintenance. Let's place it in /assets/js/PollCB.js

var PollCB = function(request, id){
    var elem = $(id);
    var size = elem.getSize();
    if(request == false){
        $(id + 'submit').disabled = true;
        var newElem = new Element('div', {
            'class': 'loading',
            'styles': { 'height': size.size.y }
        });
        elem.empty();
        newElem.injectInside(elem);
    } else {
        elem.empty();
        var newElem = new Element('div');
        newElem.setHTML(request);
        newElem.setStyles({
            'position': 'relative',
            'top': '-500px',
            'visibility':'hidden'
        });
        newElem.injectTop(elem);
        var s = newElem.getSize();
        elem.setStyles({
            'height': s.size.y,
            'position': 'relative',
            'overflow': 'hidden'
        });


        var slider = new Fx.Style(newElem, 'top', {duration:1000});
        slider.start(-s.size.y, 0);
        newElem.setStyle('visibility', 'visible');
    }
};
 

When a vote is cast, this script will replace the "voting screen" with a loading animation (by creating an empty div with class="loading") and as soon as loading is complete, the results will slide in from the top. It is up to you, how you style the loading div. Personally i add a loading animation as background image. In most of the cases, you won't even see the loading div though.

It's possibly a good idea to define some styles for the Poll, either use the bundled poll.css or create your own definition. Then you call the Snippet with the following parameters:

[!EasyPoll? &customjs=`assets/js/PollCB.js` &jscallback=`PollCB` &css=`yourCSS.css`!]

That's it. Simple but effective.

Template Function

In this example, we make use of a Template Function to change the color of the bars from Red (0% Votes) to Green (100% Votes). In addition, we place the percentage label inside the bar. If the colored area of the bar is bigger than 50%, the label will be placed inside, otherwise outside the colored area. We do this, by defining a Template Function for the &tplResult Parameter. We can do this for any of the template Parameters if we like!

First we need a minimal CSS definition. Feel free to alter/extend. In this example we place it in /assets/files/epoll.css

.pollresults li {
    clear:both;
    width:100%;
}
.easypoll fieldset {
    border:0px;
    margin:0px;
    padding:0px;
}
.easypoll_bar {
    height:1.2em;
    background-color:#CCC;
    float:left;
    width:100%;
    margin-bottom:0.5em;
}
.easypoll_bar strong {
    float:left;
    display:block;
    padding:2px 3px;
    font-size:0.9em;
}
.easypoll_inner {
    height:100%;
    float:left;
    background-color:#000;
}
 

Now we create our Template Function. Place the following Code in a new Chunk and name it "PollFunction"

// this will print a custom result bar
function EasyPoll_PrintResult(&$values, $handle){
    $perc = $values['percent_int'];
    $col = HSB2HEX($perc * 1.1, 100, 100);
    $buf = '<li><strong>'. $values['answer'] .'</strong> [' . $values['votes'] . ']'.
           '<div class="easypoll_bar"><div class="easypoll_inner" style="width:'.
           $perc .'%; background:#'. $col .'">';
    if($perc > 50){
        // place number inside bar
        $buf .= '<strong>'. $values['percent'] .'%</strong></div>';
    } else {
        // place number outside bar
        $buf .= '</div> <strong>'. $values['percent'] .'%</strong>';
    }
    $buf .= '</div></li>';
    return $buf;
}

function HSB2HEX($h, $s, $v){
    $h = round($h)%360;
    $s = round($s*2.55);
    $v = round($v*2.55);
    if($s == 0){
        $r = $g = $b = $v;
    } else {
        $t1 = $v;
        $t2 = (255-$s) * $v/255;
        $t3 = ($t1 - $t2) * ($h%60)/60;
        if($h<60) {$r=$t1; $b=$t2; $g=$t2+$t3; }
        else if($h<120) {$g=$t1; $b=$t2; $r=$t1-$t3; }
        else if($h<180) {$g=$t1; $r=$t2; $b=$t2+$t3; }
        else if($h<240) {$b=$t1; $r=$t2; $g=$t1-$t3; }
        else if($h<300) {$b=$t1; $g=$t2; $r=$t2+$t3; }
        else if($h<360) {$r=$t1; $g=$t2; $b=$t1-$t3; }
        else {$r = $g = $b =0; }
    }
    return sprintf('%02X%02X%02X', $r, $g, $b);
}
 

As you can see, we have 2 function definitions. One that is our actual output function (EasyPoll_PrintResult) and one helper function (HSB2HEX) that generates RGB Hex values from HSB input.
It doesn't matter how you name your functions, you should be aware of two important things though:
The first function definition will always be called by the snippet. In this case, it's EasyPoll_PrintResult!
Make sure, your function name is unique and not used yet. Most likely a prefixed function name like the one above will do fine.

Now we're ready to put the Snippet call somewhere in our Document and we're done. If it doesn't work, use the &showexception parameter to get some debugging information.

[!EasyPoll? &css=`assets/files/epoll.css` &tplResult=`@FUNCTIONCHUNK PollFunction`!]
Created: 21/09/2008 – Edited: 04/08/2009