ok command not work in Dialog
DanielFath
5 Feb 2010
Nvm. Stupid comment.
msl
5 Feb 2010
If you use your own command instead of Dialog.ok you get the behavior you want... So there's something in Dialog.ok that's stopping your handlers from being invoked.
If you take a look at Dialog.fan (under FAN_HOME/src/fwt/fan) you'll see that Dialog.ok is an instance of DialogCommand (declared in the same file).
The invoked(Event? e) method in this DialogCommand does two things:
switch (id)
{
case DialogCommandId.details:
toggleDetails:
default:
window?.close(this)
}
neither of which is call super.invoked(Event? e) (which would give the behavior you want)
So, in short - you can't add custom handlers to any of the Dialog.* commands.
Akcelisto
5 Feb 2010
>you can't add custom handlers to any of the Dialog.* commands
What purpose it did?
brian
5 Feb 2010
The predefined commands ok, cancel are designed to do two things:
- provide predefined localized buttons
- use as the "result value" of open
What you really want to do is this:
r := dialog.open
if (r == Dialog.ok) { ... }
Akcelisto
5 Feb 2010
How custom dialog must intercept OK inter own definition?
I want to save data in class MyDialog for incapsulation of fields of MyDialog.
class MyDialog : Dialog{
new make(Window? parent, Person p) : super(parent){
nameText := Text{}
ageText := Text{}
body := GridPane{nameText,ageText}
ok := Dialog.ok
ok.onInvoke.add{
p.name = nameText.text
p.age = ageText.text.toInt
}
commands = [ok,Dialog.cancel]
}
}
// using
MyDialog(parent,selectedPerson).open
msl
5 Feb 2010
The answer's already in this thread:
using fwt
using gfx
class MyDialog : Dialog {
Text name := Text { text="Enter your name" }
Text age : Text { text="Enter your age" }
new make(Window? parent) : super(parent) {
body = GridPane{name, age}
comamnds = [Dialog.ok, Dialog.cancel]
}
}
class Person {
Str? name
Str? age
override Str toStr() { return "Person(age=\"${age}\", name=\"${name}\")")
}
class Main {
Void main() {
p := Person()
md := MyDialog(null)
if (md.open() == Dialog.ok) {
p.age = md.age.text
p.name = md.name.text
}
echo(p)
}
}
ivan
5 Feb 2010
I'd rather write something like this:
class PersonDialog : Dialog
{
new make(Window? parent) : super(parent)
{
body = GridPane
{
it.numCols = 2
it.add(Label {text = "Name"}); it.add(name)
it.add(Label {text = "Age"}); it.add(age)
}
commands = [Dialog.ok, Dialog.cancel]
}
Text name := Text()
Text age := Text()
}
And then use it like that:
dialog := PersonDialog(parent)
dialog.name.text = selectedPerson.name
dialog.age.text = selectedPerson.age.toStr
if(dialog.open == Dialog.ok)
{
selectedPerson.age = dialog.age.text.toInt
selectedPerson.name = dialog.name.text
}
ivan
5 Feb 2010
Argh! I'm late)
msl
5 Feb 2010
Argh! I'm late)
Sidewalk needs some AJAXy goodness like stack overflow where you get "someone else has posted a response" as you're replying?
Andy/Brian: get on that wouldya? (or release the code for sidewalk and we'll take a look :P)
Akcelisto
5 Feb 2010
I want use
PersonDialog(parent,selectedPerson).open
insead of
dialog := PersonDialog(parent)
dialog.name.text = selectedPerson.name
dialog.age.text = selectedPerson.age.toStr
if(dialog.open == Dialog.ok){
selectedPerson.age = dialog.age.text.toInt
selectedPerson.name = dialog.name.text
}
You suggest me write this every place where I open PersonDialog?
ivan
5 Feb 2010
If there are thousands of places where you need to write it, then you can do something like this:
static Void showPersonDialog(Window? parent, Person person)
{
//...you got the idea...
}
msl
5 Feb 2010
@ivan I wouldn't go for something quite that ugly (general aversion to static).
Let's consider where we're at:
- You want to pass the Person to the fwt::Dialog to keep it as a single unit
- You can't add invocation handlers to fwt::Dialog.ok
- Brian's commented that fwt::Dialog.ok is intended to be used as a return value
- You get access to the fwt::Dialog.ok object by calling fwt::Dialog.open
What could you sub-class and what methods could override and intercept to figure out whether fwt::Dialog.ok was clicked (returned)?
I have the working code in front of me, but I might leave it as an open thread for the time being to see if we can't teach a man to fish :)
Martin
ivan
5 Feb 2010
Martin, agree, solution with static method is too ugly, your solution is much better. Another option instead of subclassing (which is done anyway) and overriding is to create and use some other object instead of predefined Dialog.ok.
brian
5 Feb 2010
Don't get too hung up on the static definitions of ok, cancel, etc - they are just conveniences for the common case where you don't want a subclass Dialog and just want to open something, then find out what button got pressed.
If you are going to do a custom dialog, just create your own Commands:
class MyDialog : Dialog
{
new make(Window? p) : super(p)
{
body = Label { text="hello" }
commands =
[
Command.makeLocale(Dialog#.pod, "ok") { echo("!ok"); close }
]
}
}
If you want your dialog to return a result, pass the result to close so you can do things like this:
person := MyDialog(parent).open
if (person != null) echo("cancelled!")
Dialog is a swiss army knife - it lets you build up fairly sophisticated dialogs in one line, but also gives you all the hooks you need sophisticated subclassing.
andy
5 Feb 2010
Sidewalk needs some AJAXy goodness like stack overflow where you get "someone else has posted a response" as you're replying?
Yes that would be useful to have next time we do a Sidewalk update.
Akcelisto
5 Feb 2010
using fwt using gfx class TestDlg { static Void main(){ Dialog(null) { ok := Dialog.ok ok.onInvoke.add{ echo("ok") } commands = [ok,Dialog.cancel] }.open } }Why is no output when I press OK?