GWT RichTextArea ReadOnly Workaround - gwt

GWT's RichTextArea doesn't have a method to make it "ReadOnly".
There's a setEnabled() method, but if you call setEnabled(false), it doesn't work.
I'm trying a workaround for this that should work. My idea is to replace the RichTextArea for this behavior with a HTML widget.
The problem is, if I use an HTML widget to set the original RichTextArea's content, it will be affected by all the styling of my web application.
The RichTextArea achieves this wrapping the content inside an IFrame.
So i'm trying to mimick that, doing something like this:
public class RichTextAreaReadOnly extends Composite
{
protected HTML instance;
public RichTextAreaReadOnly()
{
this.instance = new HTML();
this.initWidget(this.instance);
}
public void setHTML(String html)
{
this.instance.setHTML("<iframe class=\"gwt-RichTextAreaReadOnly\">"
+ "<html>"
+ "<head></head>"
+ "<body>"
+ html
+ "</body>"
+ "</html>"
+ "</iframe>");
}
}
The problem is, for some strange reason the body appears empty.
If I try this:
public void setHTML(String html)
{
this.instance.setHTML("<html>"
+ "<head></head>"
+ "<body>"
+ html
+ "</body>"
+ "</html>");
}
(note: without the iframe tag)
It works but the styling is incorrect because it is being affected by styles it shouldn't be.
Any idea of why when I use HTML.setHTML() to create an IFrame, the body tag appears empty???

Related

Show loading Screen while Image is loading in wicket

I'am populating a ListView with images.
In pseudocode:
populateItem(model){
load base64 from database
image.setDefaultModel(base64)
The image is just a webcomponent and in html it is just <img src="">
How can i show a indicator while the image is loaded?.
I first thought of adding IAjaxIndicatorAware but this triggers the indicator when the image is doing an AjaxRequest.
Since you seem to load and display the image as a Base64 src it will directly get send in the html response and not loaded later (in contrast to images with a src that links to another URI).
You could wrap the image in an AjaxLazyLoadPanel.
This will first display an AjaxIndicator while the content is generated and get later replaced by the actual loaded content once it is done loading/generating:
edit
I got an Exception : Component must be applied to a tag of type [img].
i didn't consider that problem. AjaxLazyLoadPanel allways uses a <div> as a html tag to display the component it loads. To display a base 64 image you would need to wrap it in another Panel:
public class Base64ImagePanel extends Panel {
public Base64ImagePanel(String wicketId, String base64Data, String contentType) {
super(wicketId);
WebMarkupContainer image = new WebMarkupContainer("image") {
protected void onComponentTag(ComponentTag tag) {
super.onComponentTag(tag);
checkComponentTag(tag, "img");
tag.put("src", "data:" + contentType + ";base64," + base64Data);
}
}
add(image);
}
}
Base64ImagePanel.html:
<wicket:panel>
<img wicket:id="image"></img>
</wicket:panel>
And then use that wrapper Panel in the AjaxLazyLoadPanel:
add(new AjaxLazyLoadPanel("imageLazyLoad") {
#Override
public Component getLazyLoadComponent(String id) {
//load your actual base64 from database, i use some example Strings for demonstration in the following line
Base64ImagePanel imagePanel = new Base64ImagePanel(id, "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==", "image/png");
return imagePanel;
}
});

Setting background image dynamically in wicket application

In my wicket application there are pages for users depending upon their role and on different criteria. In my database I am storing the path of image to be used as a background for that user. Every user has a unique page. I know I can add read image if I do something like this :
<img wicket:id="img">
and corresponding to this I am writing the code which will get image for me .
But how can I set the image as body background dynamically .I am pretty much new to wicket .Can anybody have a clue how to do that ?
In your page you can do it with some header contribution:
#Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.render(CssHeaderItem.forCSS("body{ background-image: url('" + getBackgroundBodyImagePath() + "');};", "uniqueBodyBackground"));
}
Or you could assign a wicket id to your <body> element and add an AttributeModifier like this:
#Override
protected void onInitialize() {
super.onInitialize();
bodyElement.add(AttributeModifier.replace("style", "background-image: url(" + getBackgroundBodyImagePath() + \"');"));
}

Insert Widget into pure HTML-code

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);

Can we load basic javascript function in a webview?

I have implemented a function in webview. I put the javascript function in the html head then load it through web.loadUrl but the webview does not take the function into consideration. Is it possible to load it this way ? or am I on the wrong track ?
"<td><a href='' onclick=\"displaying('image url')\" id=/image"+my_image[i] +"/"+"
class='popup-open'><img
src='"+my_image[i]+"'"+
"width='80' height='65'></a></td></tr><tr>";
the hmtl content
String webData = "<!DOCTYPE html>" +
"<head> "+
"<script>"+"function displaying(url)
{document.getElementById('image').innerHTML =\"<img src=\"url\" width=\"100\" height=\"105\">\";}"+"</script>"
+
" </head><body>"+ html_content +"</tr></table></body></html>";
Maybe is your JavaScript or some syntax shit. First of all, try to figure out what's the error message from WebKit engine.
To display webview's javascript messages, put onConsoleMessage in implementation.
myWebView.setWebChromeClient(new WebChromeClient() {
public boolean onConsoleMessage(ConsoleMessage cm) {
Log.d(cm.message() + " -- From line "
+ cm.lineNumber() + " of "
+ cm.sourceId());
return true;
}
});
Make sure you have following enabled
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);

