Edit an object in a List without a ListEditor

304 views
Skip to first unread message

Maiku

unread,
Sep 23, 2011, 4:52:29 PM9/23/11
to Google Web Toolkit
Is there a way to setup an editor so with a subeditor for one item
within a list without having to setup a ListEditor? My example is:

I have an ConfigProxy that contains a list of LanguageProxy's (which
contain a language code and a boolean for whether it is the default
language or not). When the user first starts up the program I need
them to create their ConfigProxy before doing anything and along with
that I want them to specify a default language. That means I want them
to create 1 and only 1 LanguageProxy that will be flushed into the
List<LanguageProxy> in ConfigProxy.

Because I want them to only create 1 instance, it seems like overkill
to have to put in a ListEditor but I cannot think of a way to setup
the "Path" annotations to point a simple editor to object within a
List.

Is this possible?

Thomas Broyer

unread,
Sep 23, 2011, 5:35:03 PM9/23/11
to google-we...@googlegroups.com
You could edit and flush your subobject from the setValue and flush methods of a ValueAwareEditor. You're not forced to use subeditors foreach and every value.

Maiku

unread,
Sep 23, 2011, 7:34:48 PM9/23/11
to Google Web Toolkit
Hello Thomas,

Thanks for the suggestion. I do not quite understand the user of
ValueAwareEditor though. I have checked the information at
http://code.google.com/webtoolkit/doc/latest/DevGuideUiEditors.html#ValueAwareEditor
and on your blog (http://tbroyer.posterous.com/gwt-21-editors), and
the example in DynaTableRF, but I must say I still do not understand
the intent/use of ValueAwareEditor.

Do you know of any other examples that focus on the core purpose of
ValueAwareEditor or can you explain it more in depth?

-sowdri-

unread,
Sep 24, 2011, 1:35:04 AM9/24/11
to google-we...@googlegroups.com
Even I'm struggling with ValueAwareEditors!

According to my understanding, onPropertyChange of Editors implementing ValueAwareEditors, must be called automatically, by the driver, but so far no success with it,, 

A simple sample wil be a great help! 

Thomas Broyer

unread,
Sep 24, 2011, 8:35:09 AM9/24/11
to google-we...@googlegroups.com
Your editor for ConfigProxy would be a ValueAwareEditor. It'll receive the ConfigProxy in setValue so you could "push" the LanguageProxy to a widget of your choice (actually you could even use a "sub" editor driver). In the flush method, you'd manually flush the LanguageProxy to the ConfigProxy.

-sowdri-

unread,
Sep 24, 2011, 10:38:00 PM9/24/11
to google-we...@googlegroups.com
>> Your editor for ConfigProxy would be a ValueAwareEditor. It'll receive the ConfigProxy in setValue so you could "push" the LanguageProxy to a widget of your choice (actually you could even use a "sub" editor driver). In the flush method, you'd manually flush the LanguageProxy to the ConfigProxy.

Thanks, this explains the crux of ValueAwareEditor!

When will ValueAwareEditor#onPropertyChange called?? 

Thomas Broyer

unread,
Sep 25, 2011, 4:34:13 AM9/25/11
to google-we...@googlegroups.com

Maiku

unread,
Sep 25, 2011, 9:30:43 PM9/25/11
to Google Web Toolkit
So if I understand correctly, ValueAwareEditor basically allows you to
muck with how the object obtains its values? I have tried to
implement this in 2.3 but now I am getting a problem with the Config
object not retaining the values set for the LanguageProxy. That is,
the returned ConfigProxy seems to have the values but once the code
calls to the Server side, the values have been reset to "null".

In my code:

In ConfigViewImpl (which implements ConfigView which in turn
implements ValueAwareProxy<ConfigProxy>):

<pre>
@Override
public void flush()
{
List<LanguageProxy> languages = new ArrayList<LanguageProxy>();

// Not sure if this is the correct way to create an editable
ValueProxy
LanguageProxy lang =
requestFactory.configRequest().create(LanguageProxy.class);

lang.setString(language.getText());
lang.setDefault(true);
languages.add(lang);
proxy.setLanguageList(languages);
}
...
@Override
public void setValue(ConfigProxy value)
{
proxy = value;
}
</pre>


Then in ConfigPresenter:

<pre>
public void save()
{
ConfigRequestContext context =
(ConfigRequestContext)view.getEditorDriver().flush();

// If I use this code, the values persist properly.
//LanguageProxy language = context.create(LanguageProxy.class);
//language.setString("FRA");
//editProxy.setLanguageList(new ArrayList<LanguageProxy>());
//editProxy.getLanguageList().add(language);

if (null == saveRequest)
{
saveRequest = context.save(editProxy);
}

view.setLocked(true);

// Up to this point, the editProxy contains an ArrayList with
the correct LanguageProxy
saveRequest.fire(new Receiver<Void>()
{
@Override
public void onSuccess(Void response)
{
view.setLocked(false);
view.close();
}
}
</pre>

On the server side's Save code, my Config object still contains an
ArrayList with a Language object but the fields of the Language object
are all null. If I use the commented code which sets the values in the
Presenter then those values will persist to the server side
correctly. Is this an issue with the way I have setup my
ValueAwareEditor, how I created the LanguageProxy, or something else?

-sowdri-

unread,
Sep 26, 2011, 1:05:10 AM9/26/11
to google-we...@googlegroups.com
In the code above: The RC which creates the LanguageProxy is different from the one which is used to fire the request on ConfigProxy. That could be the reason why your LanguageProxy is not presisted on the server. 

In the commented code thats not the case, thats why its working. 

To overcome this, you should not create LanguageProxies using arbitary RCs. Ask the presenter whenever you want new LanguageProxy. 

Ex:

// in view
LanguageProxy presenter.getLanguageProxy();

// in presenter 
LanguageProxy getLangaugeProxy(){
 return sameRc.create(LanguageProxy.class);
}

Keep the view simple, and let the presenter take care of creating the proxies :)

Thomas Broyer

unread,
Sep 26, 2011, 5:29:50 AM9/26/11
to google-we...@googlegroups.com
...and use HasRequestContext so that the editor driver passes the RequestContext down to your editor (that's exactly what it was meant for: http://code.google.com/p/google-web-toolkit/issues/detail?id=5892 ).

-sowdri-

unread,
Sep 26, 2011, 7:58:58 AM9/26/11
to google-we...@googlegroups.com
Thanks, HasRequestContext is in fact the right way to do it!

Maiku

unread,
Sep 26, 2011, 7:45:06 PM9/26/11
to Google Web Toolkit
Thanks Thomas,

I had no idea that interface existed. It works a charm now (although,
now I'm considering from a design perspective whether this sort of
manipulation should be done in the editor or the presenter but that's
a philosophical problem :) )

Maiku

unread,
Sep 27, 2011, 6:54:51 PM9/27/11
to Google Web Toolkit
Crud, seems I spoke too soon. The code worked the first time I tried
it but after changing something in a totally different area I get:


com.google.gwt.core.client.JavaScriptException: (TypeError):
__static[524442].call is not a function
at
com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:
237)
at
com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:
132)
at
com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:
561)
at
com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:
269)
at
com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:
91)
at
com.google.web.bindery.autobean.gwt.client.impl.ClientPropertyContext
$Setter$.beanSetter(ClientPropertyContext.java)
at
com.google.web.bindery.requestfactory.shared.messages.InvocationMessageAutoBean.traverseProperties(InvocationMessageAutoBean.java:
91)
at
com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.traverse(AbstractAutoBean.java:
166)
at
com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.accept(AbstractAutoBean.java:
101)
at
com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl.doCoderFor(AutoBeanCodexImpl.java:
521)
at
com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.setProperty(AbstractAutoBean.java:
276)
at
com.google.web.bindery.requestfactory.shared.messages.InvocationMessageAutoBean.access
$8(InvocationMessageAutoBean.java:1)
at
com.google.web.bindery.requestfactory.shared.messages.InvocationMessageAutoBean
$2.setOperation(InvocationMessageAutoBean.java:73)
at
com.google.web.bindery.requestfactory.shared.messages.InvocationMessageAutoBean
$1.setOperation(InvocationMessageAutoBean.java:32)
at
com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.makePayloadInvocations(AbstractRequestContext.java:
990)
at
com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.access
$4(AbstractRequestContext.java:980)
at
com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext
$StandardPayloadDialect.makePayload(AbstractRequestContext.java:220)
at
com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.doFire(AbstractRequestContext.java:
944)
at
com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.fire(AbstractRequestContext.java:
468)
at
com.google.web.bindery.requestfactory.shared.impl.AbstractRequest.fire(AbstractRequest.java:
54)
at
com.google.web.bindery.requestfactory.shared.impl.AbstractRequest.fire(AbstractRequest.java:
59)
at
com.myproject.client.activity.ConfigDialogPresenter.edit(ConfigDialogPresenter.java:
97)


