ShowModal in a web-app

How can I use window.showModal in a method to stop execution until the window is closed?
In XOJO -Web it seems not to be implemented (Yet?)

Web apps cannot be modal like that. Use a WebDialog to show a dialog and then use its Dismissed event handler to do any processing when the dialog is closed.

ok - maybe that I have, as we call it in Germany, a burl in my brain - and don’t see an easy solution for my problem:

I started the webdialog with calling a method of that dialog and need the result of the dialog.

something like that:

result = webdialog.startfunc(value)

I don’t see how to do this with the dismiss-event …

Put a public property on the WebDialog. On the button that closes the dialog, set the public property with the value you want. In the Dismissed event handler, get the value from the public property.

(FYI: This technique is described in User Guide Book 2: User Interface, Chapter 3: Web, Section 10: Dialog Boxes.)

RTFM :wink: I’ll take a look ! Thanks for your help!

Hmmm - that example does not look to solve my problem with the way calling a function on the dialog :frowning:

It just isn’t possible. The UI is disconnected from your code, instructions are only sent to the browser at the end of the event loop.

Well, you need to redo your design to use the Dismissed event handler technique. You can’t just call a function and have it return a result in whatever manner you may have been using before.

Display the dialog:

MyWebDialog.Show

In the dialog, have the button that closes the dialog set a property with the value that the function would calculate.

And in the dismissed event you get the value from the property:

myValue = MyWebDialog.ValueFromProperty

I’d recommend using “Me” instead of “MyWebDialog” in the Dismissed event. No reason other than it is more future-proof, if you decide to rename the instance.

ok - thanx a lot for your help!
Knut

Ok, I know exactly what Knut needs to do and why the Dismiss kind of approach doesn’t really fit the logic that well. Here’s my scenario:

I have a lot of screens where I want the user to confirm something, even as simple as Yes or No. I have a general purpose function that I call which works out which Modal, Yes/No type box to pop up. For example when someone wants to save a customer record, I want to say “Are you sure?”, Yes/No.

At that point I am right in the middle of a massive amount of code so I just want to pop up the dialog box, make it stay on that until they answer, then carry on. However, as you know the coding will carry on although the modal box will stay up. The dismiss action won’t allow us to come back to where we left off and continue to save.

I also want to use the same kind of thing to pop up a window that would go and search for customer for billing. So again, I’m in the middle of something else and need to get a customer number to use, so I want to pop up a customer search box and then get the customer number back and then carry on. At that point I’m deep in the middle of a complex set of logic.

Is it feasible to pop up the dialog box and then do something like a doevents until the dialog box object is null, for example? So it sits there until the dialog box has gone? Or does this cause a big strain on the server?

Just saying “use the dismiss event” and setting a public variable when it is dismissed doesn’t give you the flow of logic that you need. I appreciate this is a web app, but as Xojo web apps are meant to mimic desktop apps, we both need a way to achieve the same kind of logic, within what Xojo WE has to offer.

So, in summary, what’s the best way to effect the simple:

code
code
code
Pop up dialog - Wait for a yes or no answer…
code
code
code

Any ideas with practical solutions would be great… It’s holding up new system too trying to think of the best way to do it.

No. There really is no way to do as you’re asking. HTTP works as in a Request/Response model. The browser will connect to the server, request some content, wait for the server to respond, display the content, and disconnect. You code runs in the “wait for the server to respond” piece of the puzzle. Only a single response can be sent per request, which is why no UI changes can happen until the end of your event loop. Clicking a “Yes” or “No” button would be a completely separate request, meaning a completely separate event loop.

Sleeping or locking the thread won’t help either, because the response still won’t be sent until the thread completes. A timer could fire a separate push request, but you wouldn’t be able to tell the timer when to start firing. You’d have to set it up to continuously fire just in case a modal is required. Even then, I’m struggling to come up with a way this could be effective.

I’m sorry, it’s just the way it is. WE uses an asynchronous UI running on a separate machine, which makes this style of coding pretty much impossible. You have to design your code / UX accordingly.

[quote=36433:@Richard H]So, in summary, what’s the best way to effect the simple:

code
code
code
Pop up dialog - Wait for a yes or no answer…
code
code
code[/quote]
As Thom says, you’ll have to rethink your program flow.

Your best bet is to ask for the information up front and then start the long running process from the Dismissed event handler, supplying the value from the dialog.

Hmmmm. I can’t ask for the information up front, as I have no idea what they are going to choose to do before they do it, so … design rethink, given that lots of other web apps have the same kind of functionality no problem, so they’ve got a way to do it, so I must be able to think of a good way as well!

I’ll re-think my code somehow into smaller distinct modules so that the process can store it’s progress, which is easy, then be able to return with the triggering of the dismiss event, and then re-start the process from the next module, which will then allow it to do nothing in between.

One thing WE is very good at is keeping all the session data and everything safe and storing data and objects between requests, which in PHP would require loads of extra coding, so I should be able to come up with some way of doing it.

Ok, if I come up with something good which can trigger the Modal “questions” and then trigger a “continue” when they’ve picked their options, then I’ll post it here. There is a way of course, I just haven’t thought of it yet!

The bits that sounded tricky when I started turned out to be easy, I can push messages and information between users in real time between continents, so this shouldn’t be too hard!

Richard, You just need to adopt an event-driven design:

• Some event triggers a dialog to show.
• Dismissing the dialog triggers some action.

That’s all. They’re not going to redesign this.

I haven’t asked anyone to redesign this, I do adopt an event driven design otherwise nothing in the app would happen at all and I have done so for a long time, and this is event driven, I’m just trying to work out the best way to achieve this logic, which every app has potentially and thought others would have already thought of this and might be able to help.

Your 2 stage, do this, do that, That’s all isn’t very helpful, I know how events work, and given that I didn’t start this thread it’s logically what lots of people need to achieve, so that’s all we’re both asking, the best way to achieve that.

The flow logic and business logic aren’t changed by the technology, just the ways you achieve it in each development tool and system.

We didn’t come here to complain or moan, just for good ideas and help, which I thought the forum was for!

When I come up with the best way I can think of to do this I’ll come back and post it.

The way with the dismiss-event works ‘fine’ in just one case: I have do do the action in the dismiss-event for the module that called the dialog. In my case it is an Calendar-dialog and very often used in the app. So do I have to create several instances of the dialog with the action I need for the calling module?
In my case most of the time the date is written into a label of the calling module. So, ist there a way to store the name of the label in a property somewhere and then do something like that in the dismiss event:

webpage1.nameOfTheLabel.text = myDate

I think there was a possibility to do so but I can’t remember how …

No, but you can use AddHandler to attach a method to the dismissed event from the calling code.

Sorry I’m a bit late with this but I stumbled this post and thought I could give my 2 cents.

@Richard

[quote=36433:@Richard H]
So, in summary, what’s the best way to effect the simple:

code
code
code
Pop up dialog - Wait for a yes or no answer…
code
code
code
.[/quote]

This is how I have tackled this problem in the past with some web server app with a long process that I wanted to be kind of linear.

Properties in your session:

Session.nextStep as integer Session.lastAnswer as string (or whatever)

Your long code is split as:

MyMainMethod select case session.nextStep case 1 Step1 case 2 Step2 case 3 Step3 end select

Then you place the different parts of your long process in several steps as:

[code]sub Step1
code
code
code
session.nextStep = 2
popupDialog
end

sub Step2
code
code
code
session.nextStep = 3
popupDialog
end

sub Step3
code
code
code
end[/code]

And finally, in the dismiss event of your dialog:

session.lastAnswer = theAnswerYouWantToPass MyMainMethod //call the main method to continue process

When you initially call MyMainMethod, make sure you initialize session.nextStep to 1. It might seem a bit complicated compared to a long linear procedure as we used to write in traditional languages, but once you wrap your head around it, it’s actually pretty neat. You can also have another property lastActionDate which is tested every time MyMainMethod is executed to implement a timeout.

@Knut

[quote=37367:@Knut Andersson]
In my case most of the time the date is written into a label of the calling module. So, ist there a way to store the name of the label in a property somewhere and then do something like that in the dismiss event:

webpage1.nameOfTheLabel.text = myDate

I think there was a possibility to do so but I can’t remember how …[/quote]

How about you create a web dialog that you can directly pass the webLabel as a parameter to a updateLabelDate method, and when the date is pressed, the dialog itself populates the label?

Hence, your dialog could have a private property:

theLabelToUpdate as webLabel

… and a method:

sub updateLabelDate ( theLabel as webLabel) self.theLabelToUpdate = theLabel self.show end

… and whenever a date is selected:

if theLabelToUpdate <> nil then theLabelToUpdate.text = myDate.SQLDate

You could also make your dialog more versatile by also having a method that accepts a WebField and when you want to update your date, test both for nil and update whichever is not nil. That’ll give you a nice and versatile date dialog box that updates whatever object you pass to it.

Hope it helps!