1

I have a custom module for notifications as a block and I am trying to use AJAX on a jQuery click event to update a timestamp in a user flag for the current user. The module works without the AJAX. But my JavaScript and AJAX is simple at best. The working js file (no AJAX) is:

(function ($) {
Drupal.behaviors.user_notifications = {
  attach: function (context, settings) {
    $('.notify-icon').click(function(e) {
      $('.notify-list').toggle();
      var $this = $(this);
      $('.notify-count').remove();
      if ($('.notify-count').length || $('.notify-list').is(':visible')) {
        $this.children().first().attr("src","path/to/flag-light.png");
      } else {
        $this.children().first().attr("src", "path/to/flag-dark.png");
      }
      e.stopPropagation();
      });
    }
  };
}(jQuery));

I have added the following route for the AJAX using hook_menu():

function user_notifications_menu() {
  $items = array();
  $items['user_notifications/notify'] = array( 
    'title' => 'Ajax notify button callback',
    'page callback' => 'update_user_flag',
    'access arguments' => array('access content'), 
    'type' => MENU_CALLBACK,
  );
  return $items;
}

The callback function is:

function update_user_flag() {
  global $user;
  $current_timestamp = time();

  // Get user_notification_flag.
  $flag = flag_get_flag('user_notifications_notify');

  // Check if flag exists, if not create the flag for the current user.
  if ($flag && $flag->is_flagged($user->uid)) {
    $user_flag = flag_get_user_flags('user', $user->uid, null, null, false);
  } else {
     $flag->flag('flag', $user->uid);
    $user_flag = flag_get_user_flags('user', $user->uid, null, null, false);
  }

  // Get the flagging ID from the flagging table.
  foreach($user_flag as $flagging_object) {
    $flagging_id = $flagging_object->flagging_id;
  }

  // Load the flagging entity & update the timestamp to the current timestamp value.
  $flagging = entity_load_single('flagging', $flagging_id);
  $flagging->timestamp['und'][0]['value'] = $current_timestamp;
  entity_save('flagging', $flagging);
}

The ajax version (draft) of the js file is:

(function ($) {
Drupal.behaviors.user_notifications = {
  attach: function (context, settings) {
    $('.notify-icon').click(function(e) {
      $('.notify-list').toggle();
      var $this = $(this);
      $.ajax({
        url:'user_notifications/notify'
        data: this,
        success: function(result) {
          console.log(result);
        },
        error: function() {
          console.log("something went wrong");
        }
      });
      $('.notify-count').remove();
      if ($('.notify-count').length || $('.notify-list').is(':visible')) {
           $this.children().first().attr("src","path/to/flag-light.png");
      } else {
        $this.children().first().attr("src","path/to/flag-dark.png");
      }
      e.stopPropagation();
      });
    }
  };
}(jQuery));

I can remove the count button defined by css with the class selector of .notify-count using jQuery (see js function). However I need to send an asynchronous request to change the timestamp of the user flag entity so that when the page is reloaded the following conditional statement in the hook_block_view() will revert to the second test:

user_notifications_block_view(){

// .... standard delta info ...
// Get query info ...

// Get new notifications count.
$notify_count = _get_new_notification_count();

// Test for comments
 if (!empty($items) && ($notify_count > 0)) {
   // Insert flag icon light -indicating new comments
   $block['content']['notify_icon'] = array(
     '#type' => 'markup',
     '#markup' => '<li class="notify-icon"><img src="..path/to/flag-light.png" alt="New notifications" ></li>',
   );
   // Add number of new comments badge
   $block['content']['notification_count'] = array(
     '#type' => 'markup',
     '#markup' => '<li class="notify-count">' . $notify_count . '</li>',
   );

   // Theme content title
   $block['content']['title'] = array(
     '#type' => 'markup',
     '#markup' => '<ul class="notify-list"><li class="block-title"><h3>Notifications</h3></li>',
   );

   // Theme notification items in list for pre-render
   $block['content']['list'] =  array(
     '#theme' => 'item_list__user_notifications',
     '#items' => $items,
     '#pre_render' => array(
       'user_notifications_item_list_child_render'
           ),
   );
 } else {
   // Insert flag icon dark - indicating no new comments
   $block['content']['notify_icon'] = array(
     '#type' => 'markup',
     '#markup' => '<li class="notify-icon"><img src="../path/to/flag-dark.png" class="img-swap" alt="No new notifications" ></li>',
   );

   // Theme content title
   $block['content']['title'] = array(
     '#type' => 'markup',
     '#markup' => '<ul class="notify-list"><li class="block-title"><h3>Notifications</h3></li>',
   );
   // Theme notification items in list for pre-render
   $block['content']['list'] =  array(
     '#theme' => 'item_list__user_notifications',
     '#items' => $items,
     '#pre_render' => array(
       'user_notifications_item_list_child_render'
      ),
    );
  }
}
return $block;
}

I have tried to find use cases for my method but so far I am not sure what to pass into $.ajax({}); as options. I am assuming a 'POST' but what. I tried using just url:'user_notifications/notify' but I got a 500 error. currently I am getting an "unexpected identifier" error. Any help would be greatly appreciated.

Thank you in advance.

Your Answer

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

Browse other questions tagged or ask your own question.