CodeMirror-UI in smartGWT tab

I have a question regarding the integration of CodeMirror UI in a smartGWT tab.
Basically, I can't display the CodeMirror-UI editor inside the textarea element I attached to a smartGWT tab. Here's what I did:
I installed CodeMirror-UI as described on its page, correcting the paths to match my project's directory hierarchy
I wrote a js script in my project's main html (at head) :
<head>
...
<script>
function fireEditor()
{
var textarea = window.document.getElementById('tab_editor' );
var uiOptions = { path : 'codemirror-ui/js/', searchMode : 'inline' };
var codeMirrorOptions = { mode: 'javascript' };
var editor = new CodeMirrorUI(textarea,uiOptions,codeMirrorOptions);
}
</script>
</head>
I invoked the script while opening a (smartGWT) tab:
// create a smartGWT tab
Tab tab = new Tab("tab");
tab.setID("tab");
tab.setCanClose(true);
// put the CodeMirror UI inside the smartGWT tab
// create a smartGWT canvas
Canvas tabContent = new Canvas();
tabContent.setID("tabc");
tabContent.setWidth100();
tabContent.setHeight100();
// use a GWT HTMLPanel to attach new html elements to the smartGWT canvas
// and invoke the fireEditor() function to load the CodeMirror UI
HTMLPanel editorContainer = new HTMLPanel(
"<div id=\"editor_container\">"
+ "<textarea id=\"tab_editor\" style=\"width:100%;height:100%\" onload=\"fireEditor()\">"
+ "</textarea>"
+ "</div>");
editorContainer.setWidth("100%");
editorContainer.setHeight("100%");
running from a browser (I'm using firefox - iceweasel 10.0.10), this results in a smartGWT tab that shows an empty textarea element.
Checking with firebug, the area within the smartGWT tab contains the HTML I specified in the HTMLPanel, but no CodeMirror UI is shown.
What am I missing?
I'm using Eclipse Indigo, with gwt 2.4.0, smartgwt 3.0p, and codemirror ui 0.0.19 from its git repo (which itself uses CodeMirror 2.3).
Thank you
Found the solution.
First of all, there is no "onload" event for an html textarea element, so the code
HTMLPanel editorContainer = new HTMLPanel(
"<div id=\"editor_container\">"
+ "<textarea id=\"tab_editor\" style=\"width:100%;height:100%\" onload=\"fireEditor()\">"
+ "</textarea>"
+ "</div>");
will just place a textarea in the HTMLPanel, without calling "fireEditor()".
Replacing "onload" with "onclick" does the trick: once the textarea element shows up, click on it, and the CodeMirrorUI will show up as well.
Problem: I need to visualize the CodeMirrorUI interface automatically, ergo the "onclick" approach is useless.
To accomplish this task, I need to somehow modify the DOM of the smartGWT tab, replacing its inner html with CodeMirrorUI's html.
I found this documentation very helpful: http://www.smartclient.com/smartgwtee-latest/javadoc/com/smartgwt/client/docs/DomIntegration.html
this is the resulting code:
1) I kept the js script in my project's main html (at head) :
<head>
...
<script>
function fireEditor()
{
var textarea = window.document.getElementById('tab_editor' );
var uiOptions = { path : 'codemirror-ui/js/', searchMode : 'inline' };
var codeMirrorOptions = { mode: 'javascript' };
var editor = new CodeMirrorUI(textarea,uiOptions,codeMirrorOptions);
}
</script>
</head>
2) I created a new class -"MyEditor", following the example found in the documentation link I mentioned above :
public class MyEditor extends Canvas {
private String editor_id = null;
private static native void replace(String editor) /*-{
$wnd.fireEditor(editor);
}-*/;
public MyEditor(Integer num) {
editor_id = "editor_" + num;
setRedrawOnResize(false);
}
#Override
public String getInnerHTML() {
return "<textarea id=\"" + editor_id + "\"" + "style=\"width:100%;height:100%\"></textarea>";
}
#Override
protected void onDraw() {
MyEditor.replace(editor_id);
}
}
3) finally, I filled the smartGWT tab with an instance of MyEditor:
// create a smartGWT tab
Tab tab = new Tab("tab");
tab.setID("tab");
tab.setCanClose(true);
MyEditor editor = new MyEditor(tabNumber); // an integer number
tab.setPane(editor);
Tested. Working.