1

I'm displaying a user's Messages (created with the Message module) in a View. I'd like to flag them once they're viewed and thought that a Rule could do this easily. I've set the Rules Event to "A message is viewed" and the Rules Action to "Flag a message", but for some reason the viewing event is not triggered. I tried hovering the Message, visiting the referenced node's page and visiting Content > Messages, but nothing runs the Rule.

Did anyone experience the same problem before? Maybe this is a bug in the Message module (I've reported it at https://www.drupal.org/node/2291695), but I'd like to know whether you've already found a solution for this.

Ultimately, I'd like the Rule to be activated when a user hovers the Message or clicks it (I've already made sure that he/she will then be redirected to the referenced node/comment).

  • are you certain the rule is actually running? – Geoff Jun 26 '14 at 13:20
  • @Geoff: It's not disabled if that's what you mean. – Jeroen Jun 26 '14 at 13:23
  • that's not what I mean. Are you sure the trigger is happening and the Rule is actually running? With rules, the problem isn't always in the action, it's just as often a problem with the trigger or conditions. Set an action of send a system message to the user (or log a message), and see if it actually gives you a message – Geoff Jun 26 '14 at 13:25
  • It won't trigger a content is viewed rule when viewed via Views - it requires viewing the actual node. To make it function in Views, you would need to create an AJAX callback. – Geoff Jun 26 '14 at 20:02
  • @Geoff: That could explain the problem. :) How can I create an AJAX callback? I'm not very familiar with those things. Simply activating AJAX in the view doesn't work anyway, but I don't think it's supposed to be that easy, is it? – Jeroen Jun 26 '14 at 20:11
1

I will go about this differently. Create a non-global flag on the message (ie for each user) and only give flag action (not unflag). Do not auto display this flag.

Then in your view you add the flag action as a field on the row and test whether it works by clicking on it (to test you could give temporary unflag permission). When it works to you satisfaction hide the flag link via css, and add some javascript to click the flag if the row is hovered (or whatever) over. And set the Javascript up so that it can only activate the link once as one can sometimes fire off multiple events when on the border of an element.

And then just add you rule to fire when the message is actually viewed to cover that angle as well as the user may go to that path from somewhere else but your view.

EDIT: jQuery example code:

This code is for a flag called 'test', and a view called 'all', jQuery version 1.7+

(function ($, Drupal, window, document, undefined) {
    Drupal.behaviors.MYMODULE = {
        attach: function(context, settings) {
            $('.view-all .views-row').once().on('mouseover', function(){
               // unbind this event handler so it only fires once
                $(this).off('mouseover');
                // get the flag and click it.
                $(this).find('.flag-test a.flag').trigger('click');
            });

            window.alert = function(text) {
            // Prevent unwanted ajax errors when navigation away
            return true;
        };
        }
    };

})(jQuery, Drupal, this, this.document);

One other little issue is that views does not seem to respect the flag unflag permissions per role. I circumvented that by adding a field 'Flags: Flagged (A boolean field to show whether the flag is set or not.) and setting its output to 0/1. I then hid this new field as well as the flag link, and added a Global PHP field with this Output Code, and it worked like a charm:

<?php
if (!$row->flagged) print $row->ops;
?>

There is a possible patch for this behaviour at Flags: Flag link views field should respect permissions, but I have not tested it.

  • Thank you very much for your update! It really looks clean and promising, but I've tested it and it doesn't seem to work yet. Firstly, I've added a flag link to the View (I don't understand why you use "flag action" in your answer). Secondly, I've pasted your code in my custom module's module.js file, replaced the placeholders with the correct names and cleared caches, but nothing happens when I hover the View's rows and refresh the page. Is something wrong with your code or did I miss something? – Jeroen Sep 10 '14 at 23:28
  • I tested my code and it worked. class .view-all should be replaced with your view, class .flag-test should be replaced with your flag, and these replacements should be looked up in your css. Make sure you are using jQuery 1.7+ (because of on()), and other than that just do things stepwise. Start without hiding the flag link etc. – J. Reynolds Sep 11 '14 at 3:13
  • Thanks for your quick reply. I've updated my site's jQuery version to 1.8 with the 'jQuery Update' module and added scripts[] = MYMODULE.js to my custom module's info file (I forgot to do that yesterday), but the problem is still not solved. I'm certain that I've replaced the placeholders in your code correctly, because I inspected my View with Firebug. Clicking the flag link in the View manually works, but the code doesn't click it automatically when one hovers a Message. – Jeroen Sep 11 '14 at 8:42
  • Add console.log('hello'); to just after the line attach: function(context, settings) { and see if it prints out to the console. Maybe your jquery file is not loading. Inspect the browser source for the script. – J. Reynolds Sep 11 '14 at 11:28
  • Great, I solved the problem! I simply forgot to use drupal_add_js in my custom module's file. There's only one annoying thing left: every time one clicks a Message in the View, the error "An HTTP 0 error occured." appears, because the flagging isn't finished yet when the user is lead to the referenced node. Everything looks right afterwards, though. Do you know a simple solution to prevent this error or should I ask a new question about this? In the meantime, an extra upvote! – Jeroen Sep 11 '14 at 22:12
0

Have you enabled Message UI module, if not, enable it and add the view link in your view. Then clicking the link will take you to the message page and it will trigger the rule event.

Note : make sure you give permission

  • Thanks for your link to this useful module. Although your suggestion would probably work, a link is not really what I want. I'd like the Message to be considered as viewed when a user hovered it in the View or clicks it. Any ideas how I can achieve that? – Jeroen Jul 20 '14 at 19:13
0

Based on the comments above:

You would need to create an ajax call built from a custom module. I don't have much experience with ajax in Drupal outside of forms, so I can't provide any code to help, but here's something to start for info - they're not exactly the same but could point you in the right direction:

when mouseover on username display popup views

Failing that (and now that we have determined what the actual question is), I would close this question and ask a new question about modifying values through an ajax call within Views - you might get more relevant answers.

0

I can see there is a lot of suggestions here - one suggest to trigger it via flag but the trigger will be with the link of the flag... it's sound to much complicated. No need for external module for that.

Some one mentioned here a simple AJAX and he's right about that. What i'm going to give is a mock-up but will explain the process.

First of all we will need a field that will attached to the message and determmine of the message has been watched or any other logic. The secong step is to set up a simple menu callback:

/**
 * Implements hook_menu().
 */
function module_menu() {
  $items = array();

  $items['update-message/%message'] = array(
    'page callback' => 'module_set_message_as_watch',
    'page arguments' => array(1),
    // This will set the menu item accessible for any one. You can set your own
    // logic with the 'access arguments' and pass a permission name or use
    // another function name.
    'access callback' => TRUE,
  );

  return $items;
}

/**
 * Menu callback; Set the message as viewed.
 */
function module_set_message_as_watch($message) {
  $wrapper = entity_metadata_wrapper('message', $message);
  $wrapper->field_viwewed->set(1);
  $wrapper->save();
}

What i defined here is a menu item that pass him a message ID. When i go to update-message/1 the message 1 will be set as viewed.

You can create in you view a simple HTML output with the link above. A simple jqeury can get in action and do something like:

(function ($) {

  Drupal.behaviors.SetMessageAsViwewed = {
    attach: function() {
      $(".set-message-as-viewed").click(function(event) {
        event.preventDefault();


        // Using our own ajax callback.
        $.ajax($(this).attribute('href'))
          .done(function() {
            $(this).text(Drupal.t('The message was viewed.'));
          });
      });
    }
  }

 })(jQuery);

The indentation are wrong but this is the big idea. Not something fancy. Simple jQuery and AJAX interaction with Drupal.

  • Thanks a lot for your answer! I've used your code in my custom module. The module_menu and module_set_message_as_watch functions work fine: the Message's boolean field 'Viewed' is updated correctly. However, I don't understand how this solves my problem. The fact that the Message has been seen is still not triggered and the users shouldn't be supposed to visit MYSITE/update-message/MID every time. The Message should be considered as 'viewed' when he/she hovers it in the View. Maybe I forgot to do something, because I don't find your last step ("You can create in you...") very clear. – Jeroen Sep 10 '14 at 23:24
  • You need to call the menu item via ajax as i displayed with a simple jquery check. like $("#foo").hover(function(){$.ajax...}); – Roy Segall Sep 11 '14 at 4:31
0

I know this question was asked some time ago, but it was one of the top links when I googled for a solution to the same problem as described in the OP.

I believe I have found a solution that doesn't require a custom module, I can't say if this is because the key modules (Views, Rules, Flags and Message) have been updated, or just because no-one else has noticed it before. Anyway, I thought I'd share it so other people that get here from Google can have a go.

My thinking was that the triggering of the Rules event seems to be hardwired somehow to the viewing of the message as a node, and I noticed that on my Message display in Views, there is a "Message: Rendered Message" field. I added this, and on the next screen selected "show complete entity" from the "Display" dropdown menu. I don't think it matters which view mode you select from the next dropdown, and I then removed the label, and excluded the field from being displayed.

This seems to have done the trick for me. I am using an embedded view of a list of messages in the header, and there is a Flag toggle link in that display. I can now, unflag the "seen" flag on a message in the embed, and see that it remains so while I view other messages, and when I view the message again in the main Views display I can see the flag has been changed automatically.

I hope this post is helpful for others with this problem.

0

I've set the event to "A message is viewed" and the action to "Flag a message", but for some reason the viewing event is not triggered.

The "clue" about what "Content is viewed" actually means, seems to be like so:

  • The event Content is viewed is what it is: the user has (already) started viewing the content.

  • The (system) event Drupal is initializing is what you should use instead (possible combined with other Events and/or Actions), if you want to trigger some Rules "Action(s)" BEFORE the user can start viewing (= looking at) the content.

Did anyone experience the same problem before? Maybe this is a bug in the Message module ..., but I'd like to know whether you've already found a solution for this.

For a working sample (in Rules 'export format'), refer to How to specify a Rules event like "Content is 'going to be' viewed"?

Ultimately, I'd like the Rule to be activated when a user hovers the Message or clicks it

A possible implementation which is Rules based (zero custom coding) and close to what you're asking for, is explained in the tutorial "How to allow users to manage their own Message Stack messages?".

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.