0

I've managed to successfully add AJAX into a Joomla module (see here for a highly imperfect implentation of how I did it Putting AJAX in a Joomla Module )

My problem I've got is returning errors in that when I'm throwing errors to date I've just been throwing a JApplication message e.g.

JFactory::getApplication()->enqueueMessage('Some error message', 'error');

However clearly this doesn't give the AJAX any sniff of an error so any time I submit it it calls it a 'success'. Hence my problem.

Too many users for my liking still don't have Javascript enabled for me to feel happy to just add in a straight 400 header redirect (and in any case I would like the error message to be displayed to the user). I would still like the JApplication to just enqueue an error message through PHP as a fallback when javascript is disabled.

I also saw methods of just echoing out the error message onto the page. But because of the not particularly useful way that Joomla modules deal with AJAX the call back data result is actually the full html code of the page! So I'd have to specifically select an element on the page I guess if I were to do it that way - and I'm not sure how to do that/if it's even possible!

So what would be the best way of going about throwing an error message for the AJAX and then retrieve it so that I can display it to the User (yet still retain a nice non-javascript fallback?) Thanks!

Community
  • 1
  • 1
George Wilson
  • 5,595
  • 5
  • 29
  • 42
  • You might want to do warning or notice instead of error. I recently came across something in cli where the complete html for the error page was being sent. – Elin Apr 23 '13 at 11:42
  • @Elin Even so how do I make this fail the AJAX? I only want things coming from my module to trigger the AJAX fail - otherwise I'd just insert a conditional statement in php and use JFactory::getApplication()->getMessageQueue() – George Wilson Apr 23 '13 at 11:59

5 Answers5

1
<script>
  jQuery(window).load(function(){
   var data = {};
   display_result_data();
  });
function display_map_result_data() {
var ajaxUrl = "modules/mod_mapcontent/submit_form.php";
 jQuery.ajax({
              type: "POST",
              url: ajaxUrl,
              data: {category: 'simple'},
              dataType    : "json",
              async       : false,
              success : function(result){
                data = result;
               }
          });
}
 </script>
<?php
/**
 * @package     Joomla.Site
 * @subpackage  mod_banners
 *
 * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
*/
  defined('_JEXEC') or die;
  $baseurl = JURI::base();
?>
 <div id="mapcontent" class="mapcontent">
   <div id="map-canvas"></div>
 </div>
Maulik patel
  • 2,546
  • 2
  • 20
  • 26
1

Joomla javascript object has appropriate function renderMessages for this purpose.

// available msg types: success, error, notice
var msg = {
    error: ['it is an error!<br />', 'it is enother error!'],
    success: ['It works!!']
};
Joomla.renderMessages( msg );

Result

Sergey Onishchenko
  • 6,943
  • 4
  • 44
  • 51
  • I am unable to get 'x' sign (in right top corner, to remove message remaining on that page) along with this message, as it shows in messages rendered after setRedirect. Is there any way to achieve that? – Anant Jun 21 '16 at 16:09
0

Modules can't take full control over application output, there is component and plugins involved too.

You need something that will output message queue and close application.

piotr_cz
  • 8,755
  • 2
  • 30
  • 25
  • I don't necessarily need it to hook into the message function! I just want a way of displaying those messages. If I need a second line where I pass the error message into some array and then json_encode it back thats fine. I'm just not sure how to even gain access to JUST that json_encoded data – George Wilson Apr 23 '13 at 11:41
0

The Joomla devs have been changing things that used to be incredibly useful, and making them more difficult to use. One of those things is the message queue. Currently, you can only read it.

So, if you could set the message in the message queue, then use your AJAX response to move it to a more AJAX friendly location for display - you'd be set. right? This way, it's in queue for display on the next page load, and if a user successfully makes an AJAX request (indicating they have JS enabled), the message is moved to the client with their AJAX response.

First, you'll need a server with Reflection installed/enabled. To my knowledge, it's built-in on PHP 5.3 and later. You can get it on PHP 5.2 and a few prior revisions. Because my solution requires it, I'm going to assume you have it.

This function takes a portion of the error message to search for. So, you'll need to plan your error output so you can find it in the message queue. You could assume that your message is the only message in the queue, but I wouldn't. When theh function finds the message, it grabs it, clears it from the message queue, and returns the complete message.

function getMessage($error) {
  $app=JFactory::getApplication();
  $appReflection = new ReflectionClass(get_class($app));
  $_messageQueue = $appReflection->getProperty('_messageQueue');
  $_messageQueue->setAccessible(true);
  $messages = $_messageQueue->getValue($app);
  foreach($messages as $key=>$message) {
      if(preg_match('/'.preg_quote($error,'/').'/',$message['message'])) {
          $return = $message;
          unset($messages[$key]);
      }
  }
  $_messageQueue->setValue($app,$messages);
  return $return;
}

Using this method, you could set up your ajax response to include the message as a separate data value for your client-side ajax handler to use. When the user has JS turned off, the ajax handler on the server never runs this code, so the message appears as a normal system message.

Michael
  • 9,223
  • 3
  • 25
  • 23
0

In your function:

    $app = JFactory::getApplication();
    echo new JResponseJson(null, $app->enqueueMessage('Some errormessage','error'));

    //close the $app
    $app->close();

In your javascript:

    success: function(response) {
            var jMsgs = response.messages;  // You can stack multiple messages of the same type
            Joomla.renderMessages(jMsgs);
    }
3ehrang
  • 619
  • 1
  • 7
  • 22