Despabilando la MonoNeurona::Internet es de todos [Inicio] [Regresar]
WWW \ Ajax Poll CakePHP
WWW
Ajax Poll CakePHP

Este artículo ha sido consultado en 1,132 ocasiones.

I am implementing a polling ajax system on CakePHP, I have two Postgresql tables:

CREATE TABLE polls (
    id serial PRIMARY KEY,
    question varchar(130) NOT NULL,
    created timestamp(0) with time zone DEFAULT now() NOT NULL,
    user_id integer NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    status integer DEFAULT 0 NOT NULL   -- defines if poll is published = 1   or  not = 0
);

CREATE TABLE pollrows (
    id serial PRIMARY KEY,
    poll_id integer NOT NULL REFERENCES polls(id) ON DELETE CASCADE,
    answer varchar(130) NOT NULL,
    color varchar(15) DEFAULT 'green' NOT NULL,
    vote integer DEFAULT 0 NOT NULL
);

Note "users" table must exist, if you don't have the table just delete the column user_id in "polls" table. Poll keeps the questions and Pollrows the answers and votes. (Is easy migrate the tables to->MySQL just use "date" instead "timestamp"). So the model Poll is:

<?php
//File: /app/models/poll.php
class Poll extends AppModel
{
  public $name = 'Poll';
 
  public $hasMany = array('Pollrow' =>
                         array('className'     => 'Pollrow',
                               'conditions'        => null,
                               'order'               => 'answer',
                               'limit'                => null,
                               'foreignKey'       => 'poll_id',
                               'dependent'       => true,
                               'exclusive'         => false,
                               'finderQuery'     => ''
                         )
                  );
}
?>

The Pollrow model:

<?php
class Pollrow extends AppModel
{
  public $name      = 'Pollrow';
 
  public $belongsTo = array('Poll' =>
                             array('className'  => 'Poll',
                                     'conditions'   => '',
                                     'order'          => '',
                                     'foreignKey'  => 'poll_id'
                           )
                     );
}
?>

I inserted manually the first poll:

INSERT INTO polls ("question", "user_id", "status") VALUES ('Who is your favourite Renaissance Artist?', 1, 1);

INSERT INTO pollrows ("poll_id", "answer", "color", "vote") VALUES (1, 'Michelangelo',        'green',    0);
INSERT INTO pollrows ("poll_id", "answer", "color", "vote") VALUES (1, 'Raphael',              'orange',   0);
INSERT INTO pollrows ("poll_id", "answer", "color", "vote") VALUES (1, 'Leonardo Davinci',  'red',        0);
INSERT INTO pollrows ("poll_id", "answer", "color", "vote") VALUES (1, 'Other',                  'blue',       0);
INSERT INTO pollrows ("poll_id", "answer", "color", "vote") VALUES (1, 'None',                   'yellow',    0);
 

The colors column correspond to images in app/webroot/images/static/poll directory, every images is 10x10 pixels and .png (and only .png) format.

I am putting the poll inside the div add_pollrow in app/views/users/general.thtml (my homepage site defined in routes.php), this view correspond to /users/general (controller/action). Surely you have another controller/action as your home page, just set DIV add_pollrow in the view and load the model Poll on the controller.

 The steps:

  1. Set a form with the question and the options to answer in add_pollrow div in the view app/views/users/general.thtml
  2. Send and add the vote to Pollrows model (table) in app/controllers/pollrows.php,  method "vote()" and after this, select the new values
  3. Render app/views/pollrows/results.thml and set the new values of poll in add_pollrow

So we need to load the Poll model in app/controllers/users_controller.php:

loadModel('Poll');

And inside "general" method:

       /**********  Poll  ****/
       
        $this->Poll = new Poll;  //Instantiate the model
       
        $conditions = array("status"=>1);     // only polls published
        $fields     = array("id", "question");
        $order      = "Poll.id DESC";              // the most recent poll
        $limit      = 1;
       
        $this->set('poll', $this->Poll->findAll($conditions, $fields, $order, $limit, null, 2));

After set "poll" array in app/views/users/general.thtml, I process the array "poll" in this view (you will need a loading.gif image):

<div class="tiny_title">Well, the poll</div>

<div id="loading" style="display: none;">
       <?php echo $html->image("static/loading.gif", array("alt"=>"Loading")); ?>
</div>

