Spoke too quickly! Just to verify this I updated to vaadin 6.4.4 and rechecked this, and indeed the widgetset was still on 6.4.1. A quick fix to my deployment scripts and now its working! Thanks for the help, and sorry for the noise.
Now if there was only a way to integrate this with a help icon next to my form fields without completely customizing my form layouts…
Since there doesn’t appear to be a way to do the above easily, one other approach I was thinking of using was to have one help icon at the top of my form that would show the context help for all fields at once. However, only the last call to showHelpFor has any effect. How hard would it be to support the simultaneous opening of multiple context help popups via “showHelpFor”?
Hi Jan, and thanks for your report!
I’ll make sure to look into this problem as soon as my other responsibilities allow me to. I will probably include a fix for this in the next version if all goes well.
You can follow the status of this bug on
bitbucket
ContextHelp is currently not designed to allow opening more than one help-bubble at once. Among other technical problems there’d probably be problems avoiding overlap of bubbles, which would confuse users more than help. If you want to go this way I suggest an “old timey” popup with a screenshot and help texts or something.
However, it should be possible to quite easily integrate a help icon with each form field by using the
CustomField add-on . I would try that before the multiple help-bubbles strategy.
I gave CustomField a shot. I implemented the following to test this:
public class FieldWithHelp<T> extends FieldWrapper {
public FieldWithHelp(final Field wrappedField, Class<T> propertyType, String help) {
super(wrappedField, propertyType, new HorizontalLayout());
HorizontalLayout layout = (HorizontalLayout) getCompositionRoot();
layout.setMargin(false);
layout.setSpacing(true);
layout.setSizeUndefined();
layout.addComponent(wrappedField);
final ContextHelp contextHelp = new ContextHelp();
layout.addComponent(contextHelp);
contextHelp.addHelpForComponent(wrappedField, help);
Button helpButton = new Button("Help", new Button.ClickListener() {
@Override
public void buttonClick(Button.ClickEvent event) {
contextHelp.showHelpFor(wrappedField);
}
});
layout.addComponent(helpButton);
layout.setComponentAlignment(helpButton, Alignment.MIDDLE_LEFT);
layout.setExpandRatio(helpButton, 0);
Label spacer = new Label(" ", Label.CONTENT_XHTML);
layout.addComponent(spacer);
layout.setExpandRatio(spacer, 1.0f);
}
}
It sort of works but causes a bunch of issues (these are most likely CustomField issues so I guess this is the wrong spot to post these, but I can’t be the only one trying to add ContextHelp in this way!):
The form caption ends up moving from the left column to above the field (as if the field wasn’t in a form).
The width gets set to 100% for some reason, and so the help button is way off in the middle of nowhere. Adding the spacer and expand ratios didn’t help.
For some reason the app starts getting variable changes for non-existent components and starts doing weird things like getting out of sync errors. This seems to happen after clicking the Help button.
I can’t believe how hard this is… I’ve built an entire data-driven Vaadin application and the most complex thing has been creating a little help icon next to my form fields.
I guess one thing that might cause problems is the adding of many different ContextHelp components. Try to only add one to the topmost layout. I usually put a ContextHelp in the very topmost layout in the main window (Application.setMainWindow()) and register all help texts / components with this. I also add a getter to my Application class to easily access the ContextHelp component from anywhere.
I’ll try to fix the problem tomorrow if you still can’t get it to work after trying the above.
Typically each layout handles the caption of the fields inside it, so in this case the HorizontalLayout handles the caption of the wrapped field, and the form layout never sees it.
You could try something like this in the FieldWithHelp constructor (untested):
I cannot recall how FormLayout manages field widths, maybe that has something to do with this.
You could also consider using CssLayout instead of HorizontalLayout - it is a little more lightweight if you have many of these on a form, and although it has to be configured with CSS, that might also give you a little more control over the help button placement etc. Just set a style name for the help button, and do the rest in the style sheet.
I’ve tried the solution with only 1 ContextHelp-component added to the layout of the top-window of the app, but with no success. When a ‘global requestrepaint’ is done, the app now hangs (red turning wheel…). Debugging (using Chrome) showed that the browser is in an infinite loop where a does a paint-action over and over again…
I’ve spent the morning on this and have made good progress, thanks to Henri and Jonatan. Putting a single ContextHelp in the main window worked very well!
I now have two remaining cosmetic issues with CustomField, which I’m sure there are simple workarounds for – I just can’t figure them out:
With Henri’s suggestion, the caption is now positioned correctly. However the required field indicator is shown in two places: next to the caption AND somewhere in the composition root. Obviously, it should not show in the composition root. This happens when using either a CssLayout and HorizontalLayout as the composition root, though he positioning of the extraneous * is a little different.
My custom field wraps fields with required=true. If I don’t enter a value and validate the form via form.validate() the custom field throws the correct ErrorMessage i.e. it correctly contains the String I set via setRequiredError(). However, the form error area doesn’t show that message – for some reason it instead shows the caption of the wrapped field instead of the correct error message.
I had this problem too… YMMV, but in my case I realized that I still had an errant extra ContextHelp component in a form. Once I replaced it with a call to the global component, all worked well.
This does not seem to be the problem, because i double-checked and i only have 1 ContextHelp in my app, which is attached to the layout of the main app window. I did found that the recurring paint-job that is was referring to, is the repainting of the red turning wheel :-), so bottom line, the browser isn’t doing anything, it just sits and waits. But to my opinion, the app is stuck in an infinite loop caused by the ContextHelp…
REMARK: i struck me that, when i undeploy the app, the app does not crash. Instead it just keeps on showing the red turning wheel. Normally when the app is waiting for something and you undeploy it, you get a communication error at the client side…This could mean that the infinite loop is on the client-side and not on the server-side…
Any thoughts on this by the designer of ContextHelp?
This kind of sounds like the bug I’ve been chasing for a couple of months now
Basically to reproduce the bug in the demo I do the following:
[list=1]
[]
Focus on a field and press F1 to bring up the help bubble
[]
Click somewhere to close the bubble
[*]
Check the “Follow focus” checkbox
[/list]This causes the “red spinner of death” due to a NullPointerException in the core of Vaadin. I have yet to figure out why it occurs. It might be due to an exotic bug in Vaadin or something in ContextHelp. The workaround for this case is obviously to not allow the user to change the “follow-focus” mode of the component, but it looks like you have hit the same bug with another use-case…
I finally squished the NPE bug I was referring to earlier and released version 0.8 of ContextHelp! V0.8 can be considered to contain all features that will be in version 1.0. All suggestions will be taken into account for the following versions. I also think that I fixed the bubble-opens-on-requestRepaint that Jan talked about; could you please test this new version, Jan?
Thanks to the squished bugs, ContextHelp can now be considered relatively stable. If there are no bugs found I will release this as version 1.0 in a few weeks.
mmmhhh, a bit too early with my conclusions…
i still have issues with the ContextHelp; when using one global ContextHelp component (attached to the layout of the top-level window of the app), i have issues with parts of the app that are not immediately visible when first shown ( i have a menu, and based on the item clicked in the menu, another part of the gui is shown). When shown for the second time or after hitting the F5-button, they become visible.
I tried another approach by only generating the ContextHelp component when needed (i.e. when the ‘help’-button is clicked), but then it does not show me the popup help when clicking the ‘help’-button; not the first time, not the second time. Only when hitting F5, the popup becomes visible…
So it appears that the fix you made to the bug, blocks repaintrequests to other components on the screen…
I am having the same problem Raman. I am using vaadin 6.5.0 with maven and cannot get this to work. I can see the widget being compiled - but I still get this error:
Widgetset does not contain implementation for org.vaadin.jonatan.contexthelp.ContextHelp. Check its @ClientWidget mapping, widgetsets GWT module description file and re-compile your widgetset. In case you have downloaded a vaadin add-on package, you might want to refer to add-on instructions.
I have been able to use other addons successfully so am at a loss. It seems that other people have had no issues - any suggestions?
In my case the widgetset that was being compiled was not being deployed to my runtime environment. Once I fixed the deployment script, it started working.
What I did was after building the widgetset, I copied target/app-version/foo.bar.widgetset.AppWidgetset to src/main/webapp/VAADIN/widgetsets/: