Since the pages I am going to display contain a lot of text, which I want to pre-format in their own text-files, I do the following:
execute: onModuleLoad()
- make an Async call to the server and load
the text files which are html-formatted
The code looks like this:
homeAsync.load(new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
contentHome.add(new HTML("<h1>FAIL</h1>something went wrong"));
caught.printStackTrace();
}
public void onSuccess(String result) {
contentHome.getElement().setId("inner");
contentHome.add(new HTML(result));
//RootPanel.get("content").add(new HTML(result));
}
});
Now.. inside those text-files are some customized tags:
<!graph>
which I want to replace with some GWT widgets. My problem is, that I just don't know how I could accomplish that easily.
I could do a work around like:
- load text part 1 (async call)
- insert graph for part 1
- load text part 2 (asynca call)
- insert foobar
- and so on ..
I don't even know if this would work but to be honest.. that's simply too ugly ^^
Any suggestions for me?
Knowing the part1 and part2 two makes things much clear.
Yes you can render all the HTML content to the widget (But in a Safe way,Yes Talking about SafeHtml).
And avoid two RPC calls to fetch the strings from DB.If you know part1 and part2 load the string at a time (with an Identifier and split it on client side).
Use HTMLPanel as a template.
An example:
String html = "<div id='one' style='border:3px dotted blue;'></div>"
+ "<div id='two' style='border:3px dotted green;'></div>";
HTMLPanel panel = new HTMLPanel(html);
panel.setSize("200px", "120px");
panel.addStyleName("demo-panel");
panel.add(new Button("Do Nothing"), "one");
panel.add(new TextBox(), "two");
RootPanel.get("demo").add(panel);
You can use following methods also:
Label w = new Label();
w.getElement().setInnerHTML(html);
w.getElement().setInnerSafeHtml(safeHtml);
Related
I use RPC calls to connect to mySql and bring text data from there.
My page is defined as split Layout.
my problem is that I don't know how to update the main layout with different text.
if i use the clear() method it will remove all the layout !
"p" is the splitLayout.
RPC:
rpcService.getChapterTxt(selectedBook,bookChapters[selectedBook],
new AsyncCallback<List<BibleTxt>>(){
public void onFailure(Throwable caught)
{
Window.alert("Failed getting Chapter");
}
public void onSuccess(List<BibleTxt> result)
{
int i = 0 ;
String verseText ="";
//Label verseLabel = new Label();
PPanel chapterPar = new PPanel();
HTML page= new HTML(verseText);
for(i=0;i<result.size();i++)
{
verseText = result.get(i).getVerseText();
//verseLabel.setText(verseText);
page.setText(page.getText() + verseText);
}
chapterPar.add(page);
//p.clear();
p.add(chapterPar); // adds the main layout
}
});
Why you don't reuse the text component changing its content text instead of continuously detaching/attaching elements to the widget hierarchy. That way should perform better and cause less problems.
I am using wicket 1.4.17.I went through quite a few posts on this but couldn't understand it clearly. How can I make an accordion in wicket?
Basically what I am looking for is kind of a table with 1 column and multiple rows where each row can be expanded or collapsed, and each row on expansion shows another table of data.
The following code example should help you get started.
Feel free to ask questions if something seems unclear. Of course you could go even deeper in your DetailPanel (that's why I would suggest that approach)
AbstractRepeater exampleView = new ListView<Object>("exampleView", myList) {
#Override
protected void populateItem(ListItem<Object> item) {
//you can use a own panel, fragment, etc to illustrate your detail view here
//you could also use one WebMarkupContainer for visibility - but I'd assume this will get very messy, very soon
final DetailPanel detailPanel = new DetailPanel("detailPanel", item.getModel());
detailPanel.setVisible(false);
detailPanel.setOutputMarkupPlaceholderTag(true);
item.add(detailPanel);
//add AjaxLink to switch between the visibilty of the detailView
AjaxLink<Void> detailLink = new AjaxLink<Void>("detailLink") {
#Override
public void onClick(AjaxRequestTarget target) {
detailPanel.setVisible(!detailPanel.isVisible());
target.addComponent(detailPanel);
}
};
item.add(detailLink);
}
};
add(exampleView);
I want to fetch an image from a remote server (not my app's server, but I don't think that matters) and display it in an existing Image widget. The existing widget displays its original content, from a ClientBundle ImageResource , OK.
In UiBinder template:
<g:Image ui:field='myImage' resource='{res.anImage}'/>
In code:
#UiField Image myImage;
...
int width = Window.getClientWidth();
int height = Window.getClientHeight();
String url = ...;
myImage.addErrorHandler(new ErrorHandler() {
public void onError(ErrorEvent event) {
Window.alert("Error getting image data: " + event);
}
});
myImage.addLoadHandler(new LoadHandler() {
public void onLoad(LoadEvent event) {
Window.alert("LoadEvent: " + event);
}
});
myImage.setUrlAndVisibleRect(url, 0, 0, width, height);
As far as I can tell setUrlAndVisibleRect is a no-op. FireBug reports no network activity -- no request to the server specified by the URL. What am I overlooking? In my extended thrashing about trying to get this working I have inferred that it may have something to do with myImage not being "logically attached", but I'm not entirely sure what that means and I've no idea how to correct it if that is the problem.
EDIT with SUMMARY of SOLUTION:
My initial hunch was right. Because I had chosen to implement the image code within a second pseudo-widget (...extends Composite) that shared my UiBinder template with the main pseudo-widget that implements most of my app's UI, I got into trouble. I neglected to add this second pseudo-widget to the RootPanel as is normally done in the class that implements EntryPoint. This left my Image widget unattached to the widget chain, because its parent, the second pseudo-widget, was unattached. And an Image widget must be attached to work. What I ended up doing is moving the Image code back into my main app/GUI class, i.e., into the first and now only pseudo-widget and abandoning the special class for the Image code. I did that because it's simpler and the Image code turns out not to be as long as I had originally thought.
Adding image to the DOM is little tricky,the below code which supports all the browsers(setVisibility trick added to support IE also,as It has a different way to image rendering).
I did'nt use setUrlAndVisibleRect before and AFAIK,Image must render to the DOM inorder to resize it.Just try the below codes.
image.addLoadHandler(new LoadHandler() {
#Override
public void onLoad(LoadEvent event) {
//Do your operations on image .//resize ..etc
image.getElement().getStyle().setVisibility
(Style.Visibility.Visible);
}
});
image.getElement().getStyle().setVisibility(Style.Visibility.HIDDEN);
RootPanel.get().add(image);
image.setUrl(url);
You are using ClientBundle ImageResource which is compile time. You cannot change it unless you replace the new image with exact name in the exact position of prev one. One of the possible hack which is possible is, place the image in a div with its ID set ( getElement().setId("your ID") ). Once you get you new image you use RootPanel.get("Your Id") and do your job.
I'm using a GWT library (gwt-openlayers) which allows me to create a map popup containing arbitrary HTML, similar to Google Maps. I need this HTML to contain a GWT Button widget.
I'm creating some HTML elements on-the-fly like this:
Element outerDiv = DOM.createDiv();
outerDiv.getStyle().setOverflow(Overflow.HIDDEN);
outerDiv.getStyle().setWidth(100, Unit.PCT);
outerDiv.appendChild(new HTML(mapPOI.getHtmlDetails()).getElement());
Button popupButton = new Button("View Property");
popupButton.getElement().getStyle().setFloat(com.google.gwt.dom.client.Style.Float.RIGHT);
outerDiv.appendChild(popupButton.getElement());
Then I'm getting the source HTML for these elements by calling
String src = outerDiv.toString();
and inserting this html into my map marker. Now my map marker displays the content ok, including the button. However, the button won't respond to any events! From what I can gather, this is because the buttons onAttach() method is never being called.
Is there a better way to do this?
Thanks,
Jon
~~~~EDIT~~~~
I'm now trying a new way of doing this, which seems to be the accepted method looking at other similar posts.
First I'm creating my div:
String divId = "popup-" + ref;
String innerHTML = "<div id=\"" +divId + "\"></div>";
Then I'm adding this to my map popup and displaying it (which adds it to the DOM). After the popup has been displayed, I'm getting the Element as follows and trying to wrap a HTMLPanel around it:
Element element = Document.get().getElementById(divId);
HTMLPanel popupHTML = HTMLPanel.wrap(element);
My div element is successfully retrieved. However, HTMLPanel.wrap(element); doesn't complete. The reason for this is that wrap(..) calls RootPanel.detachOnWindowClose(Widget widget), which includes the following assertions:
assert !widgetsToDetach.contains(widget) : "detachOnUnload() called twice "
+ "for the same widget";
assert !isElementChildOfWidget(widget.getElement()) : "A widget that has "
+ "an existing parent widget may not be added to the detach list";
I put some breakpoints in and it seems that the 2nd assertion is failing!
Does anybody have any idea why this might be the case? Should failing this assertion really result in a complete failure of the method (no return)?
Your first approach is good, you just need to register onClick event for your button like this:
DOM.sinkEvents(popupButton.getElement(), Event.ONCLICK);
DOM.setEventListener(popupButton.getElement(), new EventListener() {
#Override
public void onBrowserEvent(Event event) {
//implement the logic after click
}
});
I have checked this, it works 100%!
You might try something like
RootPanel.get("idOfYourMapMarker").add(popupButton);
See RootPanel.get()
Unfortunately, RootPanels are AbsolutePanels which aren't so nice for layout but could work if you just have a simple button to add. You could also try RootLayoutPanel which will give you a LayoutPanel (also not so nice when you just want things to flow). You might end up creating a container widget that does the layout for you, and adding that to the RootPanel.
SimplePanel is a DIV. Perhaps that can be used instead?
You added the element, but you have to keep the hierarchy of the actual GWT Widgets too.
I don't see a clean way to do this, but you could use something like jQuery to grab the button by and ID and add a click handler back to it that would call the original click handler.
private static native void registerEvents(String buttonId, MyClass instance)/*-{
var $ = $wnd.$;
//check click
$('#'+buttonId).live('click', function(e) {
e.preventDefault();
instance.#com.package.MyClass::handleButtonClick(Lcom/google/gwt/event/dom/client/ClickEvent;)(null);
});
}-*/;
Call this registerEvents() either in your onAttach or constructor.
I once had a similar problem. You can use the gwt-openlayer's MapWidget as follows:
private MapWidget createMapWidget() {
final MapOptions defaultMapOptions = new MapOptions();
defaultMapOptions.setDisplayProjection(DEFAULT_PROJECTION);
defaultMapOptions.setNumZoomLevels(TOTAL_ZOOM_LEVELS);
MapWidget mapWidget = new MapWidget(MAP_WIDGET_WIDTH, MAP_WIDGET_HEIGHT, defaultMapOptions);
map = mapWidget.getMap();
return mapWidget;
}
And then add it to any panel be it vertical or horizontal.
MapWidget mapWgt = createMapWidget();
VerticalPanel mainPanel = new VerticalPanel();
mainPanel.add(mapWgt);
...
... add whatever you want
...
You can finally add the created Panel(containing the MapWidget and the gwt widget) to the PopupPanel. Also, you should now be able to add handlers to the gwt button.
I've been working with GWT for awhile, I can't find a way to integrate it with a preexisting website which is a real downer. My page content is already generated for me using jsp, like:
<div id='A'></div>
<div id='B'></div>
etc.
there is no way for me to do something like this though:
public void onModuleLoad() {
SimplePanel spA = new SimplePanel(
Document.getElementById("A"));
spA.add(new Label("hello"));
SimplePanel spB = new SimplePanel(
Document.getElementById("B"));
spB.setWidth("200px");
etc ..
}
seems like there's no way to just wrap a pre-existing element. Is this true, or am I missing how to do this? I need be able to wrap a bunch of elements like this, to manipulate them later on. I see TextBox, Button, a few other classes have wrap() methods, however nothing like that exists for elements,
Thanks
There is a way to wrap existing DOM elements, like Label's wrap() method. For example:
Label label = Label.wrap(DOM.getElementById("A"));
label.setText("Foo!");
Other GWT classes can wrap DOM elements too, like Button, and CheckBox using its constructor.
Use HTMLPanel:
class MyPanel extends HTMLPanel {
private SimplePanel a = new SimplePanel();
private SimplePanel b = new SimplePanel();
public MyPanel() {
super("<div id="a"></div><div id="b"></div>);
addAndReplaceElement(a, "a");
addAndReplaceElement(b, "b");
}
}