<div id="add_pollrow">
  <?php

    if ( !isset( $_SESSION["poll"] )  ) // the user has not voted, so, set the form
   {
    
echo $html->formTag('#','post', array("onsubmit"=>"return false;"));    // do nothing

     $array   = array();
   
     echo "<p><b>" . $poll[0]['Poll']['question'] ."</b></p>";
   
     echo $html->hiddenTag('Pollrow/poll_id', $poll[0]['Poll']['id']);       // Poll_id
   
     foreach ($poll[0]['Pollrow'] as $key=>$val)
     {
          $array[$val['id']] = $val['answer'];                                      // construct id->value array
     }
   
    echo $html->radio('Pollrow/id', $array, '<br /><br />');              //print the answers
   
    echo '<br /><br />';
   
    echo $ajax->submit('Vote', array("url" => "/pollrows/vote",
                                     "update"=>"add_pollrow",       // add_pollrow wil be updated with app/views/pollrows/results.thtml render
                                     "loading" => "Element.hide('add_pollrow');Element.show('loading')",
                                     "complete" => "Element.hide('loading');Effect.Appear('add_pollrow')"
        ));
  echo '</form>';
  }
  else // the user has voted, so just print the poll results
  {
   
    $total_votes = 0;
   
    foreach ($poll[0]["Pollrow"] as $key => $val)
    {
        $total_votes += $val["vote"];  // the total votes
    }
   
    foreach ($poll[0]["Pollrow"] as $key => $val)
    {
             $percent = ($val["vote"] * 100) / $total_votes;  // % = votes * 100 / total
             $width   = number_format($percent, 0);
             echo '<p><b>'.$val['answer'].'</b> '.number_format($percent, 2).'% <br />';
             echo $html->image('static/poll/'.$val["color"].'.png', array("height"=>"10", "width"=>$width,"alt"=>$val["answer"], "title"=>$val["answer"]) );
             echo "  ". $val['vote'];
    }
 
  echo "<p class='negrita'>Total votes:" . $total_votes . "</p>";
}
?>
</div>

Note $ajax->submit send the vote to app/controllers/pollrows/vote:

  public function vote() {
        // adds new vote to database
     if (!empty($this->params['data']))
     { 
       $vote = $this->Pollrow->field('vote', array("Pollrow.id" => $this->params['data']['Pollrow']['id']) );
      
       $vote += 1;
      
       $this->params['data']['Pollrow']['vote'] = $vote;  // add vote
      
       //die(print_r($this->params['data']));
      
       if ( $this->Pollrow->save($this->params['data']) )   // add the Poll vote
           {      
               $_SESSION["poll"] = true; //set session, only one vote per session
              
               $conditions = array("Pollrow.poll_id" => $this->params['data']['Pollrow']['poll_id']);
               $fields     = array("Pollrow.answer", "Pollrow.color", "Pollrow.vote", "Pollrow.poll_id");
               $order      = "Pollrow.answer DESC";
              
               $this->set('poll', $this->Pollrow->findAll($conditions, $fields, $order, null, null, 2));
              
               $this->render('results', 'ajax');
            }
            else
            {
                echo "Ajax error, check with the company's computer guy...";
            }
        }
    }

 

Note, after add the vote and set 'poll' array, the view app/views/pollrows/results.thtml is rendered:

<?php
  //die(print_r( $poll ));
  $total_votes = 0;
 
  foreach ($poll as $key => $val)
  {
       $total_votes += $poll[$key]["Pollrow"]["vote"];  // the total votes
  }
 
  foreach ($poll as $key => $val)
  {
             $percent = ($poll[$key]["Pollrow"]["vote"] * 100) / $total_votes;  // % = votes * 100 / total
             $width   = number_format($percent, 0);
             echo '<p><b>' . $poll[$key]["Pollrow"]["answer"] . '</b> '.number_format($percent, 2).'% <br />';
             echo $html->image('static/poll/'.$poll[$key]["Pollrow"]["color"].'.png',
             array("height"=>"10", "width"=>$width,"alt"=>$poll[$key]["Pollrow"]["answer"], "title"=>$poll[$key]["Pollrow"]["answer"]) );
             echo "  ". $poll[$key]["Pollrow"]['vote'];
  }
 
  echo "<p>Total votes:" . $total_votes . "</p>";
?>

this view is settled inside add_pollrow div as we indicated in $ajax->submit.

And that is it!! You can see the Poll in action here.


Última actualización: 2007-04-29 10:57:00-05



ir arriba
The Queen is here Mozilla Firefox The Best DataBase CakePHP Framework CSS GNU Hacker