1

I am trying to create a simple on/off link using jquery and ajax. Basically what I want to to is add a link to a page that when clicked will insert a row into my database and update the text of the link. Then when clicked again, that record will be deleted from the database.

So far everything works as expected but the problem is that the second time the link is clicked, the record is deleted like it should, but the page refreshes and redirects to the homepage.

I am following the "plus 1 vote widget" example from Pro Drupal Development and am trying to alter the code to suit my needs. Following is my .js file.

$(document).ready(function() {
  $('a.toggle-visibility-links').click(function() {
    var parentDiv  = $(this).parent();
    var toggleSaved = function (data) {
      $(parentDiv).html(data.toggleon);
    }
    $.ajax({
      type: 'POST',
      url: this.href,
      dataType: 'json',
      success: toggleSaved,
      data: 'js=1'
    });
  return false;
  });
});

Here is my "toggle_visibility" module code

/**
 * Implementation of hook_menu().
 */
function toggle_visibility_menu() {
  $items = array();
  $items['toggle-visibility'] = array(
    'page callback' => 'toggle_visibility_toggle',
    'access arguments' => array('toggle profile'),
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/*
 * page callback
 */
function toggle_visibility_toggle() {
  global $user;
  $toggle_sql = "SELECT * FROM {toggle_visibility} WHERE uid = %d";
  $toggle_result = db_query($toggle_sql, $user->uid);
  $num = mysql_num_rows($toggle_result);

  if (!$num) {
    db_query('INSERT INTO {toggle_visibility} (uid, visible) VALUES (%d, %d)', $user->uid, 1);
  } else {
    db_query('DELETE FROM {toggle_visibility} WHERE uid = %d', $user->uid);
  }

  if (!empty($_POST['js'])) {
    drupal_json(array(
        'toggleon' => '<a href="/toggle-visibility">Toggle My Profile On</a>'
        )
    );
    exit();
  }

  //UPDATE THIS TO RETURN TO THE SAME PAGE
  $path = drupal_get_path_alias('node');
  drupal_goto($path);
}

/**
 * Implementation of hook_theme().
 */
function toggle_visibility_theme() {
  return array(
    'toggle_visibility_link' => array(
      'arguments' => array(),
    ),
  );
}

/**
 * Return a message for no results
 */
function theme_toggle_visibility_link() {
  drupal_add_js(drupal_get_path('module', 'toggle_visibility') . '/toggle_visibility.js');
  global $user;
  $toggle_sql = "SELECT * FROM {toggle_visibility} WHERE uid = %d";
  $toggle_result = db_query($toggle_sql, $user->uid);
  $num = mysql_num_rows($toggle_result);

  if ( $num == 0 ) {
    $link = '<a href="/toggle-visibility" class="toggle-visibility-links">Toggle My Profile Off</a>';
  } else {
    $link = '<a href="/toggle-visibility" class="toggle-visibility-links">Toggle My Profile On</a>';
  }
  return $link;
}

Not sure what I'm missing.

Thanks!

1

In the javascript you should format the data as an object:

data: 'js=1'

replaced with

data: {js: 1}

The problem with the redirect is most likely an JS error caused by the returning value of the ajax callback. To be able to spot it you can hardcode the url in development and change the link simple be <a href="#">xx</a>, that would prevent a new page from loading in case of JS errors and would give you the possibility to read the error log from tools like firebug. Another options would be to insert breakpoints in your JS code, which can be a bit more tricky.

2
  • Thanks for the reply Googletorp. I changed data: 'js=1' to data: {js: 1} like you suggested but it didn't seem to have any effect.
    – Tim Wooten
    Jun 1 '11 at 22:14
  • I also noticed that I left out the toggle-visibility-links class in the toggle_visibility_toggle function so I added that. Really thought that would have solved it but still no change. Everytime on the second click the page refreshes.
    – Tim Wooten
    Jun 1 '11 at 22:15
0

Hope this will help you,

In Drupal 7,

  • You can use ctools for your requirement. No need to write extra JS for that. Just need to include ctools ajax, it will be done.
  • After enabling the ctools, it can be done using ctools_ajax_text_button which render text as a link.

Steps

  • Generate the link

    function create_link($id) {
      ctools_include('ajax');// Include the CTools tools that we need.
      if (!$id) {
        return;
      }
      if ($id)) {//Check for previous status(means already deleted?)
        $output = ctools_ajax_text_button(t("OFF link"), 'toggel/nojs/link/' . $id . '/0', t("OFF link"));
       //if you dont want the OFF as link then comment above Line and uncomment below Line
        //OR $output .= 'OFF';//without link
      }
      else {//not yet deleted
        $output = ctools_ajax_text_button(t("ON link"), 'toggel/nojs/link/' . $id . '/1', t("ON link"));
      }
      $link = "<div id='#toggle-link-" . $id . "'>";//must have unique ID for replacement
      $link .= $output;
      $link .= "";
      return $link;
    }

  • Create menu

    $items['toggel/%ctools_js/link/%/%'] = array(
      'title' => 'Toggle',
      'page callback' => 'toggle_link',
      'page arguments' => array(1, 3, 4),
      'access callback' => TRUE,
      'type' => MENU_CALLBACK,
    );....
     return $items;

  • Toggle link callback

    function toggle_link($js, $id, $status) {
      global $user
      // Include the CTools tools that we need.
      ctools_include('ajax');
      $output = '';
      if ($status == 0) {//ON link
        $output .= ctools_ajax_text_button(t("ON"), 'toggel/nojs/link/' . $id . '/1', t("ON LINK"), 'processed-wod-click');
      }
      elseif ($status == 1) {//OFF link
        //mysql quere goes here
        //you can have revert link if you like else send a html without link
        $output .= ctools_ajax_text_button(t("OFF"), 'toggel/nojs/link/' . $id . '/0', t("OFF link"), 'processed-wod-click');//OFF link
        //if you dont want the OFF as link then comment above Line and uncomment below Line
        //OR $output .= 'OFF';//without link
      }
      if ($js) {
        $commands = array();
        $commands[] = ajax_command_html("#toggle-link-$id", $output);
        print ajax_render($commands);
        exit;
      }
      else {
        return $output;
      }
    }

Note:

Make changes as per your requirement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.