So there we were, facing a Flash based video player that could have multiple tabs of many videos apiece. And we needed to have graphical user ratings that would be stored in the Drupal database and that looked just like fivestar on the user side. And we couldn't refresh the page when switching between videos. It just didn't look right. Luckily, the video player provider has a very verstile API and the player was firing Flash events that we could use to trigger actions. Out of this came an ajax/fivestar solution. This is what we did.
1. Create a module that facillitates capturing the individual video data as Drupal nodes.
This was essential, since fivestar captures the votes against nodes. We worked with some legacy code that uses a cron hook to sync the database with the video provider library. This way we would maintain a table that reflected the client video library correctly.
2. Install the fivestar module and enable it for the content type
This is pretty straight-forward, but if you skip this step the fivestar rating submissions will not work.
3. Add the fivestar .js and. css files to the page output. These functions are provided by the fivestar module.
fivestar_add_js();
fivestar_add_css();
4. Add a menu callback and page callback function to the module.
The menu callback that will call the function that does the form getting. This exists in a hook_menu function.
$items['fivestar_form'] = array(
'page callback' => ajax_node_fivestar',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
The page callback function the will return the fivestar form. Note that the function takes in a node id in our case. Ultimately the fivestar module needs a node object to return the correct form. Here I use node_load to get the node object.
function ajax_node_fivestar($node_id) {
$node = node_load($node_id);
if (!empty($_POST['js'])) {
drupal_json(array(
'form' => fivestar_widget_form($node),
));
exit();
}
}
5. Add a custom js file to the page that has the jquery ajax call to get the fivestar form. Our jquery call takes in data that has the node id (data.nid). We get this data in a separate call. Upon success, the function will call a second function that actually places the form on the page.
function getFiveStarForm(data) {
$.ajax({
type: 'POST',
url: 'fivestar_form/' + data.nid,
dataType: 'json',
success: setFiveStar,
async: false,
data: 'js=1'
});
}
6. Pass the form to the fivestar function. We test to be sure there is a form to place on the page. If not, then be sure to remove one that may be on the page presently, otherwise you will have a fivestar that rates a different node. In our case we place the form in a div after the video player. Once the form is placed, call the fivestar() function (from fivestar.js) to transform the form into a true fivestar experience.
function setFiveStar(data) {
if(data.form == null) {
$('#fivestar-form').remove();
} else {
$('#fivestar-form').remove();
$(".video-player-div").after("<div id='fivestar-form'>" + data.form + "</div>");
$('#fivestar-form').fivestar();
}
}
}
7. Use a trigger to set the ajax call in motion. We have Flash events that we use to trigger the ajax call, provided by the video player, so whenever a site visitor switches videos, the fivestar rating is changed to the corresponding node's fivestar and updates seamlessly.