GWT FocusPanel clickHandler not working when created with a element - java

Hello fellow GWT folks.
In my usage of GWT, I'm having an issue with a FocusPanel not handling the clickEvent that is added to it. I don't do GWT the standard way, ie building the GUI with UI binder or pure java code widgets. My host GWT HTML file is 1 large file that has div tags that represent the 'pages' of content. I use GWT to control the DOM.
I have this HTML that I'm importing as the contents of the FocusPanel.
<div id="editCardsResponses">
<div id="editCardsSuccess" class="success-box clickable">
<span id="editCardsSuccessLabel">Your card was successfully deleted/edit/added.</span>
<span class="glyphicon glyphicon-remove"></span>
</div>
...
</div>
Here's the Code...
RootPanel editCardsSuccess = RootPanel.get("editCardsSuccess");
FocusPanel editCardsSuccessPanel = new FocusPanel(editCardsSuccess);
editCardsSuccessPanel.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
hideWidget(editCardsSuccessPanel);
}
});
This didn't work until I did this...
final HTMLPanel editCardsSuccess = view.getEditCardsSuccess();
editCardsSuccess.addDomHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
hideWidget(editCardsSuccess);
}
}, ClickEvent.getType());
I even tried adding the FocusPanel to the parent DIV, thinking that the FocusPanel wasn't attached to the DOM, but that also didn't work.
RootPanel.get("editCardsResponses").add(editCardsSuccessPanel);
I would like to use the FocusPanel, as GWT wants to add a hidden input the DOM, in addtion to the element it wraps. I assume the hidden input handles some cross browser issue that I might lose if I just use the domHandler method.
Can anyone help explain why the FocusPanel.ClickHandler wouldn't be taking effect, but an attached domHandler would?
If DOM attachment is the problem, Is there a way to re-attach elements/widgets that were detached?
If I go with the domHandler way... what compatibility do I loose by not getting the hidden input that the GWT FocusPanel widget provides?

Add DOM ONCLICK handler event on the Element.
sample code:
final Element desc = RootPanel.get("editCardsSuccess").getElement();
DOM.sinkEvents((com.google.gwt.user.client.Element) desc, Event.ONCLICK);
DOM.setEventListener((com.google.gwt.user.client.Element) desc, new EventListener() {
#Override
public void onBrowserEvent(Event e) {
switch (DOM.eventGetType(e)) {
case Event.ONCLICK:
System.out.println("click");
break;
}
}
});

There is nothing wrong with adding a DOM handler the way you described. It will work across all browsers.

Related

How to popup html page from wicket page?

I am trying to popup a html page from wicket application. The html page will not have corresponding .java file. The page is static html page.
I tried to pop up html page which is a part of wicket application using following logic:
PopupSettings popupSettings =
new PopupSettings(PopupSettings.RESIZABLE | PopupSettings.SCROLLBARS).setHeight(500).setWidth(700);
Link link = new Link("link") {
#Override
public void onClick() {
System.out.println("clicked");
setResponsePage(PopupPage.class);
}
};
link.setPopupSettings(popupSettings);
add(link);
But for this to work i need to have html page with its java page. But in my requirement I have fixed html page (say test.html) and I want to pop up it.
Also I want to popup this html page on click of button. But I didn't get any method like setPopupSettings() for button. Can someone tell me the way in which I can implement it for a button?
The easiest way i can think of is to add button in your html:
<button type="button" wicket:id="popupButton">Pop</button>
And in the code you can do something like this:
add(new WebMarkupContainer("popupButton").add(AttributeAppender.append("onclick",
"window.open('test.html', 'popup', 'width=500,height=700,scrollbars=yes');")));
Or if you want it to be more dynamic, you can use a model:
add(new WebMarkupContainer("popupButton").add(AttributeAppender.append("onclick",
new AbstractReadOnlyModel<String>() {
#Override
public String getObject() {
return "window.open('test.html', 'popup', 'width=500,height=700,scrollbars=yes');";
}
})));

GWT History - Why does it change the focus of my screen?

I have a simple application structure that will contain three composites at any one time - my header, footer and content composites. The composites are laid out in the follow manner.
<body>
<div id="header">
<div id="content">
<div id="footer">
</body>
The composites are assigned to the three <div>'s in my EntryPoint. The EntryPoint also contains a History Handler as follows.
History.addValueChangeHandler(new ValueChangeHandler<String>() {
#Override
public void onValueChange(ValueChangeEvent<String> event) {
String historyToken = event.getValue();
if(historyToken.isEmpty()) {
parseTokens();
ContentContainer.INSTANCE.setContent(new IndexScreen());
}
else if(historyToken.equalsIgnoreCase("registration")) {
ContentContainer.INSTANCE.setContent(new RegisterScreen());
}
else if(historyToken.equalsIgnoreCase("login")) {
ContentContainer.INSTANCE.setContent(new LoginScreen());
}
}
});
History.fireCurrentHistoryState();
In my Composites, I have several ClickEvent handlers that look similar to the following.
#UiHandler("registerLink")
public void handleClick(ClickEvent event) {
ContentContainer.INSTANCE.setContent(new RegisterScreen());
History.newItem("registration", true);
}
This registers the history very nicely. It also brings me to the appropriate pages when I click the back button. However, it has the very odd effect of focusing the browser on the content composite, with the effect of the browser being scrolled to the bottom. It's not a deal breaker but it kind of breaks the user experience a little. (Do let me know if the explanation isn't clear, I'll add images)
What exactly is causing this and how can I fix it?
GWT history tokens work with the hash # token. In html this was originally intended to use the browser to focus on a specific part of the page, if an element has a name or id with the string after the # token. Could it be you have an id matching your history token?
Also in you handleClick you call setContent. But if I'm correct the call after it triggers a change event and will end up in the onValueChange, which also calls the setContent. So it looks like you are calling setContent twice here.

