JavaScript libraries like jQuery have the ability to dynamically add/remove classes to DOM elements like so:
$("#some-element").addClass("make-me-pretty");
This is important because it allows you to dynamically apply different styling rules to those elements.
In GWT-land, you might have a UiBinder XML snippet like this:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:gwt="urn:import:com.google.gwt.user.client.ui">
<div>
<span id="">Some content</span>
<gwt:RadioButton ...>
...
</gwt:RadioButton>
<!-- etc. -->
</div>
</ui:UiBinder>
For the non-Widget elements, such as the <span>, how can I dynamically add/remove classes in the Java code?
Speaking of <gwt:RadioButton>, I can't seem to find GWT's reference XSD for UiBinder XML, or some kind of official reference to the legal definitions for all the elements and attributes of com.google.gwt.* XML. For instance, where can I find documentation for what child elements and attributes gwt:RadioButton supports? And not just for that one widget, for all of them! Can someone point me in the right direction?
Thanks in advance!
You can find the UiBinder.xsd in gwt-user-<version>.jar (At least from 2.4.0 onwards, but I suspect older versions as well).
As for your other question: You can always traverse the DOM using
yourUi.getElement().getElementsByTagName( "span" )
and find the Element with the matching id, but that isn't very elegant. I actually have never encountered this situation; it is an interesting question!
Hope that helps.
Cheers,
To any UIobject (including RadioButton) you can:
yourUI.addStyleName("your-class");
in GWT: styleName = class
More UIObject methods
I think you can do something like this.
Map your as a UI field to a GWT 'SpanElement'.
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
<div>
Hello, <span ui:field='nameSpan'/>.
</div>
</ui:UiBinder>
In your class that binds to the above ui.xml file, you could change the class as follows
interface MyUiBinder extends UiBinder<DivElement, HelloWorld> {}
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
#UiField SpanElement nameSpan;
public HelloWorld() {
setElement(uiBinder.createAndBindUi(this));
}
public void changeClass(){
nameSpan.setClassName("newClass");
}
I guess you have a html page where you load your widgets into.
You could assign a class in the **.ui.xml file exactly like in a html page.
<div class="MyClass" align="middle">
<gwt:VerticalPanel>
.......
</gwt:VerticalPanel>
</div>
Then write you css rule in you main.css file.
.MyClass{background-color:black;}
When the view is loaded the the main.css file will "see" the name of the class and act upon it.
Related
Is it possible to extend existing wicket (= append additional property/textbox in existing wicket html) if the base wicket doesn't contain <wicket:child/> tag?
For example, I want to extend some java class which uses the following html:
<wicket:panel>
<div class="field-wrapper"><input wicket:id="field1" type="text"/></div>
[I WANT TO INJECT ANOTHER TEXTBOX HERE]
</wicket:panel>
My extended class inherits all base properties from inherited class, and I declared an additional property. But I don't know if/how I can append the additional property in base html, without having to clone the whole original html and adding my new propery, which is not elegant solution.
Is there any event I can attach to where I can modify original html (inject my property) before it is parsed / rendered?
You can override #getMarkup() method and modify its result but it would be more hack-ier than just providing a complete .html file with your modifications.
Providing your own markup file is totally elegant for me!
One way to do this is to define a method in your base page that returns a Fragment which will be inserted into the 'childContent' below:
<wicket:panel>
<div class="field-wrapper"><input wicket:id="field1" type="text"/></div>
<div wicket:id="childContent"></div>
</wicket:panel>
So in your base page you would have this function that by default returns null, but extending pages can override it to provide their own specific content:
protected Fragment getChildContent() { return null; }
And your base page will use it as follow:
Fragment childContent = getChildContent();
if(childContent != null) {
addOrReplace(childContent);
} else {
addOrReplace(new WebComponent("childContent").setVisible(false));
}
Than in your extending page you can define a Fragment with it's own html and override the getChildContent() method to return it.
Hope that helps!
I am migrating some JSP files to Thymeleaf and I have found the following problem. In the original JSP code there is a file that is included in lots of other JSP files that has a line like the following:
<c:set var="myVar" value="data-x=50 data-y=37" />
In the files which include this one the variable myVar is used like this:
<div class="myClass" ${myVar}>
setting several attributes that are used everywhere all at once. The main point here is that you set up myVar in one file and its values are used in all other files. If you need to change the value of the attributes you only need to change one file.
Trying to replicate this in Thymeleaf, I tried using the th:attr attribute in the following way. First, I set a variable in the model like this:
model.addAttribute("myVar", "data-x=50, data-y=37");
and then in Thymeleaf I do:
<div class="myClass" th:attr="${myVar}" >
but it does not work, it throws
TemplateProcessingException: Could not parse as assignation sequence: "${myVar}"
I've also have thought of using Javascript to add the attributes dynamically using JQuery, but I would prefer to do it in other way, since I did not built the application, it has a lot of scripting and I fear doing it through Javascript can have side effects.
Is there any way I can write directly in the HTML output using Thymeleaf?
One way you can accomplish this with preprocessing. Something like this will work with your example:
<div class="myClass" th:attr="__${myVar}__" />
(This does rely on ${myVar} being a valid string for the th:attr property, so you'll have to be careful with it.)
Im new at vaadin 7 and have a little issue with formatting.
I have spend a few hours but no luck.
I have:
2 Form layouts on my vertical Layout.
2 Labels on each form layout.
Better check the screenshot
I want format label test as on the right part of screenshot.
Can you please advice or share thoughts or ideas.
I'm not 100% certain if I get what you're trying to do, but you might be able to achieve this through custom CSS.
It is hard to write out the exact CSS since it would require seeing the HTML generated by Vaadin and testing it with that, but it would be something like this for the labels:
.padded-form-layout v-caption:first-child {
float: left;
padding-left: 30px; /* set desired padding used for each label */
}
Of course, you'll need something similar for the values as well.
Above, padded-form-layout is the class name you define for layouts that need this look. In Java:
formLayout.setStyleName("padded-form-layout");
To figure out what the CSS modifications needed are I recommend you open the page in browser (Chrome or Firefox will do) and use the dev tools to directly modify the CSS to figure out what rules are needed. I usually do this by simply typing a style tag to the element, something like this (in this example, style="XXXXX" would be added manually. This is possible at least with Chrome's developer tools):
<div class="v-formlayout v-layout v-widget v-has-width" style="width: 100%;">
<!-- ... -->
<td class="v-formlayout-captioncell">
<div class="v-caption v-caption-hasdescription">
<span id="gwt-uid-21" for="gwt-uid-22" style="XXXXX">First name:</span>
<span class="v-required-field-indicator" aria-hidden="true">*</span>
</div>
</td>
<!-- ... -->
</div>
To be able to use the CSS, you'll need to either add it to your theme somehow and compile it (see Vaadin documentation about themes), or by using the #StyleSheet annotation
I have created a handy tag library for my JSP page. It looks like this:
<myTag:getContent>
<div id="metadata">
<myTag:printContent arg="meta"/>
</div>
<div id="data">
<myTag:printContent arg="data"/>
</div>
</myTag>
getContent contains a RESTful web service that initializes and sets a few variables so that when I use the printContent with their respective arguments, it just has to print the variables as opposed to re-fetch the content.
The problem is that in the practical application, the calls to print contents lie deep inside different page snips:
<myTag:getContent>
<jsp:include page=".../.../.../this.jsp"/>
<jsp:include page=".../.../.../that.jsp"/>
</myTag>
I have the myTag library defined at the top of each page, but I am getting:
java.lang.NullPointerException
in the internal JSPs at the "myTag:printContent"
What do I do? Is this even possible considering the real internal jsp pages have other tag libraries and logic?
The getContent is the following attribute inside the .tld (tag library descriptor)
<body-content>JSP</body-content>
Well it seems like the good old step back and look problem is real here. I switched the jsp:includes to directive includes. For those who are unfamiliar:
<myTag:getContent>
<%#include file=".../.../.../this.jsp"%>
<#%include file=".../.../.../that.jsp"%>
</myTag>
This works because now the scope is relevant as the include here is static at translation time vs jsp:include which is dynamic at request time.
I have custom JSP tags that generate some HTML content, along with some javascript functions that get called by this HTML code. In the current implementation, the SCRIPT tags are created just above the HTML code.
To avoid modifying the existing code base, I want to pull up these scripts inside the HEAD section of the page using SiteMesh or some other decorator tool.
I know SiteMesh can extract content from <content tag="..."> elements, but I was wondering if it was possible also with other tags, such as SCRIPT.
Is this possible with SiteMesh, or know of any tools that could allow me to do that?
Thank you!
SiteMesh's HTMLPageParser is extensible, so you can add your own custom rule to extract <script> elements by extending HTMLPageParser and configuring SiteMesh to use your class instead of HTMLPageParser, something like this:
import com.opensymphony.module.sitemesh.parser.HTMLPageParser;
public CustomPageParser extends HTMLPageParser {
protected void addUserDefinedRules(State html, PageBuilder page) {
super.addUserDefinedRules(html, page);
html.addRule(new ScriptExtractingRule(page));
}
}
I imagine your ScriptExtractingRule would be modeled after the standard SiteMesh ContentBlockExtractingRule, storing the content in the page context so your decorator can access the blocks as if they were <content> blocks.