I've made some modifications that allow users to set a vote back to 0 by clicking on the "active" widget again. This requires a couple extra lines in the theme_function, and a bit more javascript.

The change to the theme function is as follows:

if (user_access('use up-down vote') && $user->uid) {
      $user_vote = votingapi_get_user_votes($type, $cid);

      if ($user_vote[0]->value > 0) {
        $class = 'vote-up-act';
        $class2 = 'vote-down-inact';
        $up = 0;
        $down = -1;
      }
      else if ($user_vote[0]->value < 0) {
        $class = 'vote-up-inact';
        $class2 = 'vote-down-act';
        $up = 1;
        $down = 0;
      }
      else {
        $class = 'vote-up-inact';
        $class2 = 'vote-down-inact';
        $up = 1;
        $down = -1;
      }

      $output .= '<span id="vote_up_'. $cid .'" class="'. $class .'" title="'. url("vote_up_down/$type/$cid/$up/1") .'">'. l('', "vote_up_down/$type/$cid/$up", array('class' => $class, 'title' => t('Vote up')), drupal_get_destination(), NULL, FALSE, TRUE) .'</span>';
      $output .= '<span id="vote_down_'. $cid .'" class="'. $class2 .'" title="'. url("vote_up_down/$type/$cid/$down/1") .'">'. l('', "vote_up_down/$type/$cid/$down", array('class' => $class2, 'title' => t('Vote down')), drupal_get_destination(), NULL, FALSE, TRUE) .'</span>';
    }

This is to add the $up and $down vars, basically to change the vote value if one is already active.

The revised AJAX js is:

    $.ajax({
      type: "GET",
      url: db.uri,
      success: function (data) {
        // extract the cid so we can change other elements for the same cid
        var cid = db.id.match(/[0-9]+$/);
        // make an array of the uri so it can be manipulated
        var args =  db.uri.split('/');
        // get some useful data from the uri
        var vote = args[args.length-2];
        var type = args[args.length-4];
        var pid = 'vote_points_' + cid;
        //update the voting arrows
        if (vote == 0) { // user is setting vote to 0, so make everything inactive
           args[args.length-2] = (db.dir1 == 'up') ? 1 : -1; // change the $vote value of the uri to be +1/-1 when reset
           $('#' + 'vote_' + db.dir1 + '_' + cid)
            .removeClass('vote-' + db.dir1 + '-act')
            .addClass('vote-' + db.dir1 + '-inact');
           $('#' + 'vote_' + db.dir2 + '_' + cid)
            .removeClass('vote-' + db.dir2 + '-act')
            .addClass('vote-' + db.dir2 + '-inact');
        }
        else { // passing a +1/-1 value
          args[args.length-2] = 0; // set up for new click uri for this element to have a $vote value of 0
          $('#' + db.id + '.vote-' + db.dir1 + '-inact')
            .removeClass('vote-' + db.dir1 + '-inact')
            .addClass('vote-' + db.dir1 + '-act');
          $('#' + 'vote_' + db.dir2 + '_' + cid)
            .removeClass('vote-' + db.dir2 + '-act')
            .addClass('vote-' + db.dir2 + '-inact');
          }
        // update the points
        $('#' + pid).html(data);
        // lock in the new $vote value to the uri
        db.uri = args.join('/');
      },
      error: function (xmlhttp) {
        alert('An HTTP error '+ xmlhttp.status +' occured.\n'+ db.uri);
      }

I'm open to feedback on how to make this more efficient, but it seems like nice functionality. Interested in a patch?

Comments

frjo’s picture

Status: Active » Closed (works as designed)
miner’s picture

It's really a nice modification. I modified my application according to your codes. Thanks!

asak’s picture

This seems like what i'm looking for (almost...) but i can't get it to work for 6.x-1.x-dev...

Does anyone know how to get a simple "VOTE" which changes into "UNVOTE" after clicking it, enabling users to cancel their vote?
I just need +1 and if clicked get a "cancel vote" button instead.

Funding possibility for a quick implementation! contact me!