Which is the best Wicket component for rendering arbitrary HTML?

I am implementing a simple markdown wiki using Apache Wicket. The wiki would typically render any arbitrary HTML based on what the user has entered.
I am a bit confused about which Wicket component would be best suited to render such arbitrary HTML.
I tried the Label component but it does not render lists properly, neither does the MultilineLabel (which puts breaks instead of the regular list HTML).
Thanks for any help.
UPDATE: The Label component works perfectly. It was my mistake that I was not able to get it to work earlier. It was a combination of some bad stylesheets and late night coding. Thanks for the helpfull answers. As suggested, I am also going to check out some WYSIWYG editors, which actually might work out better than markdown. Visural Wicket seems especially promising.
If what you want to render is not big, or is already represented as a String, Label will work well, just call label.setEscapeModelStrings(false); to ensure it prints the string as is.
But, if your HTML content is generated dynamically, or read from an InputStream/Reader, and you don't want to keep it in memory, you could use WebComponent directly, and override the method onComponentTagBody(). This way, you write directly to the response, instead of filling a in-memory buffer, transform it to a String, and then write to the response (which happens if you use Label).
Sample code, for both cases:
HomePage.java
public class HomePage extends WebPage {
public HomePage() {
add(new Label("label", "<ul><li>test</li><li>test</li><li>test</li><li>test</li><li>test</li></ul>")
.setEscapeModelStrings(false));
add(new WebComponent("html") {
#Override
protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) {
Response response = getRequestCycle().getResponse();
response.write("<ul>");
for (int i = 0; i < 5; i++)
response.write("<li>test</li>");
response.write("</ul>");
}
});
}
}
HomePage.html
<html xmlns:wicket="http://wicket.apache.org">
<body>
<h2>Label</h2>
<div wicket:id="label"></div>
<h2>WebComponent</h2>
<div wicket:id="html"></div>
</body>
</html>
It is Label, call Component.setEscapeModelStrings(false) though to render the raw html your model returns.

GWT adding Event Handler overrides the native one?

lets say i have the following html element on my host page:
<input type="text" onfocus="this.value = ''" id="textField"/>
In gwt i wrap this into an TextBox Widget like this:
final TextBox myTextBox = TextBox.wrap(DOM.getElementById("textField"));
If i now want to add a focus handler what will happen?
myTextBox.addFocusHandler(new FocusHandler() {
public void onFocus(final FocusEvent event) {
// do something
}
});
What i want to achieve is that first the javascript which was defined on the host page should be executed and after that my focus handler should be executed. But what actually is happening is that the javascript from the hostpage is not being executed and only the code within onFocus is executed. Is this behavoir normal? I would expect that add means actually add and not override. Is there a way to work arround this? Or do i maybe have any flaws which induce this behavoir. Any help is appreceated.
kuku

How to mix html with gwt widgets?

I try to generate a dynamically gwt ui. As a result I would get a html fragment like this:
<ol>
<li>MyLabel</li>
<li><input type="text"></li>
</ol>
The Label should be a GWT Label and the input should be a GWT TextBox.
How can I achieve this with GWT? I've tried to use the HTMLPanel class, but how can I inject the
<li>
Tags?
I can't use UIBinder, since I would like to dynamically create such fragments as shown above.
You should create your own subclass of ComplexPanel. This will give you something that works much the same as a HorizontalPanel or VerticalPanel, only based on list elements rather than table elements. It should look something like this:
public class OListPanel extends ComplexPanel {
final OListElement ol = Document.get().createOLElement();
public OListPanel() {
setElement(ol);
}
public void add(Widget w) {
LIElement li = Document.get().createLIElement();
ol.appendChild(li);
add(w, (Element)li.cast());
}
public void insert(Widget w, int beforeIndex) {
checkIndexBoundsForInsertion(beforeIndex);
LIElement li = Document.get().createLIElement();
ol.insertBefore(li, ol.getChild(beforeIndex));
insert(w, (Element)li.cast(), beforeIndex, false);
}
public boolean remove(Widget w) {
Element li = DOM.getParent(w.getElement());
boolean removed = super.remove(w);
if (removed) {
ol.removeChild(li);
}
return removed;
}
}
I haven't tested that but it's basically right. WRT the markup you posted in your question, this code will produce one slight difference, since GWT labels have their own <div> element:
<ol>
<li><div>MyLabel</div></li>
<li><input type="text"></li>
</ol>
You might prefer InlineLabel, which is based on the less intrusive <span> element.
You can always do something like:
Document doc = Document.get();
final OListElement ol = doc.createOLElement();
LIElement li = doc.createLIElement();
li.appendChild((new Label()).getElement());
ol.appendChild(li);
li = doc.createLIElement();
li.appendChild((new TextBox()).getElement());
ol.appendChild(li);
panel.add(new Widget() {{
setElement(ol);
}});
Why not put that fragment in a standalone Widget created via UiBinder? (if you know how the structure will look beforehand and just want to insert MyLabel and a TextBox)
Don't be afraid to split your widgets like this - the GWT Compiler is great at optimizing and UiBinder templates are processed at compile time so there shouldn't be any performance penalty (benchmarking is still strongly recommended - YMMV). I'd even say that it'd be faster then trying to add this structure via the DOM package - with UiBinder, the compiler knows what it's dealing with, with DOM you are basically saying: "I know what I'm doing, don't touch my code!" (at least that's my view on this :)). HTMLPanel could be an alternative, but you'd have to assign an id to every element you want to modify/attach stuff to... :/
Bottom line: use UiBinder for this, that's what it was built for.

Categories