View Full Version : [OPEN] [#426] X.MessageBox.Show( .. ) doesn't get focus after DirectEvent

Oct 12, 2013, 9:42 AM
I have a TextBox that has focus. A DirectEvent is called which contains the following code:

X.MessageBox.Show( new MessageBoxConfig() {
Title = "Failure",
Message = "Failed.",
Buttons = MessageBox.Button.OK,
} );

The MessgeBox appears and though the modal greys the page and emphasis moves to the MessageBox, text input still goes to the original TextBox. Pressing space should be enough to close the MessageBox, but the space types into the original TextBox where focus was before instead.

Interestingly, ENTER still closes the modal.

Oct 12, 2013, 10:11 AM
Actually I figured out this issue. In the same DirectEvent, Focus() (and a few other Server-side calls) are called after the Show(). So because Show is asynchronous, the focus is definitely being sent back to the original TextBox which makes sense but also doesn't. I originally thought the MessageBox should have the focus and queue or disregard since it takes over client-side view, then continue after the modal is closed, but that isn't the case.

I suppose there is a reasonable question about how Ext.Net handles the rendered stream that follows a Show() on a Modal.

The simple solution to my problem is to Set the Focus in the Handler of the MessageBox instead. The problem with that is I have to write client-side code in that case and cannot use Server-side calls anymore.

However, another argument could be made that another solution here is that Ext.Net can manage to attach all server-side calls that render client-side code that fall after a modal Show to the Handler of the Modal Window instead of appended to the stream.

I realize that could be a challenge, but it makes sense chronologically, and it's entirely possible to flip a switch inside Show() that turns all rendering over to another stream that renders the Handler of the Modal in the exact same way as appending it otherwise would to the end of the stream.

Vladimir, consider this challenge?

So in my example above, the following rendering would change from:

script: "Ext.Msg.show({"title":"Failed","buttons":Ext.Msg.OK,"msg":"Failure."});App.TextBox1.focus();"

... to ...

script: "Ext.Msg.show({"title":"Failed","buttons":Ext.Msg.OK,"msg":"Failure.","Handler":"App.TextBox1.focus();"});"

Maybe it can be an advanced option?

Oct 13, 2013, 3:05 AM
I spent some more time thinking about this topic and our development efforts over the next month or two.

Right now the admin side of the web application refreshes the page after every major edit. This is quite expensive, especially when we've got a robust ajax library that should be pretty adept at DirectEvent updates to the page after the post.

In the next major rev, we'll be posting a modal box to the user to indicate their update was successful, then update the contents of the page without the refresh. We want to keep the coding of updates to the client mostly server-side calls which will work great, but there will be definitely be times we need the updates to come after the modal is closed, while other times, it'll be okay to update the page underneath. So having the option to post events to the handler of the modal becomes something we need to be an option we can exploit.

Oct 13, 2013, 8:50 AM

Thank you! We will discuss your request.

Oct 14, 2013, 3:03 AM
Great. I'd even consider it pretty novel if we could switch back and forth between render streams that can be attached to modals or other windows, listeners, etc.


X.CurrentRender = new Renderer();
ctl.Text = '';
X.Msg.Alert("Test", "Test", X.CurrentRender).Show();
X.CurrentRender = X.DefaultRender;

X.CurrentRender = new Renderer();
ctl.Text = '';
Btn1.Listeners.Renderer= X.CurrentRender;
X.CurrentRender = X.DefaultRender;

Or something like that might be pretty cool.

Nov 14, 2013, 9:46 AM
I mentioned this last suggestion again in item 2 here: http://forums.ext.net/showthread.php?27212-Ext-Net-3-0

Jan 14, 2014, 11:01 AM
I guess you finally started this thread summarizing the feature request:

Jan 30, 2014, 12:07 PM
Yeah, I guess the new thread is significantly more detailed. I forgot about this diversion from the original topic in this thread.

Honestly though, when I consider the original topic and how easy it is to make this mistake, I wish there was a simple way to quash all focus events that follow after a MessageBox().Show() command. Maybe it's still an easy addressed fix. Set a variable and prevent additional focus calls? I dunno. Plausible though.

Jan 31, 2014, 12:08 AM
As I started thinking about this more, I'm realizing that focus makes sense as a function that should be a request that's globally singular. That is, it makes no sense to set focus for one control in the same page life-cycle. If the server-side code had a generalized way to enforce singular requests, it could exception on redundant requests and save developers spending a lot of time debugging.

I don't know if you'd like to support this concept but I think it's a valuable enforcement you might want to consider server-side. I can't imagine there aren't other methods that might require a singular-request enforcement besides focus. For instance, MessageBox().Show() or any window modal operation would make sense as globally enforced as singular events. That is, we shouldn't code Show() twice in the same life-cycle.

But a general model internally might be easy enough to implement. So, example, internally instead of Call("setFocus") internally, implement as: TestSingularEvent("focus"); Call("setFocus");

TestSingularEvent would pass a name that is internally used to enforced the singular event of the type. Ultimately it would add a global HashSet list that if already appears would exception if it does and notify the developer they coded something badly.

In the case of a modal event, you'd test TestSingularEvent("modal"). So in the case of MessageBox.Show(), this would be set, then if the developer also mistakenly called Wind1.Show() (and it's Modal=true), then TestSingularEvent("modal") would exception.

Anyway, it's just an idea but easy-peasy to implement. Also, an enum would be faster than a string if you wanted to limit the list of singular-type-identities to enforce.

Feb 03, 2014, 5:28 AM
It sounds interesting, thank you for the suggestion.

Though, IMO, we should leave something for developers to code. This way Ext.NET might degenerate to a button which a developer could click and get a ready application:)

I created an Issue and associated to Geoffrey. He is much better than me to decide it should/might be implemented.

Feb 03, 2014, 8:28 AM
Though, IMO, we should leave something for developers to code. This way Ext.NET might degenerate to a button which a developer could click and get a ready application:)
I created an Issue and associated to Geoffrey. He is much better than me to decide it should/might be implemented.

I think we're a long way from a ready application out-of-the-box but I get your sarcasm. But as you guys are developing tools for developers and some of those developers are VB.Net guys, catching the errors before they happen may be a #if DEBUG appropriate section. Anyway, like I said, it's just a thought. No deal-breakers here. There are a thousand ways to get frustrated and I'm just thinking inside the box on how to make it easier for the next guy not to get lost cuz it honestly took me a few hours for me when this first happened. I don't think I've posed anything all that different than say some of the other exceptions that are triggered when arguments are wrong, but yeah, I agree, I'll trust geoffrey on this one too.

Feb 03, 2014, 2:07 PM
Yes, I got your point clearly and agree.

I would not say it was sarcasm, just a joke. If you don't like it, please say and it will go away forever:)

To be serious, we much appreciate all your suggestions and investigations and consider them without any sarcasm and jokes.

Feb 04, 2014, 10:12 AM
Still, if you don't mind, I would like a button that completes my project for me. Maybe make that a feature request for 3.0? ;)

Feb 05, 2014, 2:59 AM
Ok, we will consider it for 30.0 ;)