|
WWW \ Ajax Poll CakePHP 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:
- Set a form with the question and the options to answer in add_pollrow div in the view app/views/users/general.thtml
- Send and add the vote to Pollrows model (table) in app/controllers/pollrows.php, method "vote()" and after this, select the new values
- 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
|