Setting className in UiBinder

Skip to first unread message

Geoff Huenemann

Mar 23, 2015, 8:48:43 PM3/23/15
We have successfully ported to your gwt 2.7 version of lib-gwt-svg, and it is mostly working well.

However, I'm now trying to simplify the way we style SVG icons, and I'd like to just out the style directly in the UiBinder XML file.  I sort of expected to be able to use styleName='{style.myStyle}' like I would with any other UiBinder element, but this throws a MISSING_ELEMENT_ERROR.  After some reading, it appears that the difference in the SVG DOM means that no, I should be using classNameBaseVal instead.  Based on some examples, I tried this:

.searchButton { float: left; padding-left: 10px; width: 25px; height: 25px; }


    <svg:SVGImage ui:field='searchButton' resource='{}' classNameBaseVal='{style.searchButton}' />

Although is compiles fine, I get a runtime error during initialization: (TypeError) : Cannot read property 'setClassNameBaseVal_2_g$' of undefined

If I remove the classNameBaseVall property, it works fine.  If I wrap it in a SimplePanel and use styleName='{style.searchButton}' it also works fine, but the code is needlessly complicated.

I have tried many variations on this code with no luck, including a straight copy/paste of some allegedly working examples in lib-gwt-svg-sampels.  Can you see what I'm doing wrong?  Is it possible that this is a casualty of the gwt 2.7 migration?  

Any help would be appreciated...

- Geoff

Lukas Laag

Mar 24, 2015, 6:09:58 PM3/24/15
When you use styleName='{style.myStyle}', what happens behind the
curtain is that some UiBinder-generated java code calls,%20boolean%29,
which in turns sets the Element classname javascript property. This does
not work for the SVG DOM, because, though SVG DOM objects also have a
classname property, it is not a string, but an SVGAnimatedString
(because CSS classname can be animated in SVG). Thus, in javascript, one
needs to change the classname.baseVal property to set the CSS className.
This is what is done the,
a method which is callable by UiBinder-generated code.

What you suggest:
.searchButton { float: left; padding-left: 10px; width: 25px; height:
25px; }
<svg:SVGImage ui:field='searchButton' resource='{}'
classNameBaseVal='{style.searchButton}' />

ought to work as it is the same thing I do in my widget sample
Since the sample is based on 2.7.0 and works, I do not think the problem
is related to a migration problem to 2.7.0

The error message you indicate seems to indicate that the resource is
somehow not set (the SVGImage svgElement, which ought to be se by
resource='{}', is undefined). Do you have a line like:
<ui:with field='res' type='...' />. Does it contain SVGResource or
SVGExternalResource ? In the latter case it probably would not work as
the svgElement would not be immediately available, but later, after the
async call to load the resource has completed.

Could this be a browser or OS problem ? I develop/test on linux
(opensuse13.2)+firefox(36) or chromium(41). Does the widget sample work
on your system ?
Otherwise there has to be a subtle difference someplace accounting for
the different behavior. I do not know how I can help you unless you can
create a minimalistic sample I could debug. Maybe another idea would be
to look at the generated code (in target/gen)


Geoff Huenemann

Mar 25, 2015, 12:54:39 AM3/25/15
Yes, there is a definition of:

    <ui:with field='res' type=''/>

and JostleClientBundle includes:

public SVGResource glass();

I agree that it looks like the element isn't there yet, and I suspected the external resource problem you mention, but that doesn't seem to be the issue.  And as I say, if I just remove the classNameBaseVal bit, it works fine. 

So you're saying your samples definitely work with GWT 2.7 for you?  In that case, I agree that there has to be something subtly wrong with my setup, because I copied a couple of them into my file and couldn't get them to work either.  Hmmmmmm.

I'll try again tomorrow.  Thanks for your help.

Geoff Huenemann

Mar 25, 2015, 12:31:23 PM3/25/15
So looking at your examples ( again, your UiBinder code is mostly not setting the className.for the SVG, just the class (styleName) for the svgContainer.  I can do that too with no trouble, but it's an extra div (no big deal) and isn't quite the same thing (setting fill colour wouldn't work, for instance).

It is setting the style on the "widgets" page, in the "hearts" svg, for instance.  However, when I copy that exact style and SVGImage declaration into my UiBinder code, it fails with the error mentioned above: (TypeError) : Cannot read property 'setClassNameBaseVal_2_g$' of undefined

The SVG I'm using is an SVGResource (not external) and works in all other expected ways.  PNGs in the same resource bundle (ImageResources) have no trouble setting styleName in analogous usages.

I'm not sure how much more time I can spend on this problem, given that I have a workaround, but I'd love to understand the pathology here.  Your library has otherwise been very useful to us, and we will continue to use it (at least until native SVG support comes to GWT...)

Any insight would be appreciated.

Reply all
Reply to author
0 new messages