1

I am using navigator.geolocation.getCurrentPosition to get the user's current location, and then using the Services module to update the user's location (part of the user object) via AJAX.

Here is the AJAX call to the service:

jQuery.ajax({
  type: "PUT",
  url: "/api/internal/user/" + uid,
  data: JSON.stringify(geolocation),
  dataType: "json",
  contentType: "application/json",
  success: function(r) {
    console.log(r);
  }
});

The update works just fine, but when I navigate to another page afterwards, I get the status message: "The changes have been saved". After some digging, I found that this status message gets displayed any time user data is updated, which is fine usually, but will be confusing in this scenario since data is being updated behind the scenes. I'm assuming that since the user update is taking place via AJAX, the status message doesn't get displayed until next page load.

Is there any way to prevent Drupal from displaying this status message only when user data is updated using Services?

2
  • what's your Drupal version?
    – LLub
    Commented Oct 30, 2012 at 17:53
  • Running Drupal 7.16
    – zxqx
    Commented Oct 30, 2012 at 18:28

3 Answers 3

0

On your menu callback function ( at /api/internal/user/%user ) you can call drupal_get_messages('status');. This will clear the status messages displayed to the user. A better approach would be to check the message first:

$message = drupal_get_messages('status', false);
if( $message == t('The changes have been saved.') ) {
  drupal_get_messages('status');
}

If this is not a custom module, you should build one and use hook_page_alter() like this:

function yourmodule_page_alter(&$page){
  if(arg(0) == 'api' && arg(1) == 'internal' && arg(2) == 'user') {
    $message = drupal_get_messages('status', false);
    if( $message == t('The changes have been saved.') ) {
      drupal_get_messages('status');
    }
  }
}
3
  • Pardon my ignorance; should this menu callback be in a module, or somewhere else?
    – zxqx
    Commented Oct 30, 2012 at 19:03
  • yeah. I thought this is in a custom module you built. I updated my answer with another solution. Commented Oct 30, 2012 at 21:04
  • Thanks, I was on my way to implementing a form of this, and your code helped me finish it. Appreciated!
    – zxqx
    Commented Oct 30, 2012 at 21:11
0

If you want to use JavaScript/ jQuery then simply use it:

$(document).ready(function(){
 if($("h2.element-invisible").text() === "Status message") {
    $("h2.element-invisible").parent().css('display','none');
 }
});
0

In one of our recent projects, the client wanted to block users from changing some of their own profile values based on some run-time logic. However, even if nothing was changed, the user core module would send the message "The changes have been saved." which would be confusing for the user.

The accepted answer here will delete ALL pending Drupal messages if a match is found for one of the messages--perhaps not a desired outcome.

We decided to implement a more general-case message interception scheme. Given the restrictions not to upset the Drupal 7 core, it ends up being somewhat convoluted, but the run-time performance hit is mitigated given the extra conditionals.

Given that this code is accessing only the $_SESSION variable, it can be placed in a template or module, and the '...clear...' function should be called from within a late-stage preprocess-page hook/theme/template function (e.g., template_preprocess_page(), hook_page_build(), etc.).

Anyway, here's the code we used, in case it helps others:

 /**
 * Adds message to intercept and delete upon next page load.
 *
 * intercepts system message so that it's not displayed to users
 * (usually to avoid confusing Drupal messages)
 *
 * @param string $message
 * The exact text that will be intercepted.
 * 
 * @param string $type
 * The Drupal message type that will be intercepted. 
 */
function mymodule_intercept_system_message($message = NULL, $type = 'status') {
    if (NULL !== $message) {
       $_SESSION['mymodule_intercepted_message'][$type][] = $message;
    }
}

/**
 * Clears system messages that have been flagged for interception.
 *
 * See: mymodule_intercept_system_message()
 * Admin will still see the intercepted message with added prefix.
 *
 * @param bool $clear_flagged_messages
 * boolean: true = All flagged messages are cleared for next page load, defaults
 * to true
 *
 * @return
 * bool TRUE if message was intercepted, FALSE otherwise
 */
function _mymodule_clear_intercepted_system_messages($clear_flagged_messages = true) {
/**
 * Interact directly with $_SESSION since drupal core function drupal_get_messages()
 * only allows for all or no messages to be deleted, not specific messages
 *
 * drupal messages:
 *      $_SESSION['messages'][type][idx] = message-text
 * intercept messages:
 *      $_SESSION['mymodule_intercepted_message'][type][idx] = message-text;
 */
    $retval = false;
    if (isset($_SESSION['messages'])) {
        if (isset($_SESSION['mymodule_intercepted_message'])) {

            foreach ($_SESSION['messages'] as $type => $message_array) {
                foreach ($message_array as $key => $message) {

                    if (isset($_SESSION['mymodule_intercepted_message'][$type])) {
                        foreach ($_SESSION['mymodule_intercepted_message'][$type] as $int_key => $int_message) {

                            if ($int_message === $message) {
                                //message found, clear it so it doesn't display
                                unset($_SESSION['messages'][$type][$key]);

                                //unset entire type if empty, so Drupal doesn't ouput blank message block
                                if (0 == count($_SESSION['messages'][$type])) {
                                    unset($_SESSION['messages'][$type]);
                                    // unset messages if empty,
                                    // because Drupal core expects array not to exist if empty
                                    if (0 == count($_SESSION['messages'])) {
                                        unset($_SESSION['messages']);
                                    }
                                }

                                $retval = true;
                                if (user_access('administer users')) {
                                    //let admin know of message
                                    drupal_set_message('Intercepted message was: ' . $message, $type);
                                }
                            }
                        }
                    }

                }

            }
        }
    }

    if ($clear_flagged_messages) {
        //clear out all flagged messages for next page load
        unset($_SESSION['mymodule_intercepted_message']);
    }

    return $retval;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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