cancel
Showing results for 
Search instead for 
Did you mean: 

message bar in subcontroller / message-raising in other subcontroller

daniel_humberg
Contributor
0 Kudos

In my BSP-App, I have a message bar in which I display all messages that are raised in my application.

The messages are stored in a singleton-class with a messages table.

The message bar is in subcontroller A and loops over the messages table to display all messages in that table.

The rest of the application is in subcontroller B.

The prolem: subcontroller A is processed before subcontroller B, so if I raise a message in B, it is only displayed in A after the next server event, which is of course not what I want.

What can I do? Thanks for any help!

Accepted Solutions (1)

Accepted Solutions (1)

Thilo
Explorer
0 Kudos

Hi Daniel,

I do pretty much the same, but don’t have this problem. Because: All the work (and message raising) is done in subcontroller B in method DO_HANDLE_EVENT and after that subcontroller A->DO_REQUEST shows the messages.

Maybe you should move your code to the DO_HANDLE_EVENT method or if that isn’t possible to DO_INITATTRIBUTES so that it is called before subcontroller A->DO_REQUEST.

Thilo

daniel_humberg
Contributor
0 Kudos

Hi Thilo,

I'm afraid I can't move my message-raising code to Do_HANDLE_EVENT.

I call my application with an URL parameter.

(default.htm?myParam=myValue)

Now, default.htm has two subcontrollers A and B. Now B checks if myValue has a valid value and raises a message if not. I think, I cannot do this in DO_HANDLE_EVENT, because this method is not called the first time when B is called. Right?

Thilo
Explorer
0 Kudos

You are right.

The only thing you have to do is, call your message raising code before Controller A DO_REQUEST is called. So create your subcontrollers in default-Controller->DO_INIT.

How about that:

METHOD DO_INIT .    " of default-controller

  DATA b TYPE REF TO zcl_controller_b.
  create_controller( controller_id = 'A'  controller_name = 'a.do' ).
  b ?=  create_controller( controller_id = 'B'  controller_name = 'b.do' ).

  b->do_something_and_raise_message( ).

ENDMETHOD.

daniel_humberg
Contributor
0 Kudos

Hi Thilo,

I am thinking to implement a message bar which is as easy to use as possible.

Therefore, I would not like to create all (sub-)controllers in DO_INIT of my mesasage bar.

But I could maybe ensure that the message bar is created after all the other controllers.

What would happen if I would call DO_REQUEST of the message bar controller (B) twice? Would the view be created twice?

Thilo
Explorer
0 Kudos

How do you send a message to the message bar if it is not yet created?

For me the previously described procedure is the only an easiest way to do this. I think calling the DO_REQUEST is not a good idea. If you create your sub controller in DO_INIT of the main controller you can place the <bsp:call ….> (calling sub controllers in default.htm) in any order.

maximilian_schaufler
Active Contributor
0 Kudos

I guess you should change your way of thinking a bit for this problem ... don't be focused on which controller to use, but more when all the message bar actions take place.

There are two parts, creating the messages during all application logic code and afterwards displaying them. As for displaying, you do that in sub-controller A, everything ok so far. You only have to make sure that all code for displaying (or preparing for displaying) is called after all possible messages have been created. Which should be no problem using controllers and views.

For creating messages there are two different points as well. There is the message-creating code/method, and there has to be the message-storing attribute. While messages will be created by all (sub-)controllers, you should have one central place to store them. Now this place has to be accessible from all message-creating methods.

I would recommend placing the messages into the parent controller, or even better into the model (if you use one). It is always nicer to have one central place/object for such things, instead of playing around with manual calling of control flow methods (like DO_INIT, DO_REQUEST, ...), which I would try to avoid at all cost.

daniel_humberg
Contributor
0 Kudos

Hi Max,

that's what I do. The messages are stored and managed by a singleton class called cl_s_msg_log. So, from everywhere in my code, I can get the single instance of this class to create new message.

> You only have

> to make sure that all code for displaying (or

> preparing for displaying) is called after all

> possible messages have been created. Which should be

> no problem using controllers and views.

My only problem: My application is called with some URL parameters. These parameters are analyzed by a certain subcontroller class. This can only be done in DO_REQUEST, since DO_HANDLE_DATA/EVENT is not called when the application is called first.

This leads to the problem that I create a message in DO_REQUEST (when the URL paramter was somehow wrong) and display the message in another DO_REQUEST.

maximilian_schaufler
Active Contributor
0 Kudos

I see (I should read all posts carefully, not just the first few) ...

In my opinion parameters that get submitted in the first call of the application already should not be checked in a subcontroller but in another part (main controller or application logic class) - but I'm willing to get convinced by the opposite.

Either try that, or maybe do some controller trick so that your message controller gets called as the last of all sub controller. You would have to make some view adjustments, maybe place your message bar in an absolute positioned div, so it can be placed at the end of the source code regardless of its position in the page. (this is what I do)

Or use some dummy elements like real_message_bar_is_empty_first, place this according to your layout, and call your just_for_creating_message_bar controller as the last one, and after displaying it (in a hidden div maybe) use javascript to move this hidden div's content to your real_message_bar_is_empty_first. Don't know if you get the idea, this just came to my mind the very second I'm writing this, haven't tested or anything.

Max

Former Member
0 Kudos

All controller work on the same message object (if they know each other) in the application - so the controller has to pass it to the view by in DO_REQUEST:

view->messages = me->messages.

call_view( view ).

And in the view you get them easily by:

call method page->messages->get_message

exporting

index = 1

importing

message = msg

severity = severity

dummy = dummy.

which can be used for a message bar:

<phtmlb:messageBar id = "antBar"

type = "<%= msgtype %>"

text = "<%= msg %>"

rulerDisplay = "BOTTOM" />

daniel_humberg
Contributor
0 Kudos

Hi Sebastian,

there seems to be a messages object in cl_bsp_controller, that seems to be shared by all controllers.

But I don't see how this can solve my problem.

If the view with the message bar is processed before the message is actually raised, the message won't be displayed.

maximilian_schaufler
Active Contributor
0 Kudos

Which leads back to one of my comments, you have to take care of this time-problem. You either have to create the page after all messages have been raised, or you have to use some kind of trick to push your messages into the displayed page afterwards.

daniel_humberg
Contributor
0 Kudos

Ok, thanks Max and all the others.

To summarize it:

Normally, messages are raised somewhere in DO_HANDLE_DATA or DO_HANDLE_EVENT. If so, they can be displayed without problems in the messagebar, regardless where you place it.

If messages shall be raised in DO_REQUEST (in my case because I'm checking URL parameters) you have two choices:

- check the parameters earlier that DO_REQUEST of the message bar, for example in the main controller (I think, this is what I'll do)

- ensure, that the message bar controller is created after all other subcontrollers (by create_controller( ), by absolution positioning in HTML, by Javascript and hidden elements etc.)

Thanks for your help!

Answers (1)

Answers (1)

Former Member
0 Kudos

Assuming suncontroller A and B have the same parent, you could:

*somewhere in controller B...

data main type cl_bsp_controller2,

controllerA type cl_bsp_controller2.

main ?= m_parent.

controllerA ?= main->get_controller( 'cntrlA' ).

Then call its do_request/do_handle_event or whatever you want.