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

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.

Related

Java Spring MVC form:checkboxes - how to know if any were checked

Say I have the following line in my JSP:
<form:checkboxes path="appliedPlayers" items="${suitablePlayers}" itemValue="id" itemLabel="displayName" />
I would like to disable the form-submit button when none of the checkboxes are checked. Something like:
$('#checkboxes').change(function() {
if (none_are_checked)
disableBtn();
});
Spring form tags does not support this. You can check the following link for supported attributes.
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/spring-form-tld.html#spring-form.tld.checkboxes
What can be done is, you can handle this scenario at the client side using jQuery(like you mentioned).
<script>
$(document).ready(function(){
$('input[name=players]').change(function() {
//alert('hello');
var checkedNum = $('input[name="players[]"]:checked').length;
if (!checkedNum) {
// User didn't check any checkboxes
disableBtn();
}
});
});
</script>
Explanation: in the above code snippet, when checkbox element changes then the registered function gets called which counts the number of selected checkbox elements. If zero then it enters if condition which is the requirement.
Note: above example assumes html attribute name value for checkboxes are players. You can change your jquery selectors appropriately if needed.
Credit:
https://stackoverflow.com/a/16161874/5039001

GWT FocusPanel clickHandler not working when created with a element

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.

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

(Wicket) Change visibility during ajax response

I have a AjaxPagingNavigator. Basically on a certain condition, the list which the AjaxPagingNavigator pages is reloaded. When this happens I only want to render the navigator when the list contains more than 1 page.
So does anyone know where I can attach a handler so that I can check for a visibility condition in my AjaxPagingNavigator and enable/disable visibility so that when the navigator is updated via. ajax it is either visible or not?
Markup:
<div wicket:id="mainWrap">
<div wicket:id="navigator"/>
<div wicket:id="listWrap">
<div wicket:id="list><!-- here be content --></div>
</div>
</div>
So I have an ajax event which refreshes "mainWrap" which refreshes the "navigator" along with the "list" and wrappings.
this is the event that triggers the whole thing.
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
List foo = null; // do work to get list
model.setFound(found); // update the model (thus updating "list")
target.addComponent(mainWrap);
}
Edit: I know I can write
navigator.setVisibility(list.getPageCount() > 1);
after creating the navigator and after updating the model, but I was hoping to encapsulate that in a subclass of AjaxPagingNavigator.
Be careful with doing expensive computations in an overridden isVisible method, as Wicket will call isVisible multiple times per request—not counting any calls you might inadvertently do.
Typically the best way to go about this is to override onConfigure and set the visibility flag manually.
#Override
void onConfigure() {
super.onConfigure();
setVisible(isVisible() && someExpensiveToCalculateCondition);
}
onConfigure is called just once during request processing, and called for all components, including those that are invisible (while onBeforeRender is only called for visible components).
It's been a while since I touched Wicket, but if memory serves:
Can you not override the isVisible() method of your "navigator" object, such that it only displays under the condition you desire?
e.g. something like
.addComponent(new AjaxPagingNavigator(...) {
#Override public boolean isVisible() {
return model.getFound().size() > 25;
}
});

Categories