I've received a similar error code before when trying to create a List
Editor with UIBinder (but the stack trace was totally different). How
can I debug into this further to find out the problem as it is turning
up in the javascript code?

Maiku

unread,
Sep 27, 2011, 7:58:00 PM9/27/11
to Google Web Toolkit
Hmmm... this looks it might be a bug in the Development mode for
Eclipse under Firefox 6.02 (although I had my ListEditor problem back
in FF 5.0). Running under IE9 and Chrome both work and using the
"Run" command in Eclipse (which I assume starts Hosted Mode?) instead
of the "Debug" command, also allows it to work in Firefox.

Maiku

unread,
Sep 27, 2011, 8:05:29 PM9/27/11
to Google Web Toolkit
Woops, I mean Eclipse Debug runs Development Mode and Eclipse "Run"
runs Production Mode. (I keep getting confused with the change in
terminology for the modes :) )

Zied Hamdi OneView

unread,
Jun 12, 2014, 6:38:07 AM6/12/14
to google-we...@googlegroups.com
Hi all,

Thanks for the valuable information here, I'm facing a little different but related issue: I have a form that changes some fields depending on what is selected in it

The story is a person who edits her profile, and says: "I'm a company" or "I'm a person" (eventually "I'm a member of a company")
So depending on this choice that is in the form it self, I want to change some editors in the view (first name, last name vs. company name, taxes serial number)

What I thought I could do until now is that I have a ValueAwareEditor with subeditors 

@Path("")
@UiField
protected CompanyBasicInfo basicInfoComp;

@Path("")
@UiField
protected PersonBasicInfo basicInfoPers;

both are filled by the driver, but only one of them is visible.

The thing is that I don't like the idea of having the same property in many editors, neither the performance this approach could imply

On the other side, CompanyBasicInfo and PersonBasicInfo are regular Editor implementations. So putting @Ignore on both of them is not possible since I cannot call a setValue() on them when I will want.

Also making them implement ValueAwareEditor is not clear to me since the contain regular Editor widgets, so I still won't be able to call setValue() on their fields : I'm just moving the problem a step further...

In the view I also don't have access to the Driver to call edit() again. I took a look at how it is done in the lists but there are too much new concepts, I don't think I have to learn all that code just to be able to handle this simple case

Thanks for you answers
Reply all
Reply to author
Forward
0